How it works
Every node is equal. The network is just its machines.
There is no server that knows the members, hands out addresses or brokers connections. Here is what happens instead.
Identity and addresses
Each node makes an Ed25519 key when it joins. Its id is the public key; its IPv4 address in 100.64.0.0/10 and its IPv6 address are derived from that id. Nothing needs to be handed out, so nothing needs to be coordinated. The network has a shared key, which every member gets with its invite.
Records and gossip
Each node signs a small record about itself: its name, where it can be reached, which nodes it is linked to. Nodes pass the records they know on to their neighbours, so everyone soon knows everyone. Each node keeps them on disk, which is why the network keeps working when any node is gone, including the one it was started on.
In a managed network (the default) there is also a roster of admins, signed by an admin. A node counts as a member only with an admission from an invite an admin signed.
Links and encryption
Nodes connect over TCP or UDP. Every link is a Noise XXpsk3 handshake: both ends prove their node key and the network key. On top of that, every packet is encrypted end to end between the two nodes that talk, with a counter against replays. When a packet takes a detour over other nodes, they forward what they can neither read nor change.
Finding a path
- Direct. Nodes send each other authenticated probes over UDP, to every address they know of the other: LAN addresses, public addresses, IPv6. Probes going out at the same time open both NATs. The best working path wins; a LAN path beats one over the internet.
- Through firewalls over IPv6. Routers at home and on mobile networks let no connection in, but let answers through. Two nodes that try each other at the same moment, from a fixed port, become each other's answer, for UDP and for TCP (simultaneous open).
- Port forwarding. On a home router with UPnP, NAT-PMP or PCP, a node opens its port for an hour at a time, and closes it when it stops.
- Relayed. If nothing works directly, traffic goes over the shortest chain of other nodes.
- Out over SSH. A node that may only open SSH keeps a reverse tunnel to a node that can be reached.
Finding each other again
Addresses change: a home router gets a new one every day, a laptop moves to a hotspot. Usually some node still knows the new address and gossips it. When none does, the rendezvous helps (off by default, dht = true):
- Every node puts a small entry into the public BitTorrent Mainline DHT. It holds where the node can be reached, encrypted with a key derived from the network key, and signed.
- Where the entry lives is derived from the network key and the day. Outsiders can neither find it nor read it, and it changes every day.
- Only temporary IPv6 addresses go in, which change daily too. A node's stable address would let anyone with the network key follow the machine around.
- The node is a client of the DHT only: it stores nothing for others.
With the addresses found there, two nodes punch through to each other. A new node can join the same way: the invite says where to meet the node that made it.
stun = [] for none) see that you asked for your public address.Leaving, banning, updating
A banned node is shut out by a new network key, which is sealed for each remaining member and passed on, also to members that were offline. A node that leaves tells the others to forget it. Updates come from the GitHub releases and are installed only if their signature verifies against the release key built into meshvpn.
Limits
- The mesh is full-mesh by design, which suits networks of up to a few dozen nodes.
- Members are trusted: they can reach each other's services. Access rules inside the mesh are up to the machines' own firewalls.
- Some carrier-grade NATs give a new port for every destination. Over IPv4 those can't be punched through; IPv6 or a relay takes over.
More detail, down to the file format: the README.