introduction
WireGuard is a VPN system built on modern cryptography that provides for a comparatively simple setup and uses UDP as a transport, with moderate overhead. It "just works" for road warrior setups where one end doesn't have a stable address.
The
OpenPandora (cache) is an ARM Linux pocket computer, first released around 2010, that uses an ancient
OpenEmbedded Ångström as base OS, with an Linux 3.2 kernel that has quite a few device-specific modules that never were upstreamed.
A couple of weeks ago, I decided to try to combine the two, provided I wouldn't turn out as too much of an effort. With that in mind, I looked at the
wireguard-go userspace implementation instead of attempting the make the WireGuard linux-compat kernel module build against the outdated OpenPandora kernel.
Setting up a tunnel requires two WireGuard components:
- a WireGuard protocol implementation (like the kernel module or wireguard-go)
- a version of wireguard-tools that is used to provide a configuration to WireGuard
As for wireguard-go, I made a short attempt at trying to build golang on the Pandora itself, but hit the "too much effort" barrier pretty quickly. Fortunately, golang now provides for cross-compiling to supported platforms - but the Pandora is not one of those: The Pandora OS (SuperZaxxon) is built with the outdated "softfp" ARM binary ABI, which is backwards-compatible with ARM CPUs that don't have floating-point hardware, but actually is capable to use vfp and NEON in the backend, if supported by the compiler. The workaround here is to crosscompile with ARMv5 as target architecture, which produces a pure software floating point executable (that also works on softfp by design).
cross-building wireguard-go
I built wireguard-go on a Debian Buster host, and since buster-backports only provides go1.14, I couldn't use the most recent version (which currently requires go1.16): Went with
wireguard-go 0.0.20210212 instead.
After checking out or unpacking the sources, building a binary is a simple matter of running make with the appropriate environment parameters:
env GOOS=linux GOARCH=arm GOARM=5 make
Just copy the resulting
wireguard-go over to
/usr/local/bin on your Pandora and make it executable.
wireguard-tools has only a small set of build dependencies, the most important of which unfortunately isn't even mentioned: On Linux, you need a copy of the kernel headers that roughly matches the destination kernel.
Turns out that SuperZaxxon only ships the include files for the initial kernel (2.6), but not those for the last available kernel build. Also Linux 2.6 apparently doesn't provide some required functions, so my first attempt failed.
I ended up downloading the
latest 3.2 kernel sources from the OpenPandora git.
When I compile software on the Pandora, I usually first try to use the
cdevtools PND - it has an older gcc, but is generally more leightweight than the other option (
Code::Blocks). So I start cdevtools, make a
src/wireguard directory, and then download and unpack both wireguard-tools and the Pandora kernel sources in there.
In the wireguard-tools directory, go to
src/ and run something like this:
env CFLAGS="-I`pwd`/../../pandora-kernel-pandora-3.2-c4c68a4/include -Os -mtune=cortex-a8 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -pipe" make
...and then, to install the resulting programs below /usr/local:
sudo env PREFIX=/usr/local WITH_WGQUICK=yes WITH_SYSTEMDUNITS=no make install
Pandora caveats
- SuperZaxxon does not autoload the tun module, so /dev/net/tun doesn't exist. (Ironically, it would be loaded if /dev/net/tun did exist and then something tried to access the device...)
- wg-quick uses some fancy bash i/o redirection which requires /dev/fd. Which is not there on the Pandora either, but it's easy to create, since it's just a symlink to /proc/self/fd.
- Do not use a VPN interface name that starts with "w" (like the default of wg0)! It triggers bugs in other scripts on the OpenPandora, for example loading of the WiFi firmware will fail after a resume from sleep.
- Add /usr/local/bin to the PATH of root so the binaries are found in their directory.
- A couple of the advanced wg-quick functions fail, mostly due to missing or outdated tools. One that I encountered was changing nameservers, but I assume anything the makes changes to the firewall configuration will be broken too. I did not try calling external commands from the wg-quick config file yet (which might serve as a workaround for some uses).
- Basic setup of a v4 tunnel with several routes has been tested successfully.
- IPv6 is completely untested.
I wrote a small wrapper script that creates a suitable environment for wg-quick invocation that's included as
/usr/local/bin/wg-pandora in the tar file below:
#!/bin/sh
if [ `id -u` -ne "0" ]; then
echo "[!] script needs to be run as root, use su oder sudo"
exit 1
fi
if [ "$1" == "" ]; then
echo "[!] please use the VPN interface name as parameter"
echo "NOTE: do not use any device names starting with \"w...\" -"
echo " it will prevent Wifi reconfiguration on SuperZaxxon."
exit 1
fi
if [ ! -f /etc/wireguard/$1.conf ]; then
echo "[!] please create /etc/wireguard/$1.conf with a valid wg-quick configuration"
exit 1
fi
if [ ! -e /dev/net/tun ]; then
echo "[+] load tun kernel module"
modprobe tun
fi
if [ ! -e /dev/fd ]; then
echo "[+] create missing /dev/fd symlink"
ln -s /proc/self/fd /dev/fd
fi
echo "[+] launching wg-quick"
/usr/local/bin/wg-quick up "$1"
exit 0
installation