Wireguard


This is short introduction to Wireguard by Nick Sweeting from his unofficial (but very useful) Wireguard documentation.

WireGuard is a WIP open-source VPN solution written in C by Jason Donenfeld and others, aiming to fix many of the problems that have plagued other modern server-to-server VPN offerings like IPSec/IKEv2, OpenVPN, or L2TP. It shares some similarities with other modern VPN offerings like Tinc and MeshBird, namely good cipher suites and minimal config.

And these are my notes on a simple Wireguard installation.

This install connects a VPS on the public internet to a home server using Wireguard.
While this is an extremely simple configuration it is at the same time unusual in that the home server is running Arch Linux and is also behind two NAT’ing routers (WIFi internet connection …).

The result is secure VPN between the two servers which allows bi-directional SSH, i.e. I can SSH to home from internet bypassing two NAT’ing routers along the way.

Server1
Cloud server from OVH, available on public IP 217.x.x.x, running Ubuntu 19.04.

Home server
Arch Linux, private LAN 192,168.x.x, sits behind 2 NAT’ing routers.

Installation

Ubuntu

Straightforward.
Add the Wireguard repository and then install (no need to update first).

# add-apt-repository ppa:wireguard/wireguard
 WireGuard is a novel VPN that runs inside the Linux Kernel. This is the Ubuntu packaging for WireGuard. More info may be found at its website, listed below.

More info: https://www.wireguard.com/
Packages: wireguard wireguard-tools wireguard-dkms

Install with: $ apt install wireguard

For help, please contact <email address hidden>
 More info: https://launchpad.net/~wireguard/+archive/ubuntu/wireguard
Press [ENTER] to continue or Ctrl-c to cancel adding it.

Get:1 http://security.ubuntu.com/ubuntu cosmic-security InRelease [88.7 kB]
Get:2 http://ppa.launchpad.net/wireguard/wireguard/ubuntu cosmic InRelease [15.9 kB]
Hit:3 http://nova.clouds.archive.ubuntu.com/ubuntu cosmic InRelease   
Get:4 http://nova.clouds.archive.ubuntu.com/ubuntu cosmic-updates InRelease [88.7 kB]
Get:5 http://nova.clouds.archive.ubuntu.com/ubuntu cosmic-backports InRelease [74.6 kB]
Get:6 http://ppa.launchpad.net/wireguard/wireguard/ubuntu cosmic/main amd64 Packages [940 B]
Get:7 http://ppa.launchpad.net/wireguard/wireguard/ubuntu cosmic/main Translation-en [800 B]         
Get:8 http://nova.clouds.archive.ubuntu.com/ubuntu cosmic-updates/main amd64 Packages [374 kB]
Get:9 http://nova.clouds.archive.ubuntu.com/ubuntu cosmic-updates/universe amd64 Packages [677 kB]
Fetched 1321 kB in 1s (1251 kB/s)                                                   
Reading package lists... Done

# apt install wireguard
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  binutils binutils-common binutils-x86-64-linux-gnu build-essential cpp cpp-8 dkms dpkg-dev fakeroot g++ g++-8 gcc gcc-8 gcc-8-base libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan5
  libatomic1 libbinutils libc-dev-bin libc6-dev libcc1-0 libdpkg-perl libfakeroot libfile-fcntllock-perl libgcc-8-dev libgcc1 libgomp1 libisl19 libitm1 liblsan0 libmpc3 libmpx2 libquadmath0 libstdc++-8-dev libstdc++6
  libtsan0 libubsan1 linux-libc-dev make manpages-dev wireguard-dkms wireguard-tools
Suggested packages:
  binutils-doc cpp-doc gcc-8-locales menu debian-keyring g++-multilib g++-8-multilib gcc-8-doc libstdc++6-8-dbg gcc-multilib autoconf automake libtool flex bison gdb gcc-doc gcc-8-multilib libgcc1-dbg libgomp1-dbg
  libitm1-dbg libatomic1-dbg libasan5-dbg liblsan0-dbg libtsan0-dbg libubsan1-dbg libmpx2-dbg libquadmath0-dbg glibc-doc bzr libstdc++-8-doc make-doc
The following NEW packages will be installed:
  binutils binutils-common binutils-x86-64-linux-gnu build-essential cpp cpp-8 dkms dpkg-dev fakeroot g++ g++-8 gcc gcc-8 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan5 libatomic1
  libbinutils libc-dev-bin libc6-dev libcc1-0 libdpkg-perl libfakeroot libfile-fcntllock-perl libgcc-8-dev libgomp1 libisl19 libitm1 liblsan0 libmpc3 libmpx2 libquadmath0 libstdc++-8-dev libtsan0 libubsan1
  linux-libc-dev make manpages-dev wireguard wireguard-dkms wireguard-tools
The following packages will be upgraded:
  gcc-8-base libgcc1 libstdc++6
3 upgraded, 42 newly installed, 0 to remove and 26 not upgraded.
Need to get 45.4 MB of archives.
After this operation, 177 MB of additional disk space will be used.
Do you want to continue? [Y/n] y

Arch Linux

Installation of Wireguard module requires Linux headers to compile the module.
Headers have to match the kernel version so get that first.

# uname -a
Linux vh3 4.19.45-1-MANJARO #1 SMP PREEMPT Wed May 22 17:16:41 UTC 2019 x86_64 GNU/Linux

