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.
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
umask 077
host=$1
id=$2
if [ -z "$host" -o -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
host=$1
if [ -z "$host" ]; then
echo usage: $0 host
exit 1
fi
qrencode -t ansiutf8 </etc/wireguard/$host.conf
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.