Andrew Mercer

WireGuard: A Comprehensive Overview

1. What WireGuard Is

WireGuard is a modern VPN protocol and implementation designed to be simple, fast, and cryptographically sound. It was created by Jason Donenfeld and merged into the mainline Linux kernel (5.6+) in 2020. Compared to IPsec and OpenVPN, its entire codebase is small — roughly 4,000 lines vs. tens/hundreds of thousands for the alternatives — which makes it dramatically easier to audit and reason about.

Core design goals:
- Minimal attack surface — small, auditable codebase.
- High performance — kernel-space implementation (on Linux), tight crypto primitives, no negotiation overhead per-packet.
- Simplicity — no cipher negotiation, no complex state machine. One cryptographic suite, versioned as a whole; if it's ever broken, you upgrade the whole protocol rather than patch individual algorithm choices.
- UDP-based, connectionless — behaves like a stateless tunnel that "just works" across NAT and roaming networks (mobile device switching from WiFi to LTE keeps the tunnel alive).

2. Cryptographic Foundations

WireGuard uses a fixed, opinionated set of modern primitives (Noise Protocol Framework):

Purpose Algorithm
Key exchange Curve25519 (ECDH)
Symmetric encryption ChaCha20
Authentication (AEAD) Poly1305
Hashing BLAKE2s
Handshake Noise_IK (Noise Protocol Framework)
Key derivation HKDF

There's no algorithm agility — you don't choose ciphers like in OpenVPN/IPsec. This eliminates an entire class of misconfiguration and downgrade-attack risk.

Handshake (Noise_IK):
1. Each peer has a static Curve25519 keypair (private/public).
2. On first packet, an ephemeral key exchange occurs, authenticated by the peers' known static public keys.
3. Produces a new symmetric session key roughly every 2 minutes (or after ~2^60 messages), giving forward secrecy — a compromised key doesn't retroactively expose old traffic.
4. Includes a "silent" mode: WireGuard doesn't respond to unauthenticated packets at all, so a port scanner sees nothing (no port appears "open" without the right key) — this is the same property that makes it resistant to certain DoS and fingerprinting attacks.

3. Identity Model: Keys Instead of Certificates

This is the biggest conceptual shift from OpenVPN/IPsec:

  • No PKI, no certificate authority, no revocation lists.
  • Each peer (client or server) has a Curve25519 private key (keep secret) and derived public key (share it).
  • A peer's "identity" on the network is its public key.
  • The interface config lists the peers it trusts by public key, plus which IP ranges each peer is allowed to send/receive traffic for (AllowedIPs).

This means adding a device = generating a keypair and exchanging public keys — not issuing/signing/distributing certs. It also means revocation is manual: to remove a peer, you delete its entry from the config on the other side. There is no CRL/OCSP mechanism.

4. Core Concepts and Terminology

  • Interface: a virtual network device (e.g., wg0) that WireGuard creates. It has its own private key and an IP address in the tunnel's private subnet.
  • Peer: a remote endpoint you communicate with. Each peer entry has:
  • PublicKey — identifies the peer.
  • AllowedIPs — a whitelist of source/destination CIDR ranges for that peer. This does double duty as both a routing table and a cryptographic ACL — packets from a peer are only accepted if their source IP falls within that peer's AllowedIPs.
  • Endpoint (optional) — the peer's real IP:port, if it has one (not needed for peers behind NAT that only initiate).
  • PersistentKeepalive (optional) — sends a keepalive packet every N seconds to hold NAT mappings open (important for peers behind NAT/firewalls, e.g. road-warrior clients or IoT/homelab boxes).
  • Endpoint: the actual UDP IP:port a peer is reachable at.
  • ListenPort: UDP port the local interface listens on (default convention: 51820, but arbitrary).
  • Handshake: the key-exchange event; happens roughly every 2 minutes to rotate session keys.

5. AllowedIPs — the Part Everyone Gets Wrong

