Most edge fleets are compromised not because the application was weak, but because a management port was reachable from the internet. When you operate thousands of routers and gateways across sites you don’t control, every inbound rule is a liability. This post walks through a zero-trust, outbound-only connectivity model for edge fleets, built on WireGuard, and the operational patterns that make it scale.
The problem with inbound access
The traditional way to reach a remote device is to expose something: an SSH port, a VPN concentrator, a management VLAN with a public IP. Each of those is a door, and doors get knocked on. At fleet scale the math gets worse fast:
- Every site needs a static IP or dynamic-DNS hack.
- Every firewall becomes a per-site snowflake you have to audit.
- A single exposed credential or unpatched daemon compromises the device and a path into the customer network.
If a device listens for connections from the internet, scanning bots will find it within minutes of it coming online. The only port that can’t be attacked from outside is the one that was never opened.
Flipping the model: outbound-only
The fix is to invert the direction of trust. Devices never accept inbound connections. Instead, each device dials out to a control plane over an encrypted tunnel and stays connected. Management traffic then flows back down that already-established tunnel.
Infrastructure connects securely outward, rather than exposing services publicly.
Because the tunnel is established by the device, the device’s firewall can drop all inbound traffic. There is nothing to port-scan, nothing to brute-force, and nothing to expose when a new site comes online.
Architecture at a glance
Identity-first enrollment
Every device gets a unique keypair at provisioning time. The public key is its identity; the control plane only accepts tunnels from keys it already knows. Enrollment is a one-time, authenticated exchange — after that, the private key never leaves the device.
Encrypted tunnels with WireGuard
WireGuard is a good fit for the edge: it’s a few thousand lines of code, runs in the kernel, and reconnects almost instantly after a network blip. A device peer needs only the control plane’s public key and endpoint:
[Interface]
PrivateKey = <device-private-key>
Address = 10.80.0.42/32
[Peer]
# Control plane (the only endpoint the device ever talks to)
PublicKey = bX5...controlPlanePublicKey...=
Endpoint = edge.iotocean.net:51820
AllowedIPs = 10.80.0.0/16
PersistentKeepalive = 25
The PersistentKeepalive is what keeps the outbound tunnel alive through NAT and stateful firewalls, so the control plane can reach back without the device ever listening.
Per-tenant isolation
Each customer lives in its own address range and routing domain. A device in tenant A can never see tenant B, even though both terminate on the same control plane. Isolation is enforced at the overlay, not left to the underlying network.
Treat the device private key like a hardware secret. Store it in a TPM or secure element where the platform supports it, and rotate by re-enrolling rather than copying keys between devices.
A minimal edge peer
On a fresh embedded Linux image, bringing a device onto the overlay is three commands — generate a key, drop in the config, and start the tunnel:
# 1. Generate the device keypair
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
chmod 600 /etc/wireguard/private.key
# 2. Render wg0.conf from the enrollment response
mkdir -p /etc/wireguard
curl -fsS --cert /etc/iotocean/enroll.pem
https://enroll.iotocean.net/v1/peer
| jq -r '.wg_config' > /etc/wireguard/wg0.conf
# 3. Bring the tunnel up and persist it across reboots
systemctl enable --now wg-quick@wg0
From here on, the control plane reaches the device over 10.80.0.42 — for config pushes, backups, or a remote shell — and the device’s WAN firewall can deny every inbound packet.
Operating thousands of peers
A single tunnel is easy. The interesting engineering is in the fleet. Two properties matter most: tunnels must self-heal after connectivity gaps, and the control plane must know, in real time, which devices are actually reachable.
| Concern | Inbound model | Outbound-only model |
|---|---|---|
| Public attack surface | One per site | None |
| NAT / dynamic IP | Breaks it | Irrelevant |
| Onboarding a new site | Firewall change | Plug in & enroll |
| Revoking a device | Rotate site creds | Drop one public key |
WireGuard’s last-handshake timestamp is a far better health signal than ICMP. If a peer hasn’t completed a handshake within ~3× its keepalive interval, treat it as down — you’ll detect real outages seconds faster than waiting on ping timeouts.
Revocation is the part teams underestimate. In the inbound world, a lost device means rotating shared site credentials. Here, you delete one public key from the control plane and that device can never reconnect — no other peer is affected.
- Never let edge devices accept inbound connections — dial out instead.
- WireGuard +
PersistentKeepalivekeeps an outbound tunnel reachable through NAT and firewalls. - The device public key is its identity; revoke access by removing a single key.
- Enforce tenant isolation at the overlay, and monitor the last-handshake time as your primary health signal.
Outbound-only connectivity isn’t a new idea, but at the edge it’s the difference between a fleet you can sleep through the night with and one that’s a single open port away from an incident. Start every device with no doors — and open exactly none.
