Wireguard VPN Notes

Notes on how to put multiple peers in the same virtual private network with Wireguard on Linux.

Install the Wireguard tools, including wg-quick and probably some service definitions for it for the computer's service supervision suite. Its configuration seems to lie in /etc/wireguard/wg0.conf by default. That folder should exist with appropriate permissions, but the file probably won't. If running wg-quick manually, the wg0 portion must be specified explicitly anyway, so it could be different.

When needed, generate private keys with

$ wg genkey

pre-shared keys with

$ wg genpsk

and public keys from private keys with

$ wg pubkey
<the private key>
^D (CTRL+D)

or something like

$ echo <the private key> | wg pubkey

but only on a trusted machine, and it's still best to make sure it stays out of the command history, e.g.:

$ HISTCONTROL=ignorespace
$ <some whitespace> echo <the private key> | wg pubkey

Being careless with public keys is mostly fine, but preferably do not store the others outside the config file, or at least take reasonable precautions with them. 

Call one machine the server. On that one, the wg0.conf file looks like

[Interface]
Address = X.Y.Z.1/24
ListenPort = 12345
PrivateKey = <the server's private key>

[Peer]
PublicKey = <the client's public key>
AllowedIPs = X.Y.Z.2/32
PresharedKey = <the pre-shared key>

Address should be something in a private range like 192.168.7.1. ListenPort is some free UDP port; wg-quick's man pages uses 51820.

The [Peer] sections can and should repeat, one per client; however, Wireguard does not seem to try all sections with matching allowed IPs, so it is important that the IPs specified for a peer do not overlap with those of another peer. The pre-shared key is optional. It can be the same for every peer, but probably shouldn't, especially if those peers correspond to different (human) users. That is, it is only useful as an additional security measure if it is actually kept secret.

Call another machine the client. On that one, the wg0.conf file looks like

[Interface]
Address = X.Y.Z.2/24
PrivateKey = <the client's private key>

[Peer]
PublicKey = <the server's public key>
Endpoint = <server's IP or name>:12345
AllowedIPs = X.Y.Z.0/24
PresharedKey = <the same pre-shared key>
PersistentKeepalive = 25

The main differences are that while the server listens (ListenPort) and does not actively try to connect to peers, the client does not listen and actively tries to connect to a peer (Endpoint). The PersistentKeepalive setting should try to keep an otherwise-inactive "connection" alive by sending some kind of message every 25 seconds; Wireguard doesn't care about this but some firewalls do.

Finally, start Wireguard (on the server first, then on the client) manually as

# wg-quick up wg0

or with the supervision suite's command. Check on what what wq-quick has done with

# wg

The /24 netmask allows about 254 addresses, which is usually fine. The netmask should certainly include at least the two peers, though. This is all sufficient to allow the client to talk to the server, and the following commands should succeed from both machines:

$ ping X.Y.Z.1
$ ping X.Y.Z.2

Normally, though, Linux doesn't allow forwarding from one peer to another, so it is not possible for two clients to talk to each other despite being on the same subnet. To change this, run the following command on the server:

# sysctl net.ipv4.ip_forward=1

or modify /proc/sys/net/ipv4/ip_forward directly. This change is not persistent. Normally, Linux systems run sysctl --system on startup, though, which loads such rules from certain config files; sysctl's man page has details.

Comments