So I recently received my Raspberry Pi case fan, making my Pi 4 actually usable without it spiking to 80 degrees Celsius. Hooray!
As a paranoid cypherpunk unfortunately living under an authoritarian government, I have some privacy requirements: only Windscribe, my own devices, and some very select services are allowed to see my IP; and connections between the Pi and my other devices must always be encrypted.
This ruled out Tailscale (although that could be useful especially with the integration with Mullvad as exit nodes) as that poses the risk of leaking my IP address to things linked to my digital identity.
It took me quite a bit of finagling and research to get this setup to work just right. I hope my experiences can save you time even if you don't have an extremely niche use case.
My final setup
I have two VPNs active at once on my devices: Windscribe and Nebula. Windscribe routes my outgoing traffic through their network, while Nebula connects the devices together, somewhat like Tailscale.
On the Windscribe page, I used the config generator to generate me a WireGuard config for a certain location. I simply copied this config to my Raspberry Pi and started the connection with wg-quick
(I'm not gonna go into details here, should be trivial enough with a Perplexity search)
Windscribe + Nebula
Nebula requires one always-online server called a lighthouse with a static IP (I believe it may work with dynamic DNS, but untested) in order to direct devices to reach each other. I set it up on my Raspberry Pi and opened up a port on my router to make it reachable from the Internet.
Following the Nebula docs worked out pretty well, got nothing extra to say there.
As Nebula doesn't come with systemd services, I had to write them myself. On my Raspberry Pi, I created a new system user account called nebula
, gave it ownership of /etc/nebula/
and set it up as a service:
[Unit]
Description=Nebula Overlay Networking
After=network.target
[Service]
Type=simple
ExecStart=/bin/nebula -config /etc/nebula/config.yaml
Restart=always
RestartSec=10
User=nebula
Group=nebula
AmbientCapabilities=CAP_NET_ADMIN
[Install]
WantedBy=multi-user.target
I did a similar one for my laptop, setting up Nebula as a service that runs after Windscribe starts and making sure to create the necessary user accounts:
[Unit]
Description=Nebula Overlay Networking
After=network.target
[Service]
Type=simple
ExecStart=/bin/nebula -config /etc/nebula/config.yaml
Restart=always
RestartSec=10
User=nebula
Group=nebula
AmbientCapabilities=CAP_NET_ADMIN
[Install]
WantedBy=multi-user.target
Additionally, I had to add my chosen range to Windscribe's split tunneling on my laptop in order to allow connections to go through Nebula. (Why did I use TEST-NET-2 and not the designated CGNAT range? Scroll further)
When I change my Windscribe location, I have to also restart the Nebula service, but aside from that it's perfect.
Android
On my Android, I use a work profile to run Nebula while using the main profile with Windscribe. This bypasses the Android restriction of only one VPN active at a time, so now I can have most of my apps behind Windscribe and the selfhosted apps on Nebula. Nice!
UFW kill switch
It took me a while to get it done, but:
sudo ufw allow ssh
sudo ufw allow
sudo ufw default deny outgoing
Routing conflict
On my first try, I decided to set Nebula up on the CGNAT range. Too bad Windscribe uses it.
I had to redo my Nebula network to use TEST-NET-2, which is 198.51.100.0/24
. So yeah, double check your ranges.
Windscribe doesn't play well with IPv6
Windscribe doesn't support split tunneling IPv6 ranges unfortunately. (and after I finished setting up Yggdrasil!) That was one of the things that stopped me from using Yggdrasil, the other being the high latency.
Closing remarks
Now I've got the basic networking out of the way, I am finally free to finally get some selfhosted services up.
This journey taught me CIDR notation and a little more about being a sysadmin. It would never have been possible (or at least, would take 10 times more time) without the help of my beloved Claude and Perplexity.
During my research, I came across a list of different projects. I opted for Nebula, but here's a small inexhaustive list of the stuff I came across during my search:
Innernet, a mesh network based on CIDRs
Headscale, an open source Tailscale control server implementation
tinc-boot, a wrapper over tinc, which is a full-mesh, auto-healing VPN system supporting many many OSes
A blog post from fmac titled 'Nested WireGuard tunnels to my home'
gluetun, a tool for running a VPN (the privacy tool kind, not the access tool kind) inside Docker
wireguard-go, a userspace implementation of WireGuard
NetBird, a mesh net with a full GUI and centralized access control like Tailscale (actually now that I'm writing this post I think I should've just used this but whatever i've set it up already)