GCE allow incoming traffic on specific ports - c#

I'm trying to host a TCP socket server on a Google Compute Engine, i added the following rule on GCE firewall-rules (sockets-port 0.0.0.0/0 tcp:11000 Apply to all targets) but the port is still inaccessible from the outside using the public IP (ephemeral in my case).
Is there more to be done in this case? should i use ufw on the VM itself to set additional rules?
Any help or hints would be appreciated, thx.
EDIT:
1) firewall settings:
NAME NETWORK SRC_RANGES RULES SRC_TAGS TARGET_TAGS
default-allow-http default 0.0.0.0/0 tcp:80 http-server
default-allow-https default 0.0.0.0/0 tcp:443 https-server
default-allow-icmp default 0.0.0.0/0 icmp
default-allow-internal default 10.128.0.0/9 tcp:0-65535,udp:0-65535,icmp
default-allow-rdp default 0.0.0.0/0 tcp:3389
default-allow-ssh default 0.0.0.0/0 tcp:22
sockets-port default 0.0.0.0/0 tcp:11000
2) on the VM itself the SocketListener class (C#) gives the error :
Cannot assign requested address
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
"IPEndpoint consists of the public IP of the machine and port 11000

This is a classic problem with GCE, you must bind your server socket to 0.0.0.0, instead of the external IP. I don't know if this is by design.
The external IP is a virtual IP. The infrastructure knows how to direct traffic targeting the IP to your VM, but it is not bound to any of the VM's network interfaces. If you run sudo ifconfig in the VM, you will only see the internal IP on eth0.

Related

SMBLibrary: "An attempt was made to access a socket in a way forbidden by its access permissions"

SMBLibrary project on GitHub appears to be is exactly what I am looking for.
I need something to abstract a db to look like a file system, accessible via UNC path.
I am using Windows 10, Visual Studio as Administrator. I installed the MS Loopback Adapter, and disabled the other adapters. I have stopped the "Server" service.
Running the the server on 127.0.0.1, port 445 I receive the following error:
System.Net.Sockets.SocketException
HResult=0x80004005
Message=An attempt was made to access a socket in a way forbidden by its access permissions
Source=System
StackTrace:
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at SMBLibrary.Server.SMBServer.Start(IPAddress serverAddress, SMBTransportType transport, Boolean enableSMB1, Boolean enableSMB2, Nullable`1 connectionInactivityTimeout) in C:\Users\josep\Source\Repos\SMBLibrary\SMBLibrary\Server\SMBServer.cs:line 87
I am expecting to run the server app, then using explorer navigate to \127.0.0.1
It is not clear from Read.me if this is correct or not.
The readme is pretty clear on what you are doing wrong:
if you want localhost access from Windows explorer to work as expected, you must specify the IP address that you selected (\127.0.0.1 or \localhost will not work as expected), in addition, I have observed that when connecting to the first IP address of a given adapter, Windows will only attempt to connect to port 445.
You need to connect to the IP address assigned to the loopback adapter.

Kestrel unable to start

When specifying a port to bind to with .UseKestrel() I get the errors listed below.. but if I remove the kestrel options everything works normally if I check the API from my browser.
I've tried binding to the port that my application defaults to with no ports chosen and I've tried checking netstat to actively avoid any ports that are in use. Nothing works but removing the options entirely. This is not replicated on my Mac or another Windows 10 machine. This device is Windows 10.
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 50470);
options.Listen(IPAddress.Any, 80);
})
: Microsoft.AspNetCore.Server.Kestrel[0]
Overriding address(es) 'http://localhost:50470/'. Binding to endpoints defined
in UseKestrel() instead.
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.Net.Sockets.SocketException (10013): An attempt was made to access a
socket in a way forbidden by its access permissions
at
System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException
(SocketError error, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress
socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.
BindAsync() at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.
<>c__DisplayClass21_01.<<StartAsync>g__OnBind|0>d.MoveNext() `
Also check Darkthread's answer here: https://superuser.com/questions/1486417/unable-to-start-kestrel-getting-an-attempt-was-made-to-access-a-socket-in-a-way
We discovered that a port we had been using for a long time wasn't acccessible anymore because it had been reserved by Windows! You may wish to check reserved ports using this command:
netsh interface ipv4 show excludedportrange protocol=tcp
After Windows Update, some ports are reserved by Windows and applications cannot bind to these ports. please check this command for forbiden port on Os
netsh interface ipv4 show excludedportrange protocol=tcp
In my case, Removing invalid local IP and Port address combinations from the app's launchSettings.json did it.
The additional binding of port 80 in ".UseKestrel(options => { options.Listen(...) })" was causing the issue in my case.
When you run an ASP.NET Core application directly through Kestrel, without an additional reverse proxy like IIS or nginx, you will need to configure the hosting URL properly.
The problem was because, you did not follow Port sharing limitation in Kestrel web server.
When you to use the Kestrel web server, you should set unique port to app. (if you use the port 80, make sure no apps use this port).
and your app has enough permissions, too.
more info:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2
I hope is useful.
Try Updating The Https Certificate
with this command. It worked for me!!
dotnet dev-certs https
The problem was with the additional binding of port 80, updating this corrected the problem.

Why does google captures a different IP address than my TcpListener?

I have a very simple http server:
TcpListener server = new TcpListener(System.Net.IPAddress.Any, 80);
server.Start();
var client = server.AcceptTcpClient();
var ip = client.Client.RemoteEndPoint;
// ip address in here is: 166.72.162.85
// etc. read request and write response....
I am making that request with my phone that is connected to AT&T 3G network. And my server detects the ip address 166.72.162.85
Now here is my question. I am asking this question primary to learn. Why is it that google captures a different IP address? How can I capture 2600:387:9:3::c7 with my TcpListener?
It looks like you're on a dual stacked network - you have both IPv4 and IPv6 connectivity, which a bit like being connected to two separate "Internets" at the same time.
Your server is probably accessible from only one of these "Internets" - the IPv4 Internet. Google is accessible from both. We can easily check that by resolving www.google.com to an IP address. Here's the result on my machine:
Note the first result - 2a00:1450:4001:821::2004. It's an IPv6 address, and that's the first address your operating system will try to connect to when accessing www.google.com because modern operating systems prefer IPv6 over IPv4. So your connection to Google goes over IPv6, which will see you coming from your IPv6 address (2600:387:9:3::c7).
When connecting to your IPv4-only sever, the connection is made over IPv4 - from your IPv4 address, which is 166.72.162.85 to the server's IPv4 address.
To reach your server using IPv6, you'd need to make it accessible via IPv6:
The machine on which you run your server must have a public IPv6 address
The client has to access the machine either directly by its IPv6 address, or a domain name which has a AAAA record, which is a DNS record for IPv6 addresses
On top of that, you need to make sure that your server software binds to the IPv6 address of the machine. Your code binds to System.Net.IPAddress.Any, which is equivalent to 0.0.0.0, meaning "any IPv4 address". Instead, you'd need to bind to IPAddress.IPv6Any, which is equivalent to 0:0:0:0:0:0:0:0 (or ::), meaning "any IPv6 address".
BTW, you can try getting your IP from the IPv4-only Google at https://ipv4.google.com/. It should return the same 166.72.162.85 that you're seeing in your server.
Google is showing an IPv6 address, your code is showing IPv4.
Note you can also see different IP on the receiving end depending on the route the traffic has taken to get there, like if there were a proxy involved you would see the IP of the proxy and not the actual IP of the source.

Renci ssh.net No connection could be made because the target machine actively refused it

We recently deployed a project into production and are now receiving this error message when we attempt to connect to the external sftp machine, "No connection could be made because the target machine actively refused it". When I was developing the application and testing it, we had no issues connecting to this server.
What would be different? I have administrative privileges and the app pool on the production server does not. I'm not sure if this could be what's causing the issue or if it may be something on the external client's server or their firewall blocking us.
If you are using localhost, specify 127.0.0.1 instead.
When I was using SSH.Net and the host was specified as localhost it threw the exception that the host actively refused the connection WSAECONNREFUSED - 10061. When I specified 127.0.0.1 instead, the connection could be made.
I think this is due to the implementation in SSH.Net:
internal static IPAddress GetIPAddress(this string host)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(host, out ipAddress))
ipAddress = Dns.GetHostAddresses(host).First();
return ipAddress;
}
Which does not resolve a valid hostname for localhost, apparently. C# Interactive yields the following:
> Console.WriteLine(Dns.GetHostAddresses("localhost").First());
::1
The value ::1 does not seem to be a valid IP address for sockets to use.
This is a standard TCP error
WSAECONNREFUSED - 10061
From the Client's point of view it means 'there is no socket at that address listening to that port' (the "actively refused" is a red herring).
i) check the address
ii) check the port
iii) check firewall(s)
From our extensive experience (we offer own networking components) -- it's a firewall problem. The firewall doesn't let your requests pass. It's a common situation when you run say Putty, and it works, but your code doesn't. This is because many firewalls detect well-known applications and let them pass, while preventing other applications.

ZeroMq Pub Sub Address not Available

I'm creating a pub sub style communication using zeromq c# implementation. It all works fine on my local machine but when running the client component (publisher) against a remote address I get an "Address not available". So far as I understand it the Publisher will Bind to an endpoint and the Subscriber will Connect.
Am I misunderstanding something or should publisherSocket.Bind("tcp://someRemoteIP:5001") work?
You bind to a local endpoint, and connect to a remote endpoint.
The local endpoint consists of a protocol ("tcp://"), an interface ("*", "localhost", "eth0" (or such) or the IP address of an interface), and a port number (":5001").
The remote endpoint consists of a protocol ("tcp://"), an IP address or domain name ("someremoteIP") and the port number.
Hope that helps.

Categories