Skip to main content WireGuard | IoT Worker

WireGuard

WireGuard’s configuration is usually much shorter than IPsec or OpenVPN, and it comes up quickly. The part that is easy to misread is not the small command set, but the fact that it compresses the tunnel, the security session, the routing constraint, and the peer identity into a very tight model. wg0 being up does not mean the service traffic can reach its destination, and a handshake that looks successful does not mean your routes and the peer’s allowed prefixes actually line up.

The most important thing to grasp first is not the handful of fields in the config file, but the specific job WireGuard is doing: on top of UDP, it uses a fixed and restrained cryptographic design to build a point-to-point secure tunnel, and it folds “which public key is allowed to send which prefixes” directly into the forwarding table. It is not trying to be a general-purpose negotiation platform. It is trying to keep the most common secure-tunnel path short and solid.

WireGuard does not first create an abstract VPN session and then attach routes later. It narrows identity, public key, tunnel endpoint, and allowed prefixes into a tightly coupled data-plane model.

What Problem It Solves

If you look back at the engineering reality of traditional VPNs, the pain is usually not “can it encrypt,” but “once the encrypted tunnel enters real deployment, negotiation, compatibility, and operations complexity grow fast.”

  • IPsec is powerful, but it has many conceptual layers and a heavy negotiation and implementation surface
  • OpenVPN is flexible to deploy, but the user-space implementation, TLS dependency, and configuration combinations also make troubleshooting longer
  • Mobile devices and home-networked equipment often change public IP addresses, so the tunnel must tolerate endpoint changes
  • Many real-world needs are just “keep a secure layer-3 tunnel up between a few machines,” not “bring in a full VPN control plane”

WireGuard targets exactly that kind of scenario: do not expose too many negotiable options in the protocol, and do not make the implementation carry a large historical compatibility burden. Instead, make the things most commonly needed for a secure tunnel part of the default path.

Its value is not “the most features,” but “the smallest necessary set, implemented very firmly.” That choice shapes many of the design decisions that look unusual at first glance.

Who Built It, and in What Context

WireGuard was originally started by Jason A. Donenfeld, and its goal has always been very clear: build a modern, compact, easy-to-audit layer-3 VPN protocol and implementation. It is not the kind of early Internet protocol that grew slowly under strong historical compatibility pressure. It is obviously shaped by the experience of seeing the complexity of earlier VPN generations and intentionally narrowing the design surface.

That shows up directly in its style:

  • It runs on UDP by default and does not bind itself to a connection-oriented transport
  • It avoids algorithm negotiation as much as possible, reducing implementation branches and downgrade surface
  • It leans toward kernel data-plane integration and system routing rather than inventing another complex control plane inside the protocol
  • It assumes the operator already knows the peer public keys and will either configure them manually or distribute them through an external system

So WireGuard is not a protocol that tries to “automatically discover peers and automatically distribute every policy.” It is more like a sharp infrastructure building block. Identity, address assignment, authorization, and orchestration can live around it, but it does not try to own all of them itself.

Follow One Main Path First

A common successful path through WireGuard can be compressed like this:

  1. The local interface has a static private key, and each peer already knows the other side’s public key
  2. The local side binds certain AllowedIPs to a peer
  3. When the kernel is about to send a packet for a target prefix into the tunnel, it finds that it matches some peer’s allowed prefix
  4. If there is no usable session key yet, it initiates a handshake based on NoiseIK
  5. After the handshake completes, the datagram is encapsulated into UDP and sent to the peer using the latest known endpoint
  6. The peer uses the public key to identify the sender, verify and decrypt the packet, then checks whether the source is legal against its local AllowedIPs

Logically, you can think of it this way:

inner IP packet
  -> lookup peer by AllowedIPs
  -> handshake if needed
  -> encrypt into WireGuard data message
  -> send via UDP to peer endpoint
  -> peer decrypts and validates source prefix
  -> peer reinjects inner IP packet

The most important thing in this path is not the packet name, but two decisions:

  • Peer selection and route selection are tied together
  • The handshake is not something that exists permanently ahead of time; it is established on demand and rotated over time

So WireGuard looks “very much like a VPN,” but its mental model is closer to “identity-constrained point-to-point encrypted forwarding” than many traditional VPNs.

Why It Was Designed This Way

Why It Tries Hard to Avoid Algorithm Negotiation

In traditional security protocols, algorithm negotiation looks flexible, but flexibility usually brings two kinds of cost:

  • The implementation must maintain more branches, more compatibility paths, and more downgrade risk
  • During troubleshooting, you first need to confirm what the two sides actually negotiated before you can even tell which layer is broken

