Howto: WireGuard on OpenBSD
Updated: June 28, 2022
Running WireGuard on OpenBSD is easy and pleasant. This is a minimalist howto for getting a basic server/client pair running such as in a "roadwarrior" or VPS setting.
OpenBSD server setup
On your existing OpenBSD server type the following as root:
sysctl net.inet.ip.forwarding=1
sysctl net.inet6.ip6.forwarding=1
echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf
echo "net.inet6.ip6.forwarding=1" >> /etc/sysctl.conf
mkdir -p /etc/wireguard
chmod 700 /etc/wireguard
cd /etc/wireguard
wg genkey > secret.key
chmod 600 secret.key
wg pubkey < secret.key > public.key
Now, create /etc/wireguard/wg0.conf. It should look something like this:
PrivateKey = aaaa
ListenPort = 51820
# client 1
[Peer]
PublicKey = BBBB
AllowedIPs = 10.0.0.2/32
Replace "aaaa" with the actual contents of the server's secret.key file you just created. Later, after setting up the client, replace "BBBB" with the actual contents of the client's public.key file.
Now set up /etc/hostname.wg0 to look like this:
up
!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf
Add the following to /etc/pf.conf:
pass in inet proto udp from any to any port 51820
pass out on egress inet from (wg0:network) nat-to (vio0:0)
Replace vio0 with whatever network device you have.
That's it, apart from putting the client's public key in the server's wg0.conf file.
OpenBSD client setup
The client setup is very similar to the server setup. On your existing OpenBSD client type the following as root:
mkdir -p /etc/wireguard
chmod 700 /etc/wireguard
cd /etc/wireguard
wg genkey > secret.key
chmod 600 secret.key
wg pubkey < secret.key > public.key
Now, create /etc/wireguard/wg0.conf. It should look something like this:
PrivateKey = bbbb
[Peer]
PublicKey = AAAA
Endpoint = 192.0.2.42:51820
AllowedIPs = 0.0.0.0/0, ::/0
Replace "bbbb" with the actual contents of the client's secret.key file you just created. Then replace "AAAA" with the actual contents of the server's public.key file. Replace 192.0.2.42:51820 with the actual public IP address and port (51820 is recommended) of your server. What is the AllowedIPs config line? It specifies that packets destined for these IP addresses go over WireGuard. IPs not in the list don't get sent over WireGuard. Here, 0.0.0.0/0 and ::/0 mean all IP addresses in IPv4 and IPv6, respectively.
Now set up /etc/hostname.wg0 to look like this:
up
!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf
Only a single line is strictly necessary in pf.conf, but of course feel free to keep your other pf rules:
Again, replace vio0 with whatever network device you have.
Finally, it's helpful to have a couple shell scripts to enable or disable the VPN. Put something like this into /etc/wireguard/enable.sh:
route add 192.0.2.42 192.168.0.1
route change default 10.0.0.1
Replace 192.0.2.42 with the actual public IP address of the remote WireGuard server, in case you want to directly SSH to it. Replace 192.168.0.1 with your typical (non-VPN) router/gateway IP address.
You can put something like this into /etc/wireguard/disable.sh:
route change default 192.168.0.1
With these scripts you can easily switch to or away from the VPN. There's typically no reason to have these scripts on the server. They only really benefit the client.
Wrapping it up
Now either reboot, or on both machines, run:
pfctl -f /etc/pf.conf
You can check your IP address with either of the following commands:
curl https://zx2c4.com/ip
Post-quantum security
It's not true post-quantum cryptography but mixing in a preshared key with the X25519 key agreement does protect against post-quantum attacks, and is useful until WireGuard and/or Noise adopt a pqcrypto key exchange. You can generate a PSK on OpenBSD with:
You can then add that key to your server wg0.conf and client wg0.conf, under the [Peer] section like so:
Replace CCCC with the actual contents of the PSK. This PSK is shared between both endpoints, your computer and the server. If you have multiple WireGuard peers, you can use a different PSK for each one. You can safely transmit this key using post-quantum cryptography already deployed OpenSSH by setting the following in your server's sshd.conf and your client's ssh.conf:
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org
Note than as of OpenBSD 7.1 / OpenSSH 9.0, sntrup761x25519-sha512@openssh.com is the default key exchange, so there's no need to modify your server's sshd.conf or client ~/.ssh/config files.
"Powered by WireGuard"