Tunnels and protocols

Keys, handshakes, and peers

See how peers authenticate each other, establish fresh session keys, and keep long-term private keys out of configuration sharing.

Each WireGuard peer has a private key and a public key. You share the public key and protect the private key. There are no usernames, no certificates, no accounts. A peer is its key pair.

If you have used SSH keys, this will feel familiar. The public key can travel anywhere: chat, email, a config file in a repo. The private key never leaves the device that generated it.

When two peers first exchange traffic, they perform a handshake. Each side proves it holds its private key. Together they derive fresh session keys, the short-lived symmetric keys that protect the actual traffic.

The long-term identity stays stable while the session keys rotate. Under active traffic, WireGuard performs a new handshake roughly every two minutes. So a stolen session key exposes a small window of traffic, never the whole history.

You can watch this happen. Let’s inspect a live interface:

sudo wg show
# interface: wg0
#   public key: hIhpm5DfIhSNQvvBpG0fWo6yQqYamOoO70QI0DGkfBM=
#   listening port: 51820
#
# peer: xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
#   endpoint: 198.51.100.44:53200
#   latest handshake: 34 seconds ago
#   transfer: 1.24 MiB received, 861.32 KiB sent

The latest handshake line is the most useful diagnostic in all of WireGuard. A recent handshake proves both sides hold the right keys and can exchange UDP. No handshake at all means identity or connectivity failed. Nothing else is worth checking until that line appears.

Now the part WireGuard does not do. It does not distribute keys, and it does not decide who should receive them. There is no login server and no revocation list. That work belongs to you: generate keys on each device, copy public keys between configs, and remove them when access should end.

Treat a peer key like an access credential. When a device is lost or no longer authorized, remove its key:

sudo wg set wg0 peer xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg= remove

Run sudo wg show again and that peer block is gone. The device can still send packets, but the server now drops them as if they came from a stranger.

Notice that this change lives only in the running interface. If the peer is still in /etc/wireguard/wg0.conf, the next restart brings it back. Remove it from the file too.

One mistake to avoid: copying a single private key to a second device because it seems convenient. Two devices then claim the same identity. The server flips the endpoint between their addresses each time one of them talks, and connections stall in confusing ways. Every device gets its own pair, always.

Lesson completed