Then install the matching Linux headers, e.g. for kernel version 4.19.45 install linux419-headers

# pacman -S linux419-headers

Now install the Wireguard tools and module.

# pacman -S wireguard-tools
...
# pacman -S wireguard-dkms
...

Raspberry Pi

Based on these notes.
Install Wireguard on Pi - kernel headers first.

root@pic:~# apt-get install raspberrypi-kernel-headers
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  raspberrypi-kernel-headers
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 16.7 MB of archives.
After this operation, 108 MB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian stretch/main armhf raspberrypi-kernel-headers armhf 1.20190517-1 [16.7 MB]
Fetched 16.7 MB in 1s (14.1 MB/s)                   
...

Then dirmngr, which may already be installed

root@pic:~# apt-get install dirmngr
Reading package lists... Done
Building dependency tree       
Reading state information... Done
dirmngr is already the newest version (2.1.18-8~deb9u4).
dirmngr set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Add unstable repo, update and install

root@pic:~# apt-key adv --keyserver   keyserver.ubuntu.com --recv-keys 8B48AD6246925553
Executing: /tmp/apt-key-gpghome.pXCV7n61iy/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553
gpg: key 8B48AD6246925553: 30 signatures not checked due to missing keys
gpg: key 8B48AD6246925553: public key "Debian Archive Automatic Signing Key (7.0/wheezy) <ftpmaster@debian.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1
root@pic:~# printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' | tee --append /etc/apt/preferences.d/limit-unstable
Package: *
Pin: release a=unstable
Pin-Priority: 150
root@pic:~# apt-get update
Hit:1 http://archive.raspberrypi.org/debian stretch InRelease
...
## >> You may see a warning about missing public key - it will not prevent installation

root@pic:~# apt-get install wireguard
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  dkms wireguard-dkms wireguard-tools
After this operation, 2,404 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
WARNING: The following packages cannot be authenticated!
  wireguard-dkms wireguard-tools wireguard
Install these packages without verification? [y/N] y
...
wireguard:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.19.42-v7+/kernel/net/

depmod....

DKMS: install completed.
Setting up wireguard (0.0.20190406-1) ...

All servers

Generate private and public keys on all servers.
The keys and configuration file can be in any location and use names of your choice.

# cd /etc/wireguard
# ## Protect files and directories
# umask 077
# wg genkey > wg.key
# wg pubkey < wg.key > wg.key.pub

Create configuration files, these will be different for each server.
The configuration uses a simple INI style format.
Lines starting “#” are comments.
[Interface] section defines the local network interface.
Address for the Interface, defines the range of IP’s accepted. All IP’s shoul be in CIDR format.
DNS is the DNS servers (comma separated) to be used on this interface.
SaveConfig will automatically add new peers to the configuration.
Careful here - if you change config while Wireguard is running your changes will be lost if a new peer is added by Wireguard.
[Peer] section defines properties of peers that are allowed to connect.
EndPoint is the FQDN of the server. This must be resolvable using DNS. It should not be used in Peer configuration where the peer is behind NAT routers.
AllowsdIPs IP addresses allowed to/from the peer.
PrivateKey and PublicKey are the keys generated on each server.
There are projects underway to handle Wireguard key distribution but for small networks copy/paste works.

Server1 - Ubuntu, on public internet

[Interface]
# Name = server1.bespoke-it.solutions
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <Your server PRIVATE key>
DNS = 1.1.1.1

[Peer]
# Name = home-server.local.bespoke-it.solutions
PublicKey = <Your server PUBLIC key>
# Allow only this IP from this peer
AllowedIPs = 10.0.0.3/32

Server2 - Arch Linux home server

[Interface]
# Name = home-server.local.bespoke-it.solutions
Address = 10.0.0.3/32
ListenPort = 51820
PrivateKey = <Your server PRIVATE key>
DNS = 1.1.1.1

[Peer]
# Name = bits01.bespoke-it.solutions
Endpoint = bits01.bespoke-it.solutions:51820
PublicKey = <Your server PUBLIC key>
# routes traffic to itself and entire subnet of peers
AllowedIPs = 10.0.0.1/24
PersistentKeepalive = 25

SSH between servers on Wireguard LAN (10.0.0.x)

Simple answer is to change SSH server to listen on specific addresses using multiple ListenAddress in sshd_config.

Trouble shooting

resolvconf missing during wg-quick up

This may happen on Ubuntu which does not include resolvconf by default.

[#] resolvconf -a wg0 -m 0 -x
/usr/bin/wg-quick: line 31: resolvconf: command not found

Installing openresolv worked for me.

# apt install openresolv

Try installing module by running modprobe.

$ ip link add dev wg0 type wireguard
RTNETLINK answers: Operation not supported
Unable to access interface: Protocol not supported

# modprobe wireguard

It is also possible that the installation of Wireguard kernel module failed, possibly because of missing headers.
Try re-installing it along with the Linux headers, e.g.

# apt reinstall wireguard-dkms linux-headers-$(uname -r)

Useful refs:
Arch Linux Wireguard doc
Useful doc on setting up VPN using Wireguard
Setting up Wireguard - site to site via router - this is a good one

Comment on this article using form below. Requires email login only for authentication. HTML forbidden, Markdown only.