WireGuard

Set up fast, modern VPN tunnels with WireGuard using public-key cryptography on Linux, macOS, and Windows.

WireGuard

WireGuard is a modern VPN protocol and tool that creates encrypted point-to-point tunnels using public-key cryptography, built into the Linux kernel since version 5.6.

What WireGuard Does and When to Use It

WireGuard establishes encrypted network tunnels between peers using Curve25519 for key exchange, ChaCha20 for symmetric encryption, and Poly1305 for authentication. Its codebase is approximately 4,000 lines of code — drastically smaller than OpenVPN (~100,000 lines) or IPsec implementations. This minimal surface area makes WireGuard easier to audit and less likely to contain security vulnerabilities.

WireGuard operates at the kernel level on Linux (built-in since kernel 5.6) and as a userspace application on macOS, Windows, iOS, and Android. It assigns a virtual network interface ( wg0) and routes traffic through an encrypted UDP tunnel. Configuration uses a single file per interface — no certificate authorities, no connection negotiation, no complex PKI infrastructure.

WireGuard is not a full VPN solution with user management, SSO, or access control. For those features, consider Tailscale (built on WireGuard) or Firezone. WireGuard handles the tunnel — identity management and network policy are separate concerns. For official documentation, see wireguard.com.

How to Install WireGuard

=== "Ubuntu / Debian"

sudo apt install wireguard

=== "RHEL / CentOS / Fedora"

sudo dnf install wireguard-tools

=== "macOS"

brew install wireguard-tools

Verify the installation:

wg --version

Core Concepts of WireGuard

WireGuard Key Pairs

WireGuard uses asymmetric cryptography. Each peer generates a private key and derives a public key from it. Peers exchange public keys out-of-band (manually, via a config management tool, or through a coordination service). The private key never leaves the host.

WireGuard Peers and AllowedIPs

A WireGuard peer is any endpoint that holds the other side's public key. The AllowedIPs setting in the peer's configuration defines which IP ranges the peer is authorized to send traffic from. WireGuard uses AllowedIPs as both a routing table and an access control list — traffic from a peer is accepted only if its source IP matches the peer's AllowedIPs entry.

WireGuard Interface Configuration

WireGuard configuration files live at /etc/wireguard/wg0.conf (the interface name is derived from the filename). The [Interface] section defines the local private key, listening port, and tunnel IP address. Each [Peer] section defines a remote peer with its public key, endpoint (IP:port), and allowed IP ranges.

Common Tasks with WireGuard

How to Generate WireGuard Key Pairs

Generate a private key and derive the public key with wg genkey and wg pubkey:

wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
chmod 600 /etc/wireguard/private.key

How to Configure a WireGuard VPN Tunnel

Create /etc/wireguard/wg0.conf on the server with the local interface and a peer definition:

[Interface]
PrivateKey = <SERVER_PRIVATE_KEY>
Address = 10.0.0.1/24
ListenPort = 51820

[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32

Bring the interface up:

sudo wg-quick up wg0

Enable the tunnel at boot:

sudo systemctl enable wg-quick@wg0.service

How to Check WireGuard Tunnel Status

The wg show command displays the current state of all WireGuard interfaces — active peers, last handshake time, and data transferred:

sudo wg show

WireGuard Troubleshooting

Error / SymptomCauseFix
No handshake occurs between peersFirewall blocks UDP port 51820, or endpoint address is incorrect→ Full article
Traffic routes through tunnel but no internet accessMissing PostUp iptables NAT/masquerade rule on the server→ Full article
RTNETLINK answers: Operation not supportedWireGuard kernel module is not loaded or not installed→ Full article
DNS resolution fails over tunnelDNS server is not set in [Interface] or system resolv.conf is not updated→ Full article

UFW firewall rules must allow UDP traffic on WireGuard's listening port (default 51820). See the UFW article.

SSH can be tunneled over a WireGuard VPN for secure remote server management. See the SSH article.