WireGuard’s choice is very clear: the core cryptographic suite is as fixed as possible instead of letting operators compose it from a long list of options.

That brings direct benefits:

  • The configuration surface shrinks dramatically
  • The code becomes easier to audit
  • Many interop problems caused by different negotiation outcomes disappear by design

The tradeoff is just as clear:

  • The protocol does not try to be compatible with every historical algorithm
  • In some cases, you cannot rescue a deployment by “switching to an older or more common suite”

It is not that negotiation is unknown. It is that WireGuard explicitly decides that, for its target scenarios, fewer options are more valuable than more options.

Why It Requires Pre-Shared Public Keys Instead of Doing Complex Identity Negotiation on the Fly

WireGuard’s peer model naturally requires you to know the other side’s public key first. People who see it for the first time often feel it is not automated enough, but that is exactly what makes the control plane simpler.

If the protocol itself had to handle full identity discovery, certificate-chain validation, policy distribution, and network orchestration, it would immediately become a different kind of system. WireGuard deliberately does not do that. It narrows the problem to:

  • What is this peer’s long-term identity public key?
  • Which tunnel-local addresses or prefixes is this public key allowed to represent?
  • Which outer IP:port should receive the encapsulated UDP packet right now?

The benefit is a very hard identity boundary:

  • The public key is the peer identity
  • The binding between the peer and allowed prefixes becomes part of the forwarding decision
  • The protocol itself does not need to maintain a whole PKI control flow

The tradeoff is that automatic discovery does not magically appear. Large-scale provisioning, key rotation orchestration, and address planning usually have to be solved by external systems.

Why AllowedIPs Looks Like Both Routing and Access Control

This is one of WireGuard’s most important and most frequently misunderstood design choices.

Many traditional VPNs treat “build the tunnel first” and “which networks may use the tunnel” as separate concerns. WireGuard does not. For WireGuard, AllowedIPs has at least two roles:

  • On the outbound path, it acts like a prefix lookup table for choosing a peer, deciding which inner destination address should be handed to which peer
  • On the inbound path, it acts like a source constraint, deciding whether the source address decrypted from a peer is legal for that peer to claim

That is what people mean by cryptokey routing: instead of first having a neutral tunnel and then layering access control on top with another system, the fact that “which public key may carry which prefixes” is itself part of the data plane.

The value of that design is significant:

  • The peer-selection path is very direct
  • Source spoofing constraints are naturally tied to identity
  • The configuration mental model stays clean for small point-to-point or hub-and-spoke deployments

But the tradeoff is also real:

  • Slightly overlapping prefix plans quickly introduce routing ambiguity or incorrect matches
  • When something breaks, you cannot look only at the handshake; you must also inspect AllowedIPs
  • It does not learn topology automatically the way a dynamic routing protocol does, so complex networks need extra orchestration

Many “WireGuard is connected but traffic does not flow” cases are fundamentally about this rather than about cryptography.

Why the Handshake Is On-Demand and Session Keys Rotate Regularly

WireGuard does not try to keep a permanent, always-on control connection. It is closer to “make sure there is usable key state when data needs to be sent.”

This model has several benefits:

  • Idle periods carry almost no extra control traffic
  • Session keys can be updated regularly instead of using long-term keys directly for data-plane protection
  • Temporary link loss and endpoint changes are handled more naturally

The tradeoff is:

  • Seeing “no handshake recently” is not automatically a failure; there may simply be no traffic
  • During real troubleshooting, you must distinguish “no traffic triggered a handshake” from “traffic exists but the handshake failed”

The WireGuard handshake path is based on NoiseIK. In essence, it quickly establishes temporary session keys on the basis that both sides already know each other’s static public keys, and it gives the subsequent data packets forward secrecy. What matters most operationally is that result, not memorizing every cryptographic sub-step.

Why It Fits Roaming and NAT-Side Peers So Well

One of the biggest VPN headaches is that if one side’s public address changes, the whole tunnel often feels like it has to rebuild identity. WireGuard separates “who the peer is” from “where the peer’s packets are currently arriving from.”

In practice, a peer’s endpoint can be updated by the latest valid packet. As long as:

  • The packet can be correctly decrypted and identity-checked
  • The new address is indeed the current outer address that the peer can reach

The local side can start sending replies to the new endpoint.

That means:

  • A phone moving from Wi-Fi to cellular can keep the tunnel much more smoothly
  • A device behind home NAT can change public address without necessarily requiring a full reconfiguration

