WireGuard replaced a decade of IPsec configuration with a text file. That is not an exaggeration: a working tunnel is an interface, a private key, and a peer with a public key and an allowed-IP list.
The simplicity is real, and it moves the complexity somewhere else — into key distribution and into the single field that means two different things at once.
The model
| Concept | Meaning |
|---|---|
| Interface | A virtual NIC with its own private key and address |
| Peer | A remote public key, an endpoint, and a set of allowed IPs |
| AllowedIPs | Both the routing table and the crypto filter |
| PersistentKeepalive | Keeps NAT mappings open |
There is no negotiation, no proposal list, no phase 1 and 2. If two peers have each other's public keys, they can talk. If they do not, they cannot.
The configuration
[Interface]
PrivateKey = <local private key>
Address = 10.99.0.2/24
ListenPort = 51820
[Peer]
PublicKey = <remote public key>
AllowedIPs = 10.50.0.0/16, 10.0.0.0/8
Endpoint = 203.0.113.20:51820
PersistentKeepalive = 25
Four lines per peer. The entire tunnel.
AllowedIPs means two things
This is the field that causes most WireGuard mistakes:
- Outbound routing: packets to these prefixes are sent to this peer.
- Inbound filtering: packets arriving from this peer must have a source inside these prefixes.
So AllowedIPs = 0.0.0.0/0 means "send everything here" and "accept anything from here." A peer with
that setting can route arbitrary traffic through you if forwarding is enabled.
For a site link, be explicit:
AllowedIPs = 10.50.0.0/16
That routes the campus block to the peer and refuses to accept packets claiming any other source.
WireGuard is not a user authentication system
A key is an identity. If a laptop is lost, the key is compromised, and the only remedy is removing the peer. There is no password, no MFA, no session. Pair it with device management, or do not use it for staff endpoints.
Roaming
WireGuard peers are identified by public key, not by address. When an authenticated packet arrives from a new endpoint, the peer's endpoint is updated. A phone moving from Wi-Fi to cellular keeps its tunnel without renegotiation.
That is excellent for mobile devices and slightly alarming for security: an attacker who obtains a private key can use it from anywhere, and the tunnel will follow them.
Worked example: two sites
District gateway 10.0.0.1, campus 10.50.0.1, a small WireGuard link as a backup path.
District:
[Interface]
PrivateKey = ...
Address = 10.99.0.1/30
[Peer]
PublicKey = <campus>
AllowedIPs = 10.50.0.0/16
Endpoint = 203.0.113.20:51820
PersistentKeepalive = 25
Campus:
[Interface]
PrivateKey = ...
Address = 10.99.0.2/30
[Peer]
PublicKey = <district>
AllowedIPs = 10.0.0.0/8
Endpoint = 198.51.100.5:51820
PersistentKeepalive = 25
Then add the static route and a floating distance, exactly as in the routing series. WireGuard carries packets; the routing table still decides which ones.
What breaks in production
- AllowedIPs too broad, turning a peer into a transit router.
- Key reuse across devices, so revoking one revokes all.
- No keepalive behind NAT, so the tunnel dies after 30 seconds of silence.
- MTU left at 1420 on a path that needs less, producing the classic ping-works-TLS-hangs.
- No key rotation plan, so a departed employee's key stays valid.
- Forwarding enabled without firewall rules, so the tunnel becomes a pivot point.
Checklist
- Each device has its own key pair; no sharing.
- AllowedIPs is the minimum set of prefixes, not
0.0.0.0/0by default. - Keepalive is set on any peer behind NAT.
- MTU is tested with large packets, not assumed.
- Keys are inventoried, with an owner and a removal date.
- Forwarding is disabled unless the peer is a router.
Next
WireGuard is modern and minimal. Continue with TLS VPNs and Client Access for the approach that looks like a website.