CGNAT for branches and remote staff: step by step without a public IP
Connecting branch offices and remote workers behind carrier CGNAT is entirely achievable without purchasing static public IP addresses or modifying firewall rules. A private WireGuard mesh negotiates peer-to-peer tunnels with STUN and falls back automatically to an encrypted TCP relay whenever neither endpoint possesses a routable public address.
The operational challenge of multi-party carrier CGNAT
Telecommunications providers routinely deploy Carrier-Grade NAT (CGNAT) or symmetric NAT on fibre broadband and cellular connections, blocking unsolicited inbound packets. Traditional site-to-site VPNs require at least one participating office to retain a static public IPv4 address and exposed inbound ports on its edge router.
When all locations reside behind CGNAT, standard VPN handshakes cannot complete because neither peer can address the other directly. This limitation often drives organisations toward brittle port forwardings or third-party cloud concentrators, introducing operational overheads discussed when reviewing private mesh networks vs traditional VPNs.
Direct STUN negotiation and encrypted relaying on TCP 4430
STUN runs on UDP 3478 within the control plane to discover each endpoint's external mapping and perform NAT hole punching. If hole punching succeeds, data flows point-to-point over WireGuard tunnels where each machine holds its own cryptographic key pair without usernames or passwords in the data path. WireGuard is a registered trademark of Jason A. Donenfeld.
Whenever symmetric NAT or restrictive CGNAT prevents a direct path, the client automatically re-routes traffic through a relay listening on TCP 4430. This relay processes frames in approximately 23 ns regardless of connected peer density, forwarding encrypted packets that it cannot inspect or decrypt.
Every device enrolled in the mesh receives a permanent IP address from the 100.64.0.0/10 space defined in RFC 6598 for shared carrier infrastructure. This dedicated range prevents IP collisions against standard 192.168.x.x or 10.x.x.x networks, which is essential when configuring SSH and RDP to customer servers.
Transport path characteristics for sites behind CGNAT
| Transport mode | Firewall configuration | Data encryption | Typical network overhead |
|---|---|---|---|
| Direct tunnel (STUN) | Zero inbound ports | End-to-end WireGuard | Unrestricted throughput |
| Relay bridge (TCP 4430) | Outbound TCP 4430 only | Opaque to relay host | SSH < 1 MB/h; RDP 0.5-1 GB/h |
| Subnet LAN routing | Zero router changes | Encapsulated via Linux | Dependent on local services |
Self-hosted control plane architecture and deployment
The self-hosted package runs via Docker Compose across three containers: the coordination server handling gRPC on TCP 50051 and STUN on UDP 3478, the relay on TCP 4430, and a PostgreSQL database. A standard instance requires 2 vCPUs and 2 GB of RAM to coordinate hundreds of machines on Linux x86_64 or arm64 running Docker Engine 24 or newer with Compose v2. The binaries are available from the self-hosted server downloads.
The administrative interface on port 8080 is never published directly to the Internet; operators access the management dashboard through an SSH tunnel. Mutual trust is established via SPKI public key pinning (sha256:...) during node enrolment, removing reliance on public certificate authorities. Sinergia, the Barcelona-based developer of prialo, has no access to customer keys or coordination databases.
Node installation and subnet routing step by step
- Install the agent: run the command-line installer on the target Linux or macOS machine with root privileges and the designated enrolment key.
- Confirm status: verify using
prialo statusthat the terminal displays 'Control: tls, pinned' along with an assigned 100.64.0.0/10 address. - Inspect connections: test reachability to peer nodes using
prialo peersand measure latency directly withprialo ping <host-or-ip>. - Advertise site network: expose an internal branch subnet by running
prialo up --advertise-routes=192.168.50.0/24from an on-site Linux system. - Approve subnet route: authorise the advertised network using
prialo node routes <router> --approve 192.168.50.0/24via the management console. - Enable client access: launch downstream devices with the
--accept-routesflag to import approved site routes into their routing tables.
sudo PRIALO_AUTH_KEY='<enrolment key>' prialo install --server=control.example.com:50051 --relay=control.example.com:4430 --tls-pin=sha256:<fingerprint>
Only Linux systems can function as subnet routers; mobile clients and Windows devices cannot accept advertised routes at this time. As of 17 October 2026, the Mac and iPhone applications are in Apple's review queue and cannot be downloaded; the Windows release is available as an early unsigned build without an installer, and Android support remains in active preparation.
Regarding regulatory frameworks, NIS2 (Directive EU 2022/2555), GDPR (Regulation EU 2016/679), and Spain's Esquema Nacional de Seguridad (Real Decreto 311/2022) demand strict governance over network access. prialo holds no formal certifications under these frameworks; its security model ensures that cryptographic keys, node inventories, and audit logs remain solely on customer-managed infrastructure.
Frequently asked questions
How do two CGNAT endpoints connect without a public IP?
Endpoints discover public mappings via STUN on UDP 3478 and attempt hole punching to establish a direct WireGuard connection. If restrictive CGNAT prevents a direct path, traffic routes automatically through a TCP 4430 relay that forwards packets without decrypting them.
What happens if a mesh exceeds its monthly relayed traffic quota?
When the PRIALO_MESH_QUOTA_BYTES limit is reached, the relay drops additional forwarded frames for that specific mesh and records the dropped count. It does not disconnect nodes or terminate the underlying control plane session.
Can a Windows workstation act as a branch subnet router?
No, only Linux hosts can advertise and route local subnets into the mesh network. Furthermore, client devices running Windows or mobile operating systems do not currently have the capability to accept advertised subnet routes.
What hardware is required to self-host the coordination stack?
A self-hosted deployment requires 2 vCPUs and 2 GB of RAM on Linux x86_64 or arm64 running Docker Engine 24 or newer with Compose v2. This setup manages the coordination daemon, relay server, and PostgreSQL database for hundreds of nodes.
Would you rather run your own server? Guide to the self-hosted prialo package