tonarino / innernet

A private network system that uses WireGuard under the hood.
https://blog.tonari.no/introducing-innernet
MIT License
5.02k stars 186 forks source link

NAT traversal [tracking issue] #109

Open strohel opened 3 years ago

strohel commented 3 years ago

This is a tracking issue for applying various techniques in innernet to traverse NATs in the path. CC @skywhale.

@mcginty has curated https://tailscale.com/blog/how-nat-traversal-works/ as the best resource on toolbox we have for NAT traversal (and I second).

Some aux pieces information to start:

Q: If I manually port-forward innernet port on my side, that could increase chances to connect to that other peer behind NAT? A: Yep, setting up port forwarding for innernet should fix your issues. Call innernet set-listen-port to get a stable port.

Q: Just curious, how does innernet determine my own NAT-translated port? With the help of the server? A: Yep! the server acts as STUN server, basically

mcginty commented 3 years ago

Added more details in https://github.com/tonarino/innernet/issues/115#issuecomment-882433652 that help describe our current state of NATitude.

mcginty commented 3 years ago

Here's how I'm currently thinking about the problem and working on it:

Phase 1 (STUN)

118: Add awareness of the likelihood of a working peer endpoint and don't overwrite the endpoint when the peer is already connected. This allows our current basic NAT traversal to work properly.

Phase 2 (ICE)

  1. Modify the state protocol to allow clients to report a list of self-discovered candidate endpoints, and for the server to pass those along to other peers.
  2. Modify the client's fetch() to be able to test multiple candidate IPs as endpoints and settle on the one that appears to be correct.

Phase 3 (TURN)

This is lower-priority since it adds complexity and can cause larger fluctuations in network performance if the logic isn't well-designed.

  1. Add support for relay nodes, which is probably similar to the site-to-site proposals seen before.
brandonkal commented 3 years ago

Wiretrustee (another open source tailscale alternative) has this implemented and interestingly is missing but planning for the key management features you have here. It may be useful as a reference, and ultimately worth looking into merging efforts.

https://github.com/wiretrustee/wiretrustee

brandonkal commented 3 years ago

More reference implementations

https://docs.rs/p2p/0.6.0/p2p/

The message to the rendezvous servers includes our public key so the message they send back is encrypted. This prevents some routers/firewalls from identifying it's a rendezvous attempt by looking at the message body and thus either mangling or discarding the packet. Such routers/firewalls seem to scan for socket addresses in the body and if it matches the ones in the router's pool they try to figure out it's a rendezvous/STUN attempt. With encrypted contents there is no chance of such detection, so we are safe there.

https://github.com/dswd/vpncloud

https://github.com/manuels/wireguard-p2p/tree/master (Uses OpenDHT)

mcginty commented 3 years ago

I've given a shot at not bringing in new dependencies, and implementing an ICE-lite protocol in #134 to assist with NAT traversal (or, rather, avoiding the need for holepunching all together).

I'm still on the fence about UPnP since it's a horribly messy protocol itself, and it's not something I even want people to necessarily have enabled on their routers because of the security implications...

mannp commented 3 years ago

I'm still on the fence about UPnP since it's a horribly messy protocol itself, and it's not something I even want people to necessarily have enabled on their routers because of the security implications...

Likely a dev conversation but user feedback would be -> UPnP 👎🏻

brandonkal commented 3 years ago

Isn't the purpose to create a mesh of nodes? Using all available NAT traversal techniques would be the way to go about that before resorting to a relay server. Supporting a protocol such as UPnP isn't about encouraging users to change router settings but to use all available avenues to get around a router that isn't controlled. If you are behind a router that supports it, why not use that to your advantage as Tailscale does in the article mentioned above? I agree that it is messy, which is why a library was suggested.

While there are valid concerns, many of the security points against UPnP assume that NAT = firewall and that a relay server is not a thing (that can bypass a router that has UPnP disabled).