AllowedIPs is used differently depending on which side of the config you're looking at, and this trips up almost everyone the first time:

  • On the receiving side, it's a packet filter: only accept a packet from this peer if its source IP is in this range.
  • When building the routing table, it's used to decide which peer a destination IP should be routed through.

Examples:
- A client connecting to a single-server VPN with a full tunnel (route everything through the VPN) sets AllowedIPs = 0.0.0.0/0, ::/0 for the server peer.
- A client that only wants to reach the VPN server's LAN (split tunnel) sets AllowedIPs = 10.10.0.0/24 (the LAN CIDR) instead.
- On the server, each client peer typically gets AllowedIPs = <client's tunnel IP>/32 — i.e., "only this exact tunnel address may claim to be this peer."

Overlapping AllowedIPs across peers is not allowed on the same interface — WireGuard needs an unambiguous way to route/authenticate each packet.

6. Network Topologies

WireGuard doesn't inherently have a "client/server" model — every peer is symmetric. Common topologies:

  1. Road warrior (remote access): One "hub" (e.g., your home router) with a public endpoint; multiple client peers roam and connect in. Hub has each client's /32 in AllowedIPs; clients have the hub's LAN CIDR (or 0.0.0.0/0) in theirs.
  2. Site-to-site: Two networks (e.g., two homes, or home + cloud VPS) each have a gateway peer. Each side's AllowedIPs for the other lists the remote LAN CIDR, enabling routing between full subnets.
  3. Mesh: Every peer has a direct peer entry for every other peer. No central hub, but N peers requires managing N(N-1)/2 relationships — usually orchestrated by a tool (e.g., Tailscale, Netmaker, innernet) rather than by hand.
  4. Hub-and-spoke with LAN routing: A hub relays not just to itself but forwards to its whole LAN and possibly between spokes (requires explicit IP forwarding + firewall rules on the hub — this is the "route the whole network through WireGuard" pattern, covered in the companion OPNsense doc).

7. Performance Characteristics

  • Linux kernel module implementation avoids userspace/kernel context-switch overhead that plagues OpenVPN (which runs in userspace via TUN).
  • ChaCha20 is fast even without AES-NI hardware acceleration (relevant on ARM devices, low-power routers, phones), whereas AES-based ciphers benefit heavily from hardware acceleration and can lag on hardware without it.
  • Typically achieves throughput close to line-rate on modern hardware, and consistently outperforms OpenVPN and often IPsec in real-world benchmarks, especially on constrained CPUs (e.g., consumer router SoCs, small VPS instances, ARM SBCs).
  • Lower per-packet overhead (fixed 60-byte header vs. OpenVPN's larger, variable overhead) — better MTU efficiency.

8. Comparison to Other VPN Technologies

WireGuard OpenVPN IPsec/IKEv2
Codebase size ~4K LOC ~100K+ LOC Very large (multiple RFCs, vendor stacks)
Transport UDP only UDP or TCP UDP (ESP/IKE), sometimes TCP encapsulated
Identity Static keypairs X.509 certificates (typically) Certificates or PSK
Cipher agility None (fixed suite) Configurable Configurable
Kernel support Mainline Linux since 5.6 Userspace (TUN/TAP) Kernel (XFRM) on Linux, native on most OSes
Roaming / mobile friendliness Excellent (no renegotiation needed on IP change) Poor to moderate Moderate (IKEv2 MOBIKE helps)
Config complexity Low Moderate–high High
NAT traversal Simple (UDP + keepalive) Simple Can be finicky (NAT-T)
Built-in dead-peer detection No (relies on handshake timers/keepalive) Yes Yes
DPI resistance Fair, no ability to disguise as e.g. TLS/443 Good (can run over TCP/443) Fair

Practical takeaway: WireGuard is generally the better choice for point-to-point tunnels, road-warrior remote access, and site-to-site links where you control both ends. OpenVPN-over-TCP-443 is still relevant when you need to blend in with HTTPS traffic to get through restrictive firewalls/DPI. IPsec/IKEv2 remains common in enterprise/vendor-interop scenarios (native OS clients, older network gear) and where you don't control both ends.

9. Security Considerations and Caveats

  • No built-in user authentication layer. WireGuard authenticates devices (keys), not users. If you need per-user auth (e.g., 2FA, SSO), you build that on top (e.g., a portal that provisions keys, or pairing with something like a RADIUS-gated admin process) — WireGuard itself doesn't do it.
  • No revocation infrastructure. Losing a device means you must manually remove its peer entry everywhere it was trusted. Rotate keys and treat leaked private keys as you would a leaked SSH key.
  • Private key storage matters. Anyone with a peer's private key can impersonate it. On OPNsense/Linux, key files should have restrictive permissions; avoid pasting private keys into shared configs/tickets/chat (a good pass-style habit here).
  • Metadata isn't hidden. WireGuard doesn't provide traffic obfuscation — a firewall doing deep packet inspection can identify WireGuard traffic by its handshake pattern, even without decrypting it. If protocol obfuscation is a requirement, this isn't the tool (consider udp2raw, obfs4, or shadowsocks wrapping if that's genuinely needed).
  • DoS resistance is decent but not magic. The protocol's silent-drop behavior helps, but a flood of well-formed handshake-initiation packets can still cost CPU; WireGuard includes a cookie mechanism to mitigate this under load.
  • PresharedKey (PSK) option. In addition to the asymmetric handshake, WireGuard supports an optional per-peer symmetric preshared key for post-quantum defense-in-depth — it doesn't replace Curve25519, but layers a symmetric secret onto the handshake so that a future break of Curve25519 alone wouldn't be sufficient to decrypt captured traffic. Worth enabling for anything you consider higher-value.

