WireGuard is a relatively new VPN tunnel implementation that has been written to be as stripped back as possible to keep the codebase as small as possible to help make it easier to audit.
A lot of the instructions for running WireGuard on RaspberryPi OS talk about adding debian testing repos or building the code from scratch, but it looks like recent updates have included the packages needed in the core repositories.
# apt-get install wireguard
I set up UDP port forwarding on my router for port 53145 and got my ISP to route another /64 IPv6 subnet to my line, both of these are forwarded on to the Raspberry Pi that is running that is also running my OpenVPN setup. This is useful as it’s already setup to do NAT for the 10.8.0.0/24 range I’m issuing to OpenVPN clients so having it do itfor the 10.9.0.0/24 range for WireGuard is easy enough.
WireGuard on Linux is implemented as a network device driver so can be configured on the command line with the
ip command e.g.
# ip link add dev wg0 type wireguard # ip address add dev wg0 10.9.0.1/24
Which brings the device up and sets the IP addresses but you still need to add the Private Key and remote address and Public Key which can be done with the
# wg set wg0 listen-port 53145 private-key /path/to/private-key peer ABCDEF... allowed-ips 0.0.0.0/0 endpoint 220.127.116.11:8172
Or more easily it can read from a config file
# wg setconf wg0 myconfig.conf
Or the whole setup and configured with
# wg-quick up /path/to/wg.conf
[Interface] Address = 10.9.0.1/24, 2001:8b0:2c1:xxx::1/64 ListenPort = 53145 PrivateKey = oP3TAHBctNVcnPTxxxxxxxxzNRLSF5CwII4s8gVAXg= #nexus [Peer] PublicKey = 4XcNbctkGy0s73Dvxxxxxxxxx++rs5BAzCGjYmq21UM= AllowedIPs = 10.9.0.2/32, 2001:8b0:2c1:xxx::2/128
The Server config includes:
Addressis the local address on the VPN tunnel, here has both IPv4 and IPv6.
ListenPortis which port to listen for client connections on. WireGuard doesn’t have a assigned port.
PrivateKeyto identify the host.
- There can be multiple
Peers which represent which clients can connect and the
AllowedIPsis the IP addresses for each client.
[Interface] Address = 10.9.0.2/32, 2001:8b0:2c1:4b50::2/128 PrivateKey = UFIJGgtKsor6xxxxxxxxxxxbWeKmw+Bb5ODpyNblEA= DNS = 18.104.22.168 [Peer] PublicKey = jMB2oMu+YTKigGxxxxxxxxxxSYcTde/7HT+QlQoZFm0= AllowedIPs = 0.0.0.0/0, ::0/0 Endpoint = hardill.me.uk:53145
The differences from the Server config are:
DNSentry for the client to use while the tunnel is running.
Endpointwhich is the public address and port to connect to
AllowedIPsare which IPs to route over the tunnel, in this case it’s everything
Both ends of the connection need a
PublicKey and a
PrivateKey so they can mutually authenticate each other. These are generated with the
# wg keygen > privateKey # wg pubkey < privateKey > publicKey
The WireGuard Android app that you can manually add all the details in the config file or it supports reading config files from QR codes. This makes it really easy to setup and removes the chance of getting a typo in the Keys and IP addresses.
You can generate QR codes from the config file as follows:
# qrencode -t png -o nexus.png < nexus.conf # qrencode -t ansiutf8 < nexus.conf
The first generates a PNG file with the QR code, the second prints the code out as ASCII art.
It all looks to be working smoothly. I can see the advantages over OpenVPN being that you don’t need to worry about certificate maintenance and distribution.
I’ll give it a proper work out and see how it holds up running things like SIP connections along with general access to my home network.
As well as running it on the phone, I’ll set up a client config for my laptop to use when out and about. The only issues is that the Gnome Network Manager integration for WireGuard isn’t available in the standard repos for Ubuntu 20.04 so it needs to be started/stopped from the command line.