This[1] is the best post I've seen on that _outside_ of the Tailscale writeup linked below. The clever bit is that the introduction server uses wireguard tunnels to find your endpoint information, then shares it out via DNS. Of course it still requires you to be able to run custom code on all of the endpoints, which requires supporting many different platforms.
I'm still looking for a FLOSS mesh network built on top of wireguard that can do NAT traversal between nodes and fall back to tunnelling traffic for the annoying cases where this fails. I don't really want to use Tailscale because (1) their server is not open (though this should not matter a ton for trust) and (2) they require a Google account or similar to sign up.
I can't see how the post you linked actually does the NAT traversal...
Alice finds Bob's external IP:port using the registry. That makes sense. But doesn't Bob need to send a packet to Alice to setup the NAT traversal on his side? More accurately, Alice uses the SRV field to populate the wg peer information on her side -- but how does Bob know that he needs to update the peer information on his side?
I think this is really close, but maybe using a custom DNS server for this might be trying to be a little too clever?
I also haven't fully groked this to be fair, but my understanding is:
(1) Alice and Bob both connect to coordination server
(2) Alice sets Bob's endpoint to bob_ip:bob_port
(3) Bob sets Alice's endpoint to alice_ip:alice_port
(4) Both try to ping each other, which makes both of them originate outbound packets from the wireguard socket.
IF Alice and Bob have the same public IP:port pair in their NAT with each other as they do with the coordination server (which turns out to be true in tests on my EdgeRouter X NAT, but certainly isn't true 100% of the time), then I believe this process will result in a working connection.
If you're asking how Bob & Alice know that the information in the coordination server has changed and that they need to reconfig their endpoints, then I'm not sure. Perhaps they could just re-query the coordination server on a timeout or whenever their connection went down.
I agree - using DNS as a transport seems orthogonal to the NAT punching process, and maybe too clever. If you're going to need to write custom endpoint code either way, I don't see a huge advantage. If wireguard supported DNS-based endpoint information by default (automatically re-resolving IP and detecting port from SRV), then it'd make a lot more sense.
> I can't see how the post you linked actually does the NAT traversal...
It assumes full-cone NAT - you punch a hole once by sending a packet to a third party, like a stun server which will along the way tell you your external ip:port, and then a full-cone NAT would forward packets coming to that ip:port back to you, regardless of the source.
Anyone have anything like an introduction server to help wg peers behind nat find each other?