3 min read

Setting up Wireguard on an OpenBSD 7.4 firewall device

It took me a little while after I set up my firewall device to set up Wireguard as a VPN. It’s probably something I should have done right away — the benefits of being able to log in from home (and block ads) while on the road is really nice.

The Wireguard logo

Wireguard needs a publicly available IP or domain name. I used DuckDNS. I posted about that a while back so I won’t do it again here, but you’ll need to do that first.

Wireguard is in the kernel in 7.4. Prior releases required you to pkg_add wireguard_tools, but these days you don’t need to.

The way Wireguard works is that you generate public and private keys. Each device gets its own private key, and you share the public keys. Wireguard has tools to do that. On the OpenBSD firewall side:

# mkdir /etc/wireguard
# chmod 700 /etc/wireguard
# wg genkey > /etc/wireguard/private.key
# chmod 600 /etc/wireguard/private.key
# wg pubkey < private.key > public.key

Next, you need to generate private and public keys on each of your clients. Then set up /etc/wireguard/wg0.conf to contain the firewall’s private key and also the public keys of the client. I decided to do this on a completely different network — 172.16. I assigned individual IP addresses for each device. It’s a little more management headache, but makes it easy to delete something if I lose a device. The /etc/wireguard/wg0.conf looks like this:

[Interface]
PrivateKey = the private key from /etc/wireguard/private.key
ListenPort = 51820

[Peer]
# My first peer - a laptop
PublicKey = the public key from the laptop
AllowedIPs = 172.16.0.2

[Peer]
# My second peer - an Android device running Wireguard from F-Droid
PublicKey = the public key from the device
AllowedIPs = 172.16.0.3

# ... etc...

Obviously, on each device you have to do the reverse: specify the private key generated on device, and put the firewall’s public key in as the peer. Next, you need an /etc/hostname.wg0 to bring the network up:

inet 172.16.0.1 255.255.255.0 NONE up
!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf

Before you can go further, you need to unblock the Wireguard interface in /etc/pf.conf:

(after the lan_if macro)
vpn_if="wg0"
vpn_port="51820"

(at the end after the NAT rules)
#---------------------------------#
# WireGuard
#---------------------------------#
pass in on $vpn_if
pass in inet proto udp from any to any port $vpn_port
pass out on egress inet from ($vpn_if:network) nat-to ($ext_if:0)

From there, you can restart pf and reload the new rules and sh /etc/netstart wg0.

This post is part of a series on setting up an OpenBSD 7.4 firewall device.