OpenBSD as a Wireguard Client

· 4min · Dan F.

Since it has been a couple weeks since first starting to work with wireguard on OpenBSD, I figured it was about time to figure out how to get my OpenBSD desktop to act as a wireguard client. Who knows, perhaps this will one day allow me to drop my PIA VPN and shift exclusively to running my own personal VPN's.

Well, I am no networking pro. I know there is a wg-quick script out there, but the couple of times that I tried it out on OpenBSD, it failed. I figured that there shouldn't be that much to a wireguard tunnel, all I have to do is figure out how to establish the tunnel and force data out the tun device.

Turns out that it was a little more complicated than I had expected. The first speed bump was that the configs that I had been using for my phone, won't work directly on OpenBSD.

Here is an example of an "original" client config from one of my earlier posts:

[Interface]
Address = 10.10.0.8/24
PrivateKey = <removed>
DNS = 10.10.0.1

[Peer]
PublicKey = <removed>
Endpoint = 1.2.3.4:5555
AllowedIPs = 0.0.0.0/0

After running wireguard-go -f tun3, I tried setting the config to tun3 with wg setconf tun3 /path/to/config.conf, but it failed with multiple errors, saying settings were invalid. Eventually, I found that I had to only use the bare minimum to configure the tun device:

[Interface]
#Address = 10.10.0.8/24
PrivateKey = <removed>
#DNS = 10.10.0.1

[Peer]
PublicKey = <removed>
Endpoint = 1.2.3.4:5555
AllowedIPs = 0.0.0.0/0

I decided to not remove the entries, but simply comment them out, as I will need them later. Now this was actually my second step, as I discovered later. Once I figured out the proper commands, I found that my original sequence of commands were out of order. I will give a set of commands at the end in the proper order.

The next hurdle involved configuring the tun device itself. I am using tun3 in this example, and configuring it is very simple:

ifconfig tun3 mtu 1420
ifconfig tun3 10.10.0.8 10.10.0.1 netmask 255.255.255.255

Just for clarification; 10.10.0.8 was used as this was the IP commented out in the above config. This is the IP that the wireguard server should be expecting for your public key. 10.10.0.1 is used, as this is the gateway on the wireguard server, and also happens to have a running unbound server in my case. The gateway and IP here should be specific to your setting on the server.

Almost done. The last part was the trickiest for me to figure out. We need to set the default route to eventually point to 10.10.0.1. However, without first establishing a static route to the wireguard server out your client's original gateway, we will create a routing loop, as the packets will have no way of knowing how to reach the wireguard server's IP.

To prevent this from occurring, we will have to create a static route with a higher priority than the default route to 10.10.0.1.

route add -priority 2 1.2.3.4 <current default gateway>
route change -priority 7 default 10.10.0.1

Now to string all these commands together in the correct order:

ifconfig tun3 create
ifconfig tun3 mtu 1420
ifconfig tun3 10.10.0.8 10.10.0.1 netmask 255.255.255.255
wireguard-go -f tun3 &
wg setconf tun3 /path/to/config.conf
route add -priority 2 1.2.3.4 <current default gateway>
route add -priority 7 default 10.10.0.1

After this you should have a functioning tunnel to your wireguard server. One last step would be to set your resolv.conf to point to 10.10.0.1, if you have an unbound service running on your wireguard server. If you have your dns pointing to a local DNS server, such as 192.168.0.1, changing your DNS is unnecessary, as this DNS server will remain accessible.

I hope this post will save someone else from bashing their head against the wall... That networking bit took me a good minute to figure out. Like I had mentioned earlier, I am no networking guru. Now to go cancel my PIA service.

Has been tested on OpenBSD 6.4