OpenBSD 6.8 includes WireGuard . WireGuard allows one to build VPNs. For a long time, OpenBSD has had excellent IPsec support. Unfortunately the same cannot be said of IPSec support on other platforms, and inevitably a VPN relies upon good software for all parties to VPN. WireGuard is pretty good on all platforms, making it very attractive. By pretty good, I mean: straightforward to use and well-engineered (fast, secure, code quality, crypto design, etc). Naturally though, just how well-engineered WireGuard is will be seen over the coming decades, so this is the hardest attribute to assess correctly.
Here I will describe my setup under OpenBSD: it is really just a summary of information already available in wg(4) , ifconfig(8) , hostname.if(5) , as well as the documentation for the wireguard-tools package. These instructions have been tested on all versions of OpenBSD from 6.8 to 7.1. They will probably work on future versions–but perhaps stuff will change.
We will use 10.1.1.0/16
and 2001:0db8:85a3:1::/80
as the VPN address ranges and the VPN server
has a DNS name of vpn.ioctl.uk
and will run on port 51820
; replaces these appropriately.
First up, let’s create the wg(4) interface wg0. Generate a fresh private key:
$ openssl rand -base64 32
Then create the hostname.if(5) file:
$ doas tee /etc/hostname.wg0 <<EOF
destroy
create
wgport 51820 wgkey INSERT_HERE
inet 10.1.1.1 255.255.255.0
inet6 2001:0db8:84a3:1::1 80
EOF
Save the public key:
$ doas cat /etc/hostname.wg0 | awk '$3 ~ /wgkey/ {print $4}' | \
wg pubkey | doas tee /etc/wireguard/vpn.pub
The wg
command comes from the wireguard-tools
package, available from
ports: pkg_add wireguard-tools
if you do not have it already.
I like to make it easy to add another host, so I add the following script in /etc/wireguard/add
:
#!/bin/sh
set -e
umask 077
host=$1
id=$2
if [ -z "$host" ] || [ -z "$id" ]; then
echo usage: $0 host id
exit 1
fi
if [ "$id" = 1 ]; then
echo bad id
exit 1
fi
key=/etc/wireguard/"$host".key
pub=/etc/wireguard/"$host".pub
psk=/etc/wireguard/"$host".psk
ip=10.1.1.$id
ip6=2001:0db8:84a3:1::$id
if [ -e "$key" ]; then
echo "$key" already exists
exit 1
fi
wg genkey | tee "$key" | wg pubkey >"$pub"
wg genkey >"$psk"
chmod 400 "$key" "$pub" "$psk"
cat >>/etc/hostname.wg0 <<EOF
# $host
wgpeer $(cat "$pub") wgpsk $(cat "$psk") wgaip $ip/32 wgaip $ip6/128
EOF
cat >/etc/wireguard/"$host".conf <<EOF
[Interface]
Address = $ip/32, $ip6/128
PrivateKey = $(cat "$key")
DNS = 10.1.1.1
[Peer]
PublicKey = $(cat /etc/wireguard/vpn.pub)
PresharedKey = $(cat "$psk")
AllowedIPs = 0.0.0.0/0, ::0/0
Endpoint = vpn.ioctl.uk:51820
PersistentKeepAlive = 15
EOF
And finally, another script for generating QR codes on the command line of the generated configurations.
I put this in /etc/wireguard/qr
:
#!/bin/sh
set -e
host=$1
if [ -z "$host" ]; then
echo usage: $0 host
exit 1
fi
qrencode -t ansiutf8 </etc/wireguard/$host.conf
This script makes use of the qrencode
binary from the OpenBSD package named libqrencode
(install with
pkg_add libqrencode
).
Make the scripts executable:
$ chmod +x /etc/wireguard/{qr,add}
Now enrolling a new host is very straightforward. Pick an id for the host between 2
and 255
.
Suppose we wish to add a new host called alice
as id 2
and another called bob
as id 3
:
$ doas /etc/wireguard/add alice 2
$ doas /etc/wireguard/add bob 3
$ doas sh /etc/netstart wg0
Client configuration is very simple.
- Under Linux, for example, copy
/etc/wireguard/alice.conf
to/etc/wireguard/wg0.conf
, then run on the Linux machine:
$ sudo wg-quick up wg0
- On devices with a camera, use the QR code. On the VPN server run and scan the output:
$ doas /etc/wireguard/qr alice
Note, once a host is set up you can remove the corresponding .key
and .conf
files in /etc/wireguard
on the VPN server.
If you run into problems, on the VPN server run:
$ doas ifconfig wg0 debug
then check the output of dmesg(8) to see messages. The end of wg(4) has list of good diagnostics. To switch off debugging:
$ doas ifconfig wg0 -debug
Thanks
Nate Houghton for spotting a typo in the add
script and suggesting variable usage.