10. Key Management Best Practices

  • Generate keys with wg genkey / wg pubkey (or your platform's equivalent UI, which usually wraps the same call).
  • Never reuse a keypair across multiple peers/devices.
  • Store private keys with 0600 permissions, owned by the service user.
  • Prefer a config-management or secrets tool (you already use pass — treating each peer's private key as a pass entry works well) over ad-hoc plaintext files scattered across hosts.
  • Rotate keys periodically for anything long-lived and high-trust (e.g., site-to-site links), and immediately on suspected compromise or device loss.
  • Use PresharedKeys for peers you consider high-value.

11. Operational Notes

  • MTU: Default WireGuard overhead is 60 bytes (IPv4) — a common baseline is setting the tunnel MTU to 1420 (from a standard 1500 underlying MTU) to avoid fragmentation; tune down further if the underlying path has its own overhead (e.g., PPPoE, double NAT, another tunnel).
  • Keepalives: Needed on any peer that sits behind NAT and doesn't itself receive unsolicited inbound handshakes (e.g., a phone, or a home box behind CGNAT) — typically PersistentKeepalive = 25 seconds.
  • DNS: WireGuard has no opinion on DNS. Full-tunnel clients (AllowedIPs = 0.0.0.0/0) usually also want a DNS = line pointing at an internal resolver, or their normal DNS resolution will still work but potentially leak query metadata to whatever resolver they're using, and access to internal-only DNS names (e.g., your homelab domain) will fail — the client's OS/wg-quick script needs to explicitly override resolv.conf during the tunnel session.
  • Logging/observability: wg show gives live peer state (last handshake, transfer stats). There's no built-in long-term logging — pair with your existing ELK/Prometheus stack if you want handshake/traffic history (e.g., scrape wg show output or firewall interface counters).

12. Where to Go Next

This document covers the protocol and concepts generally, independent of any specific platform. For a concrete, step-by-step implementation that routes an entire home/office network through WireGuard using OPNsense as the gateway — including firewall rules, NAT considerations, and both road-warrior and site-to-site patterns — see the companion document: wireguard-opnsense-whole-network-guide.md.

in this section
* routing the network wireguard
* wireguard overview