The Raspberry Pi Kernel has now been updated beyond Linux 5.6, meaning Wireguard has been included in the Kernel and the below shouldn’t be necessary on a recent version of Raspberry Pi OS.

This guide is mostly for my own reference after an entire day of trying to figure out how to get this working. I’ve just posted it here in case anyone else might find it useful.

I first needed a 64 bit kernel for a docker container, and then a couple of months later when trying to use WireGuard realised it wasn’t going to be easy without kernel headers and a 32-bit userland. After piecing together varying sources of information, the below should work at the time of posting on a Raspberry Pi 3 B+ running the latest Raspbian, and with arm_64bit=1 in /boot/config.txt.

The idea here is -

  • Download a 64 bit base image
  • mount & chroot in
  • Build against the 64 bit kernel
  • Put the module in the correct folder
  • Load the module

Create a folder somewhere, I called it ubuntu
mkdir ubuntu; cd ubuntu

Download the latest ubuntu base image
wget http://cdimage.ubuntu.com/ubuntu-base/daily/current/groovy-base-arm64.tar.gz

Unpack it
tar -xzf groovy-base-arm64.tar.gz

Download the kernel source code for your Raspberry Pi, can be checked with uname -a and then compared against the date that has the same kernel number by checking the Makefile in the root of the repository

wget https://github.com/raspberrypi/linux/releases/tag/raspberrypi-kernel_1.20200512-2

In my case, 4.19.118 is in the raspberrypi-kernel_1.20200512-2 release. Not sure why since the Raspbian image has 20200527 on it, but double check after downloading by using

unzip -p raspberrypi-kernel_1.20200512-2.zip linux-raspberrypi-kernel_1.20200512-2/Makefile | head -6

If that seems fine, unzip this too

unzip raspberrypi-kernel_1.20200512-2.zip

Clone the source for WireGuard

git clone https://git.zx2c4.com/wireguard-linux-compat

Sort out the appropriate mounts & configure networking

cat /etc/resolv.conf > etc/resolv.conf
mount -B /dev dev 
mount -B /proc proc 
mount -B /sys sys
mount -t tmpfs tmp tmp

chroot in

sudo chroot .

Run apt update

apt update

Install the necessary packages (not sure if all of these are needed but it worked this way!)

apt-get install libelf-dev build-essential pkg-config locales-all bc bison flex libssl-dev kmod

Configure the kernel

cd linux-raspberrypi-kernel_1.20200512-2
make bcm2711_defconfig 
make prepare 
make scripts

Compile the kernel module

cd ../wireguard-linux-compat/src/
make -C /linux-raspberrypi-kernel_1.20200512-2 M=$PWD modules

Exit the chroot and copy over the files

exit
sudo cp wireguard-linux-compat/src/wireguard.ko /lib/modules/4.19.118-v8+/wireguard.ko

If everything has gone correctly you should be able to

modprobe wireguard

If you feel daring, here it is in one bash script: