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-tools

Enable IP-forwarding.

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

Configure tunnel interface

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

inet 192.168.99.1 255.255.255.0 192.168.99.255 description "WireGuard"
!/usr/local/bin/wg setconf wg0 /etc/wireguard/server.conf
!/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 wireguard interface. This line likely already has the loopback interface lo0. It should look look this:

set skip on {lo wg0}

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

pass out on egress inet from (wg0: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/server.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

Load the wireguard configuration file

wg setconf wg00 /etc/wireguard/server.conf

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