WireGuard — Lean, Modern VPN on the Command Line

Hands-on guide to WireGuard: generate key pairs, configure peers and AllowedIPs, manage tunnels with wg and wg-quick, and verify connections.

WireGuard is a modern, lean VPN protocol that runs directly inside the Linux kernel and gets by with just a few thousand lines of code – a fraction of OpenVPN or IPsec. Instead of negotiating ciphers, it relies on fixed, state-of-the-art cryptography (Curve25519, ChaCha20, Poly1305), which keeps the configuration remarkably simple. You manage keys, peers, and tunnel status with wg, and bring an interface up or down in seconds from a config file with wg-quick. Each node has a Curve25519 key pair; peers are linked by their public key, their AllowedIPs, and an endpoint. This guide takes you from key generation through peer management to troubleshooting a running tunnel.

Key Generation

wg genkey — Generate a private key (Curve25519). Never share the private key – lock the file down with chmod 600.

wg genkey > private.key

wg pubkey < <private-key-file> — Derive the matching public key from a private key; the public key can safely be shared with peers.

wg pubkey < private.key > public.key

wg genkey | tee private.key | wg pubkey > public.key — Generate both keys in one command.

wg genkey | tee private.key | wg pubkey > public.key

wg genpsk — Generate a pre-shared key for an additional symmetric layer of security.

wg genpsk > preshared.key

wg-quick (Easy Setup)

wg-quick up <interface> — Bring up a WireGuard interface using its config file.

wg-quick up wg0

wg-quick down <interface> — Tear down a WireGuard interface.

wg-quick down wg0

wg-quick strip <interface> — Show the config with wg-quick extras removed (pure wg format).

wg-quick strip wg0

systemctl enable wg-quick@<interface> — Enable WireGuard to start at boot.

systemctl enable wg-quick@wg0

systemctl start wg-quick@<interface> — Start WireGuard via systemd.

systemctl start wg-quick@wg0

wg Interface Management

wg show — Show the status of all WireGuard interfaces.

wg show

wg show <interface> — Show the status of a specific interface.

wg show wg0

wg show <interface> dump — Show the status in machine-readable format.

wg show wg0 dump

wg showconf <interface> — Show the running configuration.

wg showconf wg0

wg set <interface> listen-port <port> — Set the listening port.

wg set wg0 listen-port 51820

wg set <interface> private-key <file> — Set the private key for an interface.

wg set wg0 private-key /etc/wireguard/private.key

Peer Management

wg set <interface> peer <pubkey> allowed-ips <cidr> endpoint <host:port> — Add a peer to an interface. The AllowedIPs decide which destination IPs are routed through the tunnel – set them carefully, as they control both routing and security.

wg set wg0 peer ABC123...= allowed-ips 10.0.0.2/32 endpoint 203.0.113.1:51820

wg set <interface> peer <pubkey> remove — Remove a peer from an interface.

wg set wg0 peer ABC123...= remove

wg set <interface> peer <pubkey> persistent-keepalive <seconds> — Set the keepalive interval for NAT traversal.

wg set wg0 peer ABC123...= persistent-keepalive 25

wg set <interface> peer <pubkey> preshared-key <file> — Set a pre-shared key for a peer.

wg set wg0 peer ABC123...= preshared-key /etc/wireguard/psk.key

wg show <interface> latest-handshakes — Show when each peer last completed a handshake.

wg show wg0 latest-handshakes

wg show <interface> transfer — Show data transfer statistics per peer.

wg show wg0 transfer

Troubleshooting

wg show <interface> endpoints — Show the current endpoints for all peers.

wg show wg0 endpoints

ping -c 4 <peer-ip> — Test connectivity to a peer through the tunnel.

ping -c 4 10.0.0.2

ip addr show <interface> — Show the WireGuard interface IP configuration.

ip addr show wg0

ip route | grep <interface> — Check which routes go through the WireGuard tunnel.

ip route | grep wg0

journalctl -u wg-quick@<interface> — View the WireGuard systemd service logs.

journalctl -u wg-quick@wg0 -f

Conclusion

WireGuard proves a VPN doesn't have to be complicated: one key pair per node, a short config file, and two commands are enough for an encrypted tunnel. Pay attention to two things above all – keep the private key locked down (chmod 600, never share it) and set AllowedIPs deliberately, since they decide routing and therefore the security of your tunnel. Once you manage more than a handful of peers, pair WireGuard with systemd (wg-quick@) and a version-controlled config under /etc/wireguard/.

Further Reading

  • age – modern file encryption with simple keys
  • clamav – open-source virus scanner for files and mail
  • fail2ban – bans IPs after repeated failed logins