Preface
I’ve wanted to setup transmission on my server for a while. I just wanted to make sure no one could see the linux iso’s I was downloading. I’ve tried before but for some reason always struggled. I mean I had it working a few years ago but that was without docker. Now I have a little bit of a diffrent approch. I want to talk about that today.
Introduction
Torrenting over a VPN is fairly simple, it is the seeding that is the problem. Lots of VPN services either block outright the ability to see or open a random port that you have to figureout and add to your client. The worst part, it changes when you restart the VPN. So… how do I go about fixing that? I will be using the LSIO container for transmission. LSIO has the amazing ability to run “Private Custom Services”. This allows you to run a script along side what ever service is starting. So lets start some of the configs and scripts.
- Create the Docker File.
Create a directory called
transsmision
and then create a file in there calledDockerFile
.
FROM linuxserver/transmission:latest
RUN apk add libnatpmp --no-cache
RUN mkdir /custom-cont-init.d
COPY ./open_port.sh /custom-services.d/
RUN chmod +x /custom-services.d/open_port.sh
- The script. In that same directory you will want to add a script called
open_port.sh
.
#!/bin/bash
# Wait for Transmission to start
while ! nc -z localhost 9091; do
echo "Waiting for Transmission to start..."
sleep 1
done
# Function to extract port number from natpmpc output
extract_port() {
local output="$1"
echo "$output" | sed -n 's/.*Mapped public port //p' | sed -n 's/\ .*//p'
}
# Run natpmpc commands and extract port numbers
tcp_output=$(natpmpc -a 1 0 tcp 60 -g 10.2.0.1)
# Extract and print port numbers
tcp_port=$(extract_port "$tcp_output")
# Update the Transmission peer listening port
transmission-remote -n "username:password" -p $tcp_port
# Check if the update was successful
if [ $? -eq 0 ]; then
echo "Transmission peer listening port updated to $tcp_port"
else
echo "Failed to update Transmission peer listening port"
fi
sleep 60m
In this script, you will need to specify the username and password, which isn’t great but I have set it to something generic as this is just my torrenting server. Maybe not the best idea, if you have any suggestions I am all ears (comments at bottom of page).
The first section of the script is checking to see if Transmission has started. Then it runs natpmpc
to see what port is open. The script then calls extract_port()
to filter out all the crap and just get the port number. Lastly, at the bottom, it uses transmission-remote
to set the port. It will then sleep for sixty minits and then run again. This is just incase it changes. Also, if you don’t make it sleep, it will run constatnly which is probably not best practice. You could also set it to sleep indefinate
, if you don’t want the script running evey hour.
- Wireguard Image We are going to need to get our Wireguard config from our VPN provider. For seeding to work you will obviously need a provider that support it, for me that is ProtonVPN. I’m not going to walk you through that section.
Right, now create a directory called wireguard
and copy the wg0.conf
file into there. Now we wan’t to create another DockerFile
.
FROM linuxserver/wireguard:latest
COPY ./wg0.conf /config/wg_confs/wg0.conf
We will also want to edit the wg0.conf
file to include these two lines:
[Interface]
...
PostUp = ip route add 192.168.1.0/24 via 172.20.0.1;
PreDown = ip route delete 192.168.1.0/24;
[Peer]
...
You will need to ensure that the subnets match your network setup.
- Now we move onto the
docker-compose.yml
file. Create this in the root of your docker folder, e.g. not in either the transmission or wireguard folders. This is the final bit before testing.
services:
wireguard:
container_name: wireguard
build:
context: wireguard/
dockerfile: Dockerfile
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.conf.all.src_valid_mark=1
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Stockholm
- VIRTUAL_HOST=127.0.0.1
- VIRTUAL_PORT=9091
ports:
- 9091:9091
volumes:
- /lib/modules:/lib/modules
restart: always
transmission:
container_name: transmission
build:
context: transmission/
dockerfile: Dockerfile
network_mode: "service:wireguard"
depends_on:
- wireguard
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Stockholm
env_file:
- ./.env
volumes:
- /location/too/transmission/transmission-config:/config
- /location/too/transmission/downloads:/downloads
- /location/too/transmission/watch:/watch
restart: always
We will also want to create the .env
file with username and password we want:
# TRANSMISSION
USER=username
PASS=password
- Running it.
We should be able to get this working now. Run
docker compose up -d
To test that trafic is going through the vpn, we can run:
docker exec transmission sh -c 'curl -Ss https://ipinfo.io'
docker exec wireguard sh -c 'curl -Ss https://ipinfo.io'
You should see:
The IP should be diffrent from your home one.
If so, you can now check by going to the ip of your docker server with the port 9091
. Go into the handburger menu at the top of the website and Edit Preferances -> Network
. You should see Peer listening port
as open.
If that is showing up, you should be all good. Feel free to ask any questions down bellow.
Comments
You can respond to this post on Mastodon: 🔗 or click to copy the URL to your clipboard so you can paste it into your client.