WireGuard Server: Raspbian Buster
In this tutorial, we setup a WireGuard server on a Raspberry Pi running Raspbian Buster (which is 99% Debian Buster).
At the end of this tutorial, the device will have a virtual network interface wg0
living on private network 10.0.2.0/24
.
The device will be ready to add WireGuard clients.
Platform
In this example, I’m using a Raspberry Pi 2 Model B v1.1. This will not work on Raspberry Pi versions prior to 2.
- Follow the installation instructions
- Set a non-default password for user
pi
withpasswd
orsudo raspi-config
- Update the base install with
sudo apt update && sudo apt upgrade
Configure the Local Area Network
Ensure that UDP port 51820
on the Raspberry Pi is available to the public internet via a stable IP address.
In this example, the device is connected to a local area network behind a WiFi/NAT router.
The NAT router has public, static IP address 35.36.37.38
,
and acts as default gateway for local area network 192.168.10.0/24
as 192.168.10.1
.
The NAT router is configured to always assign 192.168.10.100
to the Raspberry Pi device via DHCP reservation.
TODO take new screenshots
The NAT router is configured to forward incoming network traffic to UDP port 51820
to the Raspberry Pi device.
TODO take new screenshots
Shell
For the the rest of this tutorial, we’ll interact with Raspbian via command line interface. Open a terminal as an unprivileged user via the console, the Terminal GUI app, or SSH.
Trust Debian
By default, Raspbian doesn’t trust the Debian package repository. Add Debian’s public keys to the trusted set of keys.
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 04EE7237B7D453EC 648ACFD622F3D138
Executing: /tmp/apt-key-gpghome.p9XKvbbATY/gpg.1.sh --keyserver hkp://pool.sks-keyservers.net:80 --recv-keys 04EE7237B7D453EC 648ACFD622F3D138
gpg: key DC30D7C23CBBABEE: public key "Debian Archive Automatic Signing Key (10/buster) <ftpmaster@debian.org>" imported
gpg: key E0B11894F66AEC98: public key "Debian Archive Automatic Signing Key (9/stretch) <ftpmaster@debian.org>" imported
gpg: Total number processed: 2
gpg: imported: 2
Setup WireGuard
Install WireGuard
To install the most recent version of WireGuard, we’ll need packages from the Debian unstable release. Add the Debian unstable release, and pin the Debian unstable priority behind Raspbian stable. This allows us to install packages that are not available in Debian stable, while keeping the “stable” versions of everything else.
$ sudo sh -c "echo 'deb http://deb.debian.org/debian/ unstable main' >> /etc/apt/sources.list.d/unstable.list"
$ sudo sh -c "printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' >> /etc/apt/preferences.d/limit-unstable"
Update package information from both stable and unstable package repositories.
$ sudo apt update
Get:1 http://deb.debian.org/debian unstable InRelease [142 kB]
Hit:2 http://archive.raspberrypi.org/debian buster InRelease
Hit:3 http://raspbian.raspberrypi.org/raspbian buster InRelease
Get:4 http://deb.debian.org/debian unstable/main armhf Packages [7,977 kB]
Get:5 http://deb.debian.org/debian unstable/main Translation-en [6,192 kB]
Fetched 14.3 MB in 22s (655 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
Install the WireGuard packages.
After this step, man wg
and man wg-quick
will work and the wg
command gets bash completion.
$ sudo apt install wireguard --assume-yes
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
dkms raspberrypi-kernel-headers wireguard-dkms wireguard-tools
Suggested packages:
python3-apport menu
The following NEW packages will be installed:
dkms raspberrypi-kernel-headers wireguard wireguard-dkms wireguard-tools
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
...
DKMS: install completed.
Module build for kernel 4.19.75-v8+ was skipped since the
kernel headers for this kernel does not seem to be installed.
Setting up wireguard-tools (0.0.20191219-1) ...
Setting up wireguard (0.0.20191219-1) ...
Processing triggers for man-db (2.8.5-2) ...
Create Keys
In every client/server relationship, each peer has its own private and public keys. Create private and public keys for the WireGuard service. Protect the private key with a file mode creation mask.
$ (umask 077 && wg genkey > wg-private.key)
$ wg pubkey < wg-private.key > wg-public.key
Print the private key, we’ll need it soon.
$ cat wg-private.key
qPF9uU7qsCbw3uKR1t2Q0gfr2HasTKZGPkCHz2AszUs=
Create the WireGuard Network Device
Create the WireGuard service config file at /etc/wireguard/wg0.conf
.
(Use a command like sudo nano /etc/wireguard/wg0.conf
.)
# define the WireGuard service
[Interface]
# contents of file wg-private.key that was recently created
PrivateKey = qPF9uU7qsCbw3uKR1t2Q0gfr2HasTKZGPkCHz2AszUs=
# UDP service port; 51820 is a common choice for WireGuard
ListenPort = 51820
Create the WireGuard network device at /etc/network/interfaces.d/wg0
.
(Use a command like sudo nano /etc/network/interfaces.d/wg0
.)
# indicate that wg0 should be created when the system boots, and on ifup -a
auto wg0
# describe wg0 as an IPv4 interface with static address
iface wg0 inet static
# static IP address
address 10.0.2.1/24
# before ifup, create the device with this ip link command
pre-up ip link add $IFACE type wireguard
# before ifup, set the WireGuard config from earlier
pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf
# after ifdown, destroy the wg0 interface
post-down ip link del $IFACE
Start WireGuard.
$ sudo ifup wg0
If this fails, then install package linux-headers-VERSION
. It seems that the
Debian WireGuard packages don’t declare that dependency, or it’s just broken in GCP.
$ sudo ifup wg0
RTNETLINK answers: Operation not supported
ifup: failed to bring up wg0
$ sudo apt install linux-headers-$(uname -r)
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
...
Fetched 556 kB in 0s (7381 kB/s)
Selecting previously unselected package linux-headers-4.19.0-6-cloud-amd64.
(Reading database ... 60668 files and directories currently installed.)
Preparing to unpack .../linux-headers-4.19.0-6-cloud-amd64_4.19.67-2+deb10u2_amd64.deb ...
Unpacking linux-headers-4.19.0-6-cloud-amd64 (4.19.67-2+deb10u2) ...
Setting up linux-headers-4.19.0-6-cloud-amd64 (4.19.67-2+deb10u2) ...
$ sudo ifup wg0
At any time, verify that the WireGuard configuration for wg0
is what you expect:
$ sudo wg show wg0
interface: wg0
public key: 2efuG9OYmMPQpbkJ8CVxGlvQflY6p1u+o4wjcgGII0A=
private key: (hidden)
listening port: 51820
At any time, verify that the wg0
network interface exists.
$ ip address show dev wg0
7: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.0.2.1/24 brd 10.0.2.255 scope global wg0
valid_lft forever preferred_lft forever