Howto: WireGuard on OpenBSD

Updated: January 26, 2021

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:

pkg_add wireguard-tools
sysctl net.inet.ip.forwarding=1 # set also in /etc/sysctl.conf
sysctl net.inet6.ip6.forwarding=1 # set also in /etc/sysctl.conf
mkdir /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:

[Interface]
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:

inet 10.0.0.1 255.255.255.0 NONE
up

!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf

Add the following to /etc/pf.conf:

pass in on wg0
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:

pkg_add wireguard-tools
mkdir /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:

[Interface]
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:

inet 10.0.0.2 255.255.255.0 NONE
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:

pass out on egress inet from (wg0:network) nat-to (vio0:0)

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:

#!/bin/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:

#!/bin/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:

sh /etc/netstart wg0
pfctl -f /etc/pf.conf

You can check your IP address with either of the following commands:

curl https://ip.ianix.com
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:

wg genpsk > preshared.key

You can then add that key to your server wg0.conf and client wg0.conf, under the [Peer] section like so:

PreSharedKey = CCCC

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 (but disabled by default) in OpenSSH by setting the following in your server's sshd.conf and your client's ssh.conf:

# OpenBSD 6.8 / OpenSSH 8.4 and older
KexAlgorithms sntrup4591761x25519-sha512@tinyssh.org,curve25519-sha256,curve25519-sha256@libssh.org

# OpenBSD 6.8-current / OpenSSH 8.5 and newer
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org

"Powered by WireGuard"