The boundary is still important:

  • The protocol is not a public peer-discovery service
  • At least one side still has to be able to send the first packet to a currently reachable address on the other side

So roaming support is strong, but that does not mean it magically solves every NAT traversal problem.

Why PersistentKeepalive Is an Engineering Patch, Not the Main Character

Many deployment guides suggest configuring PersistentKeepalive on the NATed side. That is common, but it should not be mistaken for WireGuard’s core mechanism.

More precisely, it solves a very practical problem: some NAT mappings age out quickly. If there is no outbound traffic for a while, the outside world no longer knows which mapped port to use for return traffic.

So sending a tiny keepalive packet periodically can stop that mapping from disappearing too quickly.

Its value is concrete:

  • It helps the NATed side keep a returnable UDP mapping alive
  • It makes it easier for the peer to reconnect even when there is no steady application traffic

Its cost is also concrete:

  • It creates background traffic
  • A too-short interval wastes bandwidth, while a too-long interval may fail to preserve the mapping

So PersistentKeepalive is not “always required by default.” It is “turn it on when the NAT reality forces you to.”

Design Details That Look Simple but Are Easy to Misread

A Successful Handshake Does Not Mean the Service Is Reachable

This is the most common wrong assumption. A successful handshake only means:

  • The peer public key configuration is probably correct
  • The current endpoint is reachable at least at this moment
  • A session key has been established

It does not guarantee:

  • The inner address plan is correct
  • AllowedIPs match on both sides
  • The system route actually sends the target traffic into the wg interface
  • The peer’s kernel will forward the decrypted packets onward to the network behind it

So troubleshooting cannot stop at latest handshake.

AllowedIPs = 0.0.0.0/0 Is Not Just “Allow Everything”

Many client tutorials use 0.0.0.0/0, ::/0 for full-tunnel setups. That can certainly mean “send the default route through this peer,” but in WireGuard it is not just an abstract permission statement. It directly affects peer selection too.

That means:

  • On a client, it is often used to point the default route at the VPN
  • On a server or in a more complex topology, if the prefix plan across peers is unclear, these large prefixes can quickly create ambiguity

So AllowedIPs has to be viewed both as “what is allowed” and as “how traffic will be selected.”

WireGuard Is a Layer-3 Tunnel, Not an Automatic Control Plane

If an article describes WireGuard as a “networking system,” the boundary is usually already too broad. What WireGuard really provides stably is:

  • Peer identity and key relationships
  • Encrypted encapsulation on top of UDP
  • Prefix-based peer selection and source constraints

Things like:

  • Automatic address allocation
  • Dynamic route propagation
  • Certificate and key fleet management
  • ACL orchestration, user management, and multi-tenant isolation

can all be built around WireGuard, but they are not native protocol features.

What Engineers Should Actually Look At

When implementing, deploying, or troubleshooting, the four boundaries worth watching first are:

First check whether any traffic actually enters the tunnel selection path

If the local machine never sends a packet that matches a peer’s AllowedIPs, then there will be no handshake and no data forwarding. Many cases where “the tunnel is dead quiet” are really just routing never sending packets into wg0.

Then check whether the latest handshake and endpoint look as expected

If there is traffic triggering the tunnel but latest handshake does not update for a long time, the likely suspects are:

  • The outer UDP path is unreachable
  • A port or firewall is blocking it
  • The endpoint is configured incorrectly
  • The NAT mapping has expired and the keepalive strategy is wrong

Then check whether both send and receive counters are increasing

If only the send side grows and the receive side does not, packets are probably going out but not coming back. If both sides are increasing but the application is still broken, shift attention to the inner addresses, system routing, forwarding, and the service above them.

Finally verify AllowedIPs and the forwarding boundary

This is where high-frequency problems appear:

  • The local side handed the destination prefix to the wrong peer
  • The peer judged the decrypted source address to be illegal
  • A relay node never enabled kernel forwarding
  • The real service network behind the peer has no return route

WireGuard troubleshooting is often very efficient, but only if you separate the problem into layers: outer UDP, handshake state, tunnel send/receive, and inner routing/forwarding. If you just call everything “the VPN is down,” you lose the clarity that makes the model useful in the first place.

Further Reading

  • If you want to understand why the service is still unreachable after the layer-3 tunnel is up, continue with NAT, routing, DNS, and the host forwarding model

  • If you want to understand security sessions in datagram networks, read DTLS alongside this article to see the difference between WireGuard and a “TLS over UDP” style

  • TLS

  • UDP