François' Blog

OpenBSD & WireGuard

Published on 2023-11-20

Configuring WireGuard is not that difficult on OpenBSD, but what misses is a "complete" walkthrough. Also I am trying to fix vpn-daemon to work on OpenBSD. No idea what that would require, but if we first need to get WireGuard working on OpenBSD.

View of the Oder, near Mescherin, Germany

The following resources are of great help:

All these resources allow for creating a /etc/hostname.wg0 file that contains the WireGuard configuration which is all you need to get going. The examples below should be read together with the above manual pages in order to make sure you undnerstand what is going on. We'll only configure the OpenBSD node to allow some WireGuard peers to access services on this OpenBSD node, not as a router.

WireGuard requires a private key that you can generate and will become the value of wgkey:

$ openssl rand -base64 32
bFfdy1LVMW4+fMNYpdBYYI+FV6cHGwh8Nji0L4PcvCE=

Next, you can choose IP addresses for your WireGuard interface and configure it in /etc/hostname.wg0, e.g.:

wgkey bFfdy1LVMW4+fMNYpdBYYI+FV6cHGwh8Nji0L4PcvCE=
mtu 1392
wgport 443
inet 10.9.9.1 255.255.255.0 NONE
inet6 fd99:9:9:9::1 64
up

We choose UDP port 443, and set the MTU to 1392. We make a study of figuring out what is the best MTU for WireGuard interfaces here. I am sure it is still not perfect, but at least it seems to work in most cases!

Now you can run "netstart" to configure the interface:

$ doas sh /etc/netstart
WARNING: /etc/hostname.wg0 is insecure, fixing permissions.

Now your WireGuard interface should be up:

$ doas ifconfig wg0
wg0: flags=80c3<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1392
	index 5 priority 0 llprio 3
	wgport 443
	wgpubkey QQ+7AB8vhoFw81dh+b8mTAlozhXpyv4YUVU8eS8zUmk=
	groups: wg
	inet 10.9.9.1 netmask 0xffffff00 broadcast 10.9.9.255
	inet6 fd99:9:9:9::1 prefixlen 64

Using doas, or running the command as root, is necessary in order to be able to see the wgpubkey which is the public key the peers need in order to verify key used by this OpenBSD machine.

Talking about peers, we'll add a peer to /etc/hostname.wg0 now, you can do that with the following line:

wgpeer ZpglLHGb3gtAamYgqPhULZXXl42BiDQumUdBcUgPDTs= wgaip 10.9.9.2/32 wgaip fd99:9:9:9::2/128

The first field after the wgpeer is the public key of the WireGuard peer. The peer that has the private key belonging to the shown public key can talk to the OpenBSD node using the IP(s) specified. You'll need to re-run "netstart" to add the peer:

$ doas sh /etc/netstart

You can see the configured peer by running ifconfig wg0 as root:

$ doas ifconfig wg0
wg0: flags=80c3<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1392
	index 5 priority 0 llprio 3
	wgport 443
	wgpubkey QQ+7AB8vhoFw81dh+b8mTAlozhXpyv4YUVU8eS8zUmk=
	wgpeer ZpglLHGb3gtAamYgqPhULZXXl42BiDQumUdBcUgPDTs=
		tx: 0, rx: 0
		wgaip fd99:9:9:9::2/128
		wgaip 10.9.9.2/32
	groups: wg
	inet6 fd99:9:9:9::1 prefixlen 64
	inet 10.9.9.1 netmask 0xffffff00 broadcast 10.9.9.255

A configuration file for that peer in the wg-quick(8) format for e.g. Linux would look like shown below.

First we generate a key for that peer:

$ wg genkey | tee private.key | wg pubkey
ZpglLHGb3gtAamYgqPhULZXXl42BiDQumUdBcUgPDTs=

The private key will be placed in private.key, which is what we'll use below in the [Interface] section:

[Interface]
MTU = 1392
PrivateKey = OPDc49AzQ4RP7ErePeZ4BLqWcOqibhveyW/IBf7RE0k=
Address = 10.9.9.2/24,fd99:9:9:9::2/64

[Peer]
PublicKey = QQ+7AB8vhoFw81dh+b8mTAlozhXpyv4YUVU8eS8zUmk=
AllowedIPs = 10.9.9.0/24,fd99:9:9:9::/64
Endpoint = bsd.example.org:443

The Endpoint field MUST point to the hostname, or IP of the OpenBSD node. This is everything needed to make the VPN work.

History