8
votes

For my academic project, I am trying to achieve this. A web server node JS application listening on port 3000. So If you curl http://localhost:3000 you will get Hello World!. ( A simple web page.

Now I am running above webserver in my local machine. And my modem is behind NAT. Suppose If I port forward in the modem to myip:3000 then it is open to the world. But here is the biggest thing I am stuck - I don't want to use the modem for port forwarding, instead, I will use third party server for UDP Punch Hole.

Now my requirement is anyone from net should able to access my webserver at curl http://third-party-server-ip:3000.

What I am trying is to write another client - which opens a connection to the third party server. Say it did a hole punching at port 41234. That port is open. The third-party host can send something to that port.

Now anyone in the internet initiate this command curl http://third-party-ip:3000 to the third party host. So the third party returns the myip:udpPunchHolePort i.e., myip:41234.

anyone will again curl to myip:41234 it will be received by the node js UDP punch app, so it will redirect to localhost:3000. Finally, the anyone will receive the response from localhost:3000.

My two questions -

  1. Is there any better way than the one I proposed here?
  2. Is there any well-known node-js lib for this kind of stuff, I see, I can use UDP punch hole. Or I am thinking to write a Lib to do this in general - does this sounds like re-inventing the wheel?

Note - In this academic project, we are trying to learn how to make any local application open to the world without port forwarding in the modem.

We read on skype protocol analysis, that is also our inspiration.

Flow of request

1
It's unclear why you're trying to use UDP here. You are trying to use the third party host as a proxy for your "behind the firewall" host. There are a number of architectural ways to do that. The most straightforward way I can think of would be for your "behind-the-firewall" server to open a connection to the third party proxy. Because this connection is outbound, it will be allowed and because the connection is persistent, then both sides can send data over the connection. Thus your third party proxy can send your "behind-the-firewall" server any data it wants at any time. - jfriend00
All browser pages that use socket.io or webSockets are getting this same benefit. Client behind a firewall connects to a server, thus allowing the server to send data to them at any time even though they are located behind a firewall. Most chat clients use something like this. - jfriend00
Hello @Sam you are really re-inventing wheels for sure. You just need nginx proxy server in between. we are doing that in our current project. Everytime each & every request you send, it will go to nginx proxy server & then request will be send by nginx to your application localhost:3000. Here is detailed manual for nginx nginx.com/resources/admin-guide/reverse-proxy - Inder R Singh
@InderRSingh NGINX running on the third party machine, wont be able to traverse the NAT to the local machine. @Sam It seems to me that this problem can be easily solved with an SSH reverse tunnel. ssh -R 80:localhost:3000 user@thirdpartyip assuming sshd on the third party has the GatewayPorts yes setting enabled. - Magnus
@Sam SSH tunnelling won't help. It requires the firewall to be running an SSH server, which is essentially never available. The (extremely rare, typically homemade) firewalls that do have an SSH server will almost always have port forwarding and/or UPnP available as well. - user149341

1 Answers

4
votes

No, that won't work.

  1. HTTP runs over TCP, not UDP. Punching a UDP hole doesn't do you any good -- any TCP connection to the backend HTTP server will still fail.

  2. HTTP redirects are not magic. If a user cannot access a specific host:port, redirecting them to a URL on that host:port will just make their browser time out when it requests that URL.

  3. You cannot send a response from a different host:port from what the browser requested, because there is no TCP connection established with that endpoint.