A few useful WireGuard commands
This page is a personal reminder about WireGuard commands I use frequently. WireGuard is…
[…] an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.
Terminology
In my personal experience, in a WireGuard network, there's an "always on" peer (the "server", like a VPS) and "client" peers that initiate the connection to the server. This is why the client/server terminology is used below, but WireGuard isn't inherently centralized. Tailscale, which is built on top of WireGuard, is actually a mesh VPN.
Generating keys
Generating keys is mandatory for all peers. You can generate these keys anywhere, on the peer itself or on another computer, as long as the private key stays secure.
wg genkey | tee private.key | wg pubkey > public.key
Then:
chmod 600 private.key
wg genkeygenerates a new private key and prints it to stdout.| tee private.keysaves that private key intoprivate.keyand also passes it onward through the pipe.| wg pubkeyreads the private key from stdin and derives the corresponding public key.> public.keywrites the public key into public.key.chmod 600 private.keyrestricts the private key file to its owner.
Server config
Usually, you would begin with the "server", only specifying an interface, without peers since you didn't define any:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = ${SERVER_PRIVATE_KEY}
Address = 10.8.0.1/24assigns 10.8.0.1/24 to this interface and treats 10.8.0.0/24 as directly reachable from it.For the address range, choose any unused private subnet, commonly one from RFC1918.
ListenPort = 51820is the UDP port WireGuard listens on. 51820 is WireGuard's common default.${SERVER_PRIVATE_KEY}is the server's private key you generated. It will be used by the server to decrypt traffic that is sent by peers, who themselves will encrypt traffic using the server's public key.
Client config
Generate keys for the client and create the config:
[Interface]
Address = 10.8.0.2/32
PrivateKey = ${CLIENT_PRIVATE_KEY}
DNS = 10.8.0.1
[Peer]
Endpoint = 203.0.113.10:51820
PublicKey = ${SERVER_PUBLIC_KEY}
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 25
Address = 10.8.0.2/32is the WireGuard interface IP address on the client.${CLIENT_PRIVATE_KEY}is the client's private key.DNS = 10.8.0.1is optional: if specified, DNS requests will be routed through the WireGuard server when WireGuard is up. If you are targeting a server on which a custom DNS (likednsmasq) resolves private URLs (such asapplication.vps.internal), this can be useful.Endpoint = 203.0.113.10:51820is the remote IP or host name of the server, with the WireGuard port.203.0.113.10is just a random example, replace it with your server's public IP address or DNS name.${SERVER_PUBLIC_KEY}is the server public key. It will be used to encrypt traffic towards the server.AllowedIPsis important: it defines what traffic will go through WireGuard. Here, only traffic to the WireGuard IP of the server (10.8.0.1/32) will go through WireGuard. The/32means "this exact IPv4 address only", instead of the whole10.8.0.0/24subnet. Use the whole subnet if you already know you will add more peers and you want to reach them through the server ("hub-and-spoke" configuration).If you want all client traffic to go through the VPN, use
AllowedIPs = 0.0.0.0/0, ::/0instead. In that case, the VPS also needs to forward traffic, and usually needs NAT, for the client to reach the public internet through it.
Adding the peer to the server config
Once your client is ready, add it to the server config:
# Already defined above -------------|
[Interface] # |
Address = 10.8.0.1/24 # |
ListenPort = 51820 # |
PrivateKey = ${SERVER_PRIVATE_KEY} # |
# -----------------------------------|
# ${CLIENT_NAME}
[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = 10.8.0.2/32
Here too, /32 means that this peer is only allowed to use
10.8.0.2. If you add more clients later, each one should get its own
IP address and its own /32 route.
Restart WireGuard on the server:
sudo systemctl restart [service]
Generating QR codes
The WireGuard Android application supports importing a config as a QR code. Let's say you generated a client config on your computer, then added the peer to your server, and now you want to import that client config on your phone.
Generate a QR code:
qrencode -o wg0.png < wg0.conf
For terminal scanning, also print the QR code directly:
qrencode -t ansiutf8 < wg0.conf
Check the PNG:
zbarimg -q wg0.png
Import the PNG on your phone, connect, and check on the server after connecting:
sudo wg show
See also
You (and I 😄) should take a look at Tailscale, which is built on WireGuard.

