Home Server 4: Transmission with VPN
2022-12-20 03:35Why stick with just Bitcoin? Let’s run some other stuff on this machine, too. Let’s get a BitTorrent server running! But, we don’t want our ISP snooping on us, so let’s do it within a VPN. However, VPNs can play havoc with local LAN services, so we will also need to setup a container so that only our BitTorrent client is operating within the VPN.
How do we do that? Why, Linux network namespaces! We could also use Docker, but I’m going the barebones route this time.
First, some housekeeping: I will be using Mullvad for VPN, which supports Wireguard. If you use a different VPN provider, hopefully they support Wireguard. You should be able to adapt their Wireguard configs to this without too much difficulty. You will have a harder time if they only support OpenVPN.
First step is to install is to download the wireguard config from Mullvad. Then scp (SSH file copy) to your machine.
scp mullvad-config.zip YOUR-USERNAME@host:/home/YOUR-USERNAME/mullvad-wireguard.zip
Then SSH back into your server and install some software and copy the wireguard configs.
sudo apt install unzip transmission-cli transmission-daemon wireguard
unzip mullvad-wireguard-config.zip -d mullvad_config
sudo mkdir -p /etc/wireguard
# Pick your Mullvad server and copy the config
cp mullvad_config/my-server.conf /etc/wireguard/wg0.conf
sudo chown root:root -R /etc/wireguard && sudo chmod 600 -R /etc/wireguard
Okay, you should have a basic VPN that can function now:
wg-quick up wg0
curl https://am.i.mullvad.net/connected
# => You are connected to Mullvad (server ch2-wireguard). Your IP address is 81.17.24.203
Alright, you’re up and running! The only problem is that this covers the whole machine’s network, not just one application. This is where namespaces come in. Linux has the ability to containerize network stacks into something called namespaces. This is a fundamental building block of Docker containers. We will be building one of these manually.
I may dockerize my server at a later time, but let’s stick low level for the time being.
# Take down our previous VPN
wg-quick down wg0
# Comment out the lines starting with Address= and DNS=.
# However, remember or recordt these values because you will need them!
sudo nano /etc/wireguard/wg0.conf
touch mullvad-start mullvad-stop
chmod +x mullvad-start mullvad-stop
We’re going to create a systemd service that will create our namespace at startup, and close it down.
mullvad-start
Add this script below into the mullvad-start
file. Make sure to replace the IP addresses with the ones from the commented out Address
line from the wireguard config.
#!/usr/bin/env bash
# Create a wireguard namespace and move the wg0 interface into it
ip netns add wireguard
ip link add wg0 type wireguard
wg setconf wg0 /etc/wireguard/wg0.conf
ip link set wg0 netns wireguard
ip netns exec wireguard ip addr add 10.66.247.57/32 dev wg0
ip netns exec wireguard ip addr add fc00:bbbb:bbbb:bb01::3:f738/128 dev wg0
ip netns exec wireguard ip link set wg0 up
ip netns exec wireguard ip route add default dev wg0
# Create a tunnel between the wireguard namespace and the public namespace
ip link add transclient type veth peer name transserver
ip link set transserver netns wireguard
ip addr add 10.10.10.20/24 dev transclient
ip netns exec wireguard ip addr add 10.10.10.10/24 dev transserver
mullvad-stop
Add this text to the mullvad-stop
script.
#!/usr/bin/env bash
ip netns delete wireguard
ip link delete transclient
Install the executables.
sudo install mullvad-start /usr/local/bin/mullvad-start
sudo install mullvad-stop /usr/local/bin/mullvad-stop
Now we need to setup DNS.
sudo mkdir -p /etc/netns/wireguard
sudo touch /etc/netns/wireguard/resolv.conf
sudo chown root:root -R /etc/netns && sudo chmod 600 -R /etc/netns
sudo nano /etc/netns/wireguard/resolv.conf
Add this line to resolv.conf
: nameserver x.x.x.x
Except, of course, replace the IP with the DNS from wg0.conf
file, which you previously commented you.
You should now be able to connect to the VPN inside a container.
sudo mullvad-start
sudo ip netns exec wireguard curl https://am.i.mullvad.net/connected
# => You are connected to Mullvad (server wg0). Your IP address is x.x.x.x
sudo mullvad-stop
Let’s setup a systemd service: sudo nano /etc/systemd/system/mullvad.service
[Unit]
Description=Start Wireguard VPN in separate namespace
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mullvad-start
ExecStop=/usr/local/bin/mullvad-stop
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
Enable it and modify the transmission-daemon
service:
sudo systemctl enable mullvad
sudo systemctl edit transmission-daemon
Add the following lines and save:
[Service]
NetworkNamespacePath=/run/netns/wireguard
User=YOUR-USERNAME
BindReadOnlyPaths=/etc/netns/wireguard/resolv.conf:/etc/resolv.conf:norbind
Now let’s start the services: sudo systemctl restart mullvad transmission-daemon
Last, but not least, add the following lines to the stream {}
block in your /etc/nginx/nginx.conf
config (or create the block if you don’t have it):
stream {
upstream transmission {
server 10.10.10.10:9091;
}
server {
listen 9091;
proxy_pass transmission;
}
}
Finally, you should be able to connect to your transmission web UI on another machine on your
network like this: http://your-machine:9091
If you get a message about rpc whitelists, stop the transmission-deamon service, then edit ~/.config/transmission-daemon/settings.json
and set the rpc-whitelist
config options to false
to disable rpc-whitelist. Make sure to set the rpc-user
and rpc-password
attribute, and change rpc-authentication-required
to true
.
Links:
Wireguard in a linux namespace Overriding systemd services Redhat: network namespaces