Earlier this week I imported a port for WireGuard into the OpenBSD ports tree. At the moment we have the userland daemon and the tools available. The in-kernel implementation is only available for Linux. At the time of writing there are packages available for -current.
Jason A. Donenfeld (WireGuard author) has worked to support OpenBSD in WireGuard and as such his post on ports@ last year got me interested in WireGuard, since then others have toyed with WireGuard on OpenBSD before and as such I've used Ted's article as a reference. Note however that some of the options mentioned there are no longer valid. Also, I'll be using two OpenBSD peers here.
The setup will be as follows: two OpenBSD peers, of which we'll dub
wg1 the server and
wg2 the client.
The WireGuard service on
wg1 is listening on
Within the VPN subnet the nodes will use the following addresses:
On both nodes we'll use the
tun2 device to tunnel WireGuard traffic.
First we need to install the required packages on both nodes:
pkg_add wireguard-go wireguard-tools
Currently this installs
On the "server" node we'll generate the key pairs for both nodes:
wg genkey | tee server-private.key | wg pubkey > server-public.key wg genkey | tee client-private.key | wg pubkey > client-public.key
In order for the server to forward packets we need the to allow it via
And depending on your exact firewall configuration, you can get away with adding something like the following to
pf.conf of the server node to NAT the traffic from the tunnel:
pass out on egress inet from (tun2:network) nat-to (egress:0)
You may also need to allow incoming traffic to 51820/udp (or whicever port you choose for
Now create the tunnel interface:
ifconfig tun2 up 10.0.0.1 10.0.0.2 netmask 255.255.255.0 rcctl enable wireguard_go rcctl set wireguard_go flags tun2 rcctl start wireguard_go
Finally we'll need the actual configuration in which we declare the private key for the node,
and the public key of its peer.
[Interface] PrivateKey = sEw/H2BjShZovIn5FeOun/sgjMsxl6hzBzEDvqIYrUk= ListenPort = 51820 [Peer] PublicKey = jCmA1Kvq/0/uhi1+uX4OLWIoctqhiyMfJ4DTqbWDWWs= AllowedIPs = 10.0.0.2/32
Obviously you must use the keys you generated previously instead of re-using these :-)
Now apply the configuration to the
tun2 interface as such:
wg setconf tun2 server.conf
You can run
wg to ensure it's applied correctly.
For wg2 the required setup is:
ifconfig tun2 up 10.0.0.2 10.0.0.1 netmask 255.255.255.0 rcctl enable wireguard_go rcctl set wireguard_go flags tun2 rcctl start wireguard_go
client.conf configuration is basically the same as for
wg1, except that we omit the
ListenPort (so the client will use a random port to listen on) and we set the
Endpoint to match the IP/port on which we can reach
[Interface] PrivateKey = oNqEAeMDpnCVVU+lz/G0zEAR3/OlssGg87/Hruy5WVg= [Peer] PublicKey = GhBU6Sqss+s/ZqMuJhVM1RBIDdG5YQ9bK0EwcZNxU2Q= AllowedIPs = 0.0.0.0/0 Endpoint = 100.64.3.2:51820
Apply the configuration:
wg setconf tun2 client.conf
And now the WireGuard tunnel has been established, try pinging the other end of the tunnel to verify and run
# wg interface: tun2 public key: jCmA1Kvq/0/uhi1+uX4OLWIoctqhiyMfJ4DTqbWDWWs= private key: (hidden) listening port: 21373 peer: GhBU6Sqss+s/ZqMuJhVM1RBIDdG5YQ9bK0EwcZNxU2Q= endpoint: 100.64.3.2:51820 allowed ips: 0.0.0.0/0 latest handshake: 22 minutes, 17 seconds ago transfer: 2.54 KiB received, 3.25 KiB sent
What we can now do is to route all traffic over the WireGuard tunnel. For this to work we'll first need to add a more specific route to our server on the client:
route add -priority 2 100.64.3.2 $IP_OF_DEFAULT_GATEWAY
Finally we add the default route to the other endpoint of the tunnel using a lower priority to ensure
we don't try to route traffic to the endpoint itself over the tunnel which is still needed to go to
the address listed at
route add -priority 7 default 10.0.0.1
7 is lower than the default of
8. When routing all traffic via WireGuard you
may need to adjust the
AllowedIPs field for the peer as also traffic originating from its
non-tunnel IP will be routed over the tunnel and the following message will be displayed
by the server:
IPv4 packet with disallowed source address from peer
WireGuard (cl)aims to be easier to setup and faster than OpenVPN and while I haven't been able to verify the latter, the first is certainly true...once you've figured it out. Most documentation out there is for Linux so I had to figure out the wireguard_go service and the tun parameters. But all in all, sure, it's easier. Especially the client configuration on iOS which I didn't cover here because it's essentially
pkg_add libqrencode ; cat client.conf | qrencode -t ansiutf8, scan the code with the WireGuard app and you're good to go. What is particularly neat is that WireGuard on iOS supports Always-on.