Documentation
A VPN with no port forwarding: NAT traversal, explained
A classic VPN always starts with the same chore: opening an inbound port on the router, setting up port forwarding, exposing a server to the Internet. VIGIL-MESH asks for none of it: each machine only makes outbound connections, a relay puts the peers in touch immediately, then the session migrates without interruption to the direct path as soon as NAT traversal finds one. Zero inbound ports, a single outbound flow on 443 UDP — including behind a consumer router or a 4G/5G connection on CGNAT.
Why classic VPNs require an inbound port
For a VPN tunnel to come up, someone has to accept the connection. In a classic VPN, that someone is a server: a machine listening on a port, reachable from the Internet. Yet almost every machine today lives behind a NAT — the router translates the LAN's private addresses into one shared public address, and by default it lets no connection in. Hence port forwarding: telling the router "whatever arrives on this port, send it to that machine". That step is exactly what causes trouble, for several reasons.
The consumer router
You need access to the admin interface, you create the forwarding rule by hand, and you redo it if the router changes or the public IP address is not static. A technical manipulation most users will never perform — and one a tenant, a guest or a remote worker often cannot perform at all.
CGNAT on 4G/5G connections
On most mobile connections and many recent fiber plans, the public address is shared between many subscribers (Carrier-Grade NAT). There is no port to open: the NAT belongs to the carrier, not to you. A VPN that requires an inbound port is simply impossible to host there.
The corporate network
The firewall is run by a security team: opening an inbound port means a ticket, a justification, an approval — when it is not a flat refusal. Outbound flows, on the other hand, are the network's normal way of life.
Exposure to the Internet
An open port is an exposed service: it is scanned around the clock, and every flaw in the software listening behind it becomes exploitable from anywhere. Exposing nothing at all remains the best attack-surface reduction there is.
How NAT traversal works
The key idea behind NAT traversal fits in one sentence: a NAT blocks inbound connections, but always lets traffic out — and lets replies come back to whatever went out. If both machines each establish an outbound connection toward the other at the same moment, each NAT sees an outgoing packet, opens a passage for the reply, and the other side's packets rush into that passage. Nobody accepted an inbound connection; the two outbound flows met in the middle.
- 1Each machine dials outBoth nodes maintain an outbound connection to a rendezvous point. By dialing out, each one discovers the public address and port its NAT assigned to it — as the outside world sees them.
- 2The rendezvous exchanges the addressesThe rendezvous point hands each node the observed public address of the other. Each one now knows where to aim.
- 3The packets cross pathsThe two nodes send packets to each other simultaneously. Each NAT, having seen a packet go out toward the other, accepts what comes back from it: the direct path is open, without a single port having been configured anywhere.
Not all NATs let themselves be traversed so easily. What matters is how the NAT assigns its mappings (public address and port) and what it accepts in return:
| NAT type | Behavior | Direct path |
|---|---|---|
| Full cone | One stable mapping; anyone can reply to it | Trivial |
| Address-restricted | Accepts replies from addresses already contacted | Works with the address exchange |
| Port-restricted | Accepts replies from the exact address + port contacted | Works with crossed packets |
| Symmetric | A different mapping per destination — the port seen by the rendezvous is not the one used toward the peer | Generally impossible directly |
What VIGIL-MESH does: relay first, direct as soon as possible
VIGIL-MESH does not make you wait for the outcome of NAT traversal. As soon as two machines need to talk, traffic flows immediately through a relay (the vigie) — itself reached through an outbound connection. In parallel, the nodes attempt NAT traversal; when a direct path exists, the session migrates to it without interruption: nothing reconnects, nothing drops, the traffic simply changes route.
- Zero inbound ports — no node listens from the Internet: every connection is established outward.
- A single outbound flow, on 443 UDP — the same port as the modern web (HTTP/3), allowed outbound on virtually every network. Nothing to open, nothing to forward, nothing to justify to the firewall.
- End-to-end encryption — sessions are QUIC/TLS 1.3 connections between the two nodes. Relayed or direct, the path changes nothing about the encryption.
- Stable addresses — each machine keeps the same address on the mesh, whatever physical network it sits on and whatever path its traffic takes.
When direct is impossible: the relay remains the path
Let's be honest: NAT traversal does not always win. When both ends sit behind a symmetric NAT — two 4G connections, for instance, each on carrier CGNAT — no direct path can be established: each NAT changes port depending on the destination, and the crossed packets never meet. In that case, traffic keeps going through the vigie, permanently.
The vigie is structurally blind: it does not hold the session keys and forwards QUIC/TLS 1.3 connections encrypted end to end, whose content it never sees. And if transiting through a shared relay bothers you, you can host your own private vigie, dedicated to your workspace: the relayed path then goes through a machine of yours.