Wireguard server on OpenBSD

This is a succinct instruction on creating a WireGuard VPN host on OpenBSD. We will create a subnet (192.168.99.0/24) on a tunnel interface (tun0) in which the host and all the WireGuard clients will have an IP-adress. The host will route all client traffic over it’s primary network interface using masquerade NAT.

Prerequisites

Install the necessary WireGuard packages. This instruction is written for OpenBSD 6.7 and uses the userland WireGuard implementation. OpenBSD 6.8 will feature a kernel implementation.

pkg_add wireguard-go wireguard-tools

Enable IP-forwarding.

echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
sysctl -p

Configure tunnel interface

Create /etc/hostname.tun0 and configure addressing and routing

inet 192.168.99.1 255.255.255.0 192.168.99.255 description "WireGuard"
!/sbin/route add -inet 192.168.99.0/24 192.168.99.1

Restart the network

sh /etc/netstart && sh /etc/netstart

Configure pf

Edit the pf configuration in /etc/pf.conf

Skip pf processing on the tunnel interface. This line likely already has the loopback interface lo0. It should look look this:

set skip on {lo tun0}

Masquerade all traffic from the WireGuard subnet behind the egress interface’s address:

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

Reload the pf configuration to activate the changes:

pfctl -f /etc/pf.conf

Configure and activate WireGuard

Create the WireGuard config directory and set permissions

mkdir /etc/wireguard
chmod 0700 /etc/wireguard

Create the private and public keys

cd /etc/wireguard
umask 077
wg genkey > /etc/wireguard/privkey
wg pubkey < /etc/wireguard/privkey > /etc/wireguard/publickey

Make sure to create keys on your clients too! You can use the following commands:

wg genkey > /etc/wireguard/privkey
wg pubkey < /etc/wireguard/privkey > /etc/wireguard/publickey
wg genpsk > /etc/wireguard/psk

Create the WireGuard configuration file: /etc/wireguard/tun0.conf. This will make WireGuard listen on UDP port 51820 and have on peer which is allowed IP-address 192.168.99.2 on the WireGuard subnet.

[Interface]
PrivateKey = <paste content of /etc/wireguard/privkey>
ListenPort = 51820

[Peer]
PublicKey = <paste your peer's public key here>
PresharedKey = <paste your peer's PSK here>
AllowedIPs = 192.168.99.2/32

Set the WireGuard userland program to start on boot and tell it to use tun0 as tunnel adapter.

rcctl enable wireguard_go
rcctl set wireguard_go flags tun0
rcctl start wireguard_go

Load the wireguard configuration file and make sure it loads on reboot

wg setconf tun0 /etc/wireguard/tun0.conf
echo '/usr/local/bin/wg setconf tun0 /etc/wireguard/tun0.conf' >> /etc/rc.local

Verification

Connect a client and run the command “wg” to see the status of your WireGuard server and connected clients.

interface: tun0
  public key: (hidden)
  private key: (hidden)
  listening port: 51820

peer: (peer's public key)
  preshared key: (hidden)
  endpoint: (peer's ip-address):(peer's source port)
  allowed ips: 192.168.99.2/32
  latest handshake: 2 days, 2 hours, 26 minutes, 13 seconds ago
  transfer: 307.50 KiB received, 876.06 KiB sent