WireGuard CLI

WireGuard CLI cheatsheet — set up fast, modern VPN tunnels. wg-quick up/down wg0, wg show, wg genkey, wg pubkey. Configure peers, IP ranges, and persistent keys in wg0.conf.

6 min read

What it is

WireGuard is a simple, fast, and modern VPN that runs over UDP, designed for ease of use and high performance. You reach for it to create secure, point-to-point tunnels between machines.

Installation

Linux

sudo apt update && sudo apt install wireguard
# or on Fedora/CentOS/RHEL
sudo dnf install wireguard-tools
# or on Arch Linux
sudo pacman -S wireguard-tools

macOS

Using Homebrew:

brew install wireguard-tools

Note: The macOS GUI client from wireguard.com is recommended for ease of use. The wg command-line tools are installed by wireguard-tools.

Windows

Download the installer from the official WireGuard website: https://www.wireguard.com/install/ The installer includes the GUI and the necessary command-line tools.

Core Concepts

  • Interface: A virtual network interface created by WireGuard (e.g., wg0). It has an IP address and listens on a UDP port.
  • Peer: A remote WireGuard endpoint. Each peer is identified by its public key.
  • Public Key: A cryptographic key used to identify a peer and encrypt/decrypt traffic.
  • Private Key: A secret cryptographic key used to sign and decrypt traffic. Must be kept secure.
  • Pre-shared Key (Optional): An additional secret key shared between two peers for an extra layer of symmetric authentication.
  • Endpoint: The public IP address and UDP port of a remote WireGuard peer.
  • AllowedIPs: A list of IP addresses or CIDR ranges that WireGuard will route through the tunnel to a specific peer. This is crucial for defining what traffic goes over the VPN.

Commands / Usage

Interface Management

Creating a new interface and private/public keys:

wg genkey | tee privatekey | wg pubkey > publickey
  • wg genkey: Generates a new private key.
  • tee privatekey: Writes the private key to a file named privatekey and also pipes it to the next command.
  • wg pubkey > publickey: Reads the private key from standard input and generates the corresponding public key, saving it to publickey.

Viewing interface status:

wg show wg0
  • Shows the status of the wg0 interface, including its public key, listening port, and details about its peers.

Listing all WireGuard interfaces:

wg
  • Lists all active WireGuard interfaces on the system.

Configuration

WireGuard configurations are typically stored in .conf files (e.g., /etc/wireguard/wg0.conf).

Example wg0.conf (Client):

[Interface]
PrivateKey = <client_private_key_content>
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <server_public_key_content>
Endpoint = 192.0.2.1:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

Example wg0.conf (Server):

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

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

Bringing an interface up:

sudo wg-quick up wg0
  • Reads the configuration from /etc/wireguard/wg0.conf and creates/configures the wg0 interface.

Bringing an interface down:

sudo wg-quick down wg0
  • Removes the wg0 interface and cleans up associated routes.

Reloading configuration:

sudo wg-quick reload wg0
  • Applies changes from the configuration file without bringing the interface down. Useful for adding/removing peers or changing endpoint IPs.

Creating a configuration file:

sudo wg-quick tun 10.0.0.5/24 wg0
  • Creates a new TUN device named wg0 with the IP address 10.0.0.5/24, generating keys and a basic config file in /etc/wireguard/.

Key Generation and Management

Generate a new private key:

wg genkey
  • Outputs a new private key to standard output.

Derive the public key from a private key:

echo "<your_private_key>" | wg pubkey
  • Takes a private key from standard input and outputs the corresponding public key.

Generating a pre-shared key (PSK):

wg genpsk
  • Outputs a new pre-shared key to standard output.

Cryptokey Routing (Advanced)

WireGuard uses AllowedIPs to control routing. You can manually manipulate these routes using standard OS tools, but wg-quick handles this automatically based on the AllowedIPs in the configuration.

Common Patterns

Setting up a simple client-to-server VPN:

  1. On the server: Generate keys, create server config (/etc/wireguard/wg0.conf), run sudo wg-quick up wg0.
  2. On the client: Generate keys, get server’s public key, create client config (/etc/wireguard/wg0.conf), run sudo wg-quick up wg0.
  3. Ensure server’s firewall allows UDP traffic on the WireGuard port (e.g., 51820).
  4. Ensure client’s firewall allows outgoing traffic.

Routing all client traffic through the VPN (full tunnel): In the client’s wg0.conf, set AllowedIPs = 0.0.0.0/0, ::/0 under the server peer. On the server, ensure IP forwarding is enabled (net.ipv4.ip_forward=1 in sysctl.conf) and configure iptables or nftables for NAT.

Routing only specific client subnets through the VPN (split tunnel): In the client’s wg0.conf, set AllowedIPs to the specific internal subnets you want to reach via the VPN (e.g., AllowedIPs = 10.0.0.0/24, 192.168.1.0/24).

Keeping a peer connection alive (client-side): Add PersistentKeepalive = 25 to the [Peer] section of the client configuration. This sends a UDP packet every 25 seconds to keep the connection open through NAT.

Adding a new peer to a running server without downtime:

  1. Generate keys for the new peer.
  2. Add the new peer’s public key and AllowedIPs to the server’s wg0.conf.
  3. Run sudo wg-quick reload wg0.
  4. Configure the new peer’s client with the server’s public key and its own private key.

Using a pre-shared key for extra security: Add PresharedKey = <psk_content> to both the [Peer] section on one side and the corresponding [Peer] section on the other side.

Gotchas

  • AllowedIPs is Bidirectional: The AllowedIPs setting on a peer defines which source IP addresses are allowed from that peer, and also which destination IP addresses will be routed to that peer. This is a common point of confusion.
  • Firewall Rules: WireGuard itself doesn’t manage host firewalls. You need to ensure:
    • The server’s firewall allows UDP traffic on the WireGuard listening port.
    • Clients can send UDP traffic to the server’s endpoint IP/port.
    • If acting as a router/gateway, the server needs IP forwarding enabled and appropriate NAT rules (iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE).
  • Key Security: Private keys must be kept absolutely secret. If compromised, an attacker can impersonate your endpoint. Ensure file permissions restrict access to .conf files containing private keys (e.g., chmod 600 /etc/wireguard/wg0.conf).
  • IP Address Conflicts: Ensure the IP addresses assigned to WireGuard interfaces and the AllowedIPs ranges do not conflict with your existing local network subnets.
  • NAT Traversal: While WireGuard handles UDP well, some aggressive NAT devices or firewalls might interfere. PersistentKeepalive helps maintain state.
  • wg-quick vs. wg: wg-quick is a script that automates setting up interfaces, keys, and routing based on .conf files. The raw wg command is lower-level and used for inspecting status and managing keys. wg-quick up wg0 is the typical way to start an interface.
  • DNS Resolution: WireGuard doesn’t inherently handle DNS. You need to specify DNS servers in the [Interface] section of your .conf file (e.g., DNS = 1.1.1.1) or configure your system’s DNS resolver manually.