lontivero / Open.NAT

Lightweight and easy-to-use class library to allow port forwarding in NAT devices with UPNP and/or PMP
MIT License
421 stars 99 forks source link

Open.NAT and ASP.NET #97

Closed FreekDS closed 4 years ago

FreekDS commented 4 years ago

The problem

I am writing a small web service application using ASP.NET. I want this web API to be visible from outside a home network (behind NAT). The problem is that the user I'm writing this program for, has no access to change his router. Creating a portforwarding rule in the router configuration is no option.

As a solution to this, I tried to use UPNP with the Open.NAT framework. Sadly I can't get this to work. I'm able to create a rule, I can see that the port is open using online tools such as canyouseeme but I cannot connect to the web api using a browser. I am 100% sure UPNP is enabled on my router.

Code

The code I'm currently using is the default weather forecast code that is generated by visual studio when creating a ASP.NET web API. I added Open.NAT from the NuGet package manager.

Then I changed the default code to the following

public static void Main(string[] args)
{
    CreatePortforwardRule().Wait();
    CreateHostBuilder(args).Build().Run();
}

static async Task CreatePortforwardRule()
{
    NatDiscoverer discoverer = new NatDiscoverer();
    CancellationTokenSource cts = new CancellationTokenSource(10000);
    var device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts);
    await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 5000, 7856, "Test"));
}

When I run this application and go to canyouseeme, I get the information as shown in this image but I cannot connect to the web api using the browser. (Also tried to connect using cURL without result)

Additional things I did

In order to try to solve this, I also did the following:

I really hope I can find a solution. Thanks for taking time to read my question.

Link to stackoverflow post I made https://stackoverflow.com/questions/62038952/how-to-use-open-nat-in-an-asp-net-web-api

lontivero commented 4 years ago

You are not providing anything that can help me to help you. Could you post the Open.NAT log file?


I would also suggest to map using the same port with a higher port, for example:

await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 15_000, 15_000, "Test"));

Once you have this just listen in that port with nc:

$ nc -l 15000

and then hit that endpoint from outside of your LAN (using your cellphone data plan, for example) and check if it was reached.

FreekDS commented 4 years ago

Thanks for your fast reply! Where can I find the Open.NAT log file?

lontivero commented 4 years ago

You have to enable the logging. https://github.com/lontivero/Open.NAT/wiki/Troubleshooting

FreekDS commented 4 years ago

I have followed your advice and changed the mapping entry to

await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 15000, 15000, "Test"));

I also enabled logging. The generated log contains the following:

Open.NAT Information: 0 : Start Discovery
Open.NAT Information: 0 : Searching for: UpnpSearcher
Open.NAT Information: 0 : UPnP Response: Router advertised a 'urn:schemas-upnp-org:service:WANIPConnection:2' service!!!
Open.NAT Information: 0 : Found device at: http://192.168.0.1:5000/rootDesc.xml
Open.NAT Information: 0 : 192.168.0.1:5000: Fetching service list
Open.NAT Information: 0 : Found device at: http://192.168.0.1:5000/rootDesc.xml
Open.NAT Information: 0 : 192.168.0.1:5000: Parsed services list
Open.NAT Information: 0 : 192.168.0.1:5000: Found service: urn:schemas-upnp-org:service:WANIPConnection:1
Open.NAT Information: 0 : 192.168.0.1:5000: Found upnp service at: /ctl/IPConn
Open.NAT Information: 0 : 192.168.0.1:5000: Handshake Complete
Open.NAT Information: 0 : Stop Discovery
Open.NAT Information: 0 : CreatePortMapAsync - Creating port mapping Tcp 15000 --> 192.168.0.222:15000 (Test)
Open.NAT Verbose: 0 : SOAPACTION: **AddPortMapping** url:http://192.168.0.1:5000/ctl/IPConn

info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://0.0.0.0:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\Users\gebruiker\source\repos\WebApplication\WebApplication

(note: the last lines of logging are generated by my ASP.NET application)

I then used the nc -l -p 15000. When I use the canyouseeme tool to check if port 15000 is open, I get result from the nc command. But when I want to hit the endpoint using my public IP address with port 15000 from outside my home network, the request times out and I do not get result from the nc command. I temporary disabled my firewall while testing this out.

lontivero commented 4 years ago

Open.NAT opened the port successfully. You have verified that fact when after using https://canyouseeme.org/ you saw some output in the nc, otherwise there is no way an external service can hit a process in your machine.

I think you are probably making a mistake in your ASP application. Make sure to listen in the correct port and with the correct prefixes. It is a common mistake to listen on 127.0.0.1 instead of something more generic like http://+:15000

Anyway, there is nothing else I can help you here because clearly the port is opened.

FreekDS commented 4 years ago

Ok, no problem, thanks for your time and help.