Skip to content

CONCEPT Cited by 1 source

WireGuard handshake

The WireGuard handshake is the exchange of UDP packets that establishes a WireGuard session. Specified in detail in the WireGuard paper. Properties relevant to systems design:

  • Four message types, each identified by a single plaintext byte at offset 8 in the UDP payload: 1 = handshake initiation, 2 = handshake response, 3 = cookie reply, 4 = transport data.
  • Two-message handshake. Initiator sends a handshake initiation; responder sends a handshake response; both sides then hold symmetric keying material for transport data. No 3-way TCP-shaped sequence.
  • Identity-hidden. Built on Noise — the initiator's static public key is encrypted by the handshake. (Source: sources/2024-03-12-flyio-jit-wireguard-peers)
  • Transport: UDP port 51820 by default; easily tunnelled over WebSockets, TCP, etc., because the handshake is self-contained datagrams.

Filter shape

Because the packet type is plaintext at offset 8, a BPF filter for "incoming handshake initiation" is a three-primitive + one-byte-compare:

udp and dst port 51820 and udp[8] = 1

(Source: sources/2024-03-12-flyio-jit-wireguard-peers)

This is the data-plane event source Fly.io uses to drive JIT peer provisioning — see patterns/bpf-filter-for-api-event-source.

Initiator / responder

WireGuard handshakes are symmetric about which end is the initiator. "WireGuard doesn't have notions of 'client' or 'server'. It's a pure point-to-point protocol; peers connect to each other when they have traffic to send. The first peer to connect is called the initiator, and the peer it connects to is the responder." (Source: sources/2024-03-12-flyio-jit-wireguard-peers)

This symmetry is what patterns/initiator-responder-role-inversion exploits — if Fly's gateway has just installed a peer whose initiation packet it sniffed, it can swap roles and originate the next handshake itself to that peer's ephemeral source port, bringing the session up at install-speed rather than waiting on the client's retry.

Seen in

Last updated · 200 distilled / 1,178 read