How can I ensure transmission traffic uses a VPN?
I'd like to ensure that transmission only sends/receives traffic when the server it runs on is connected to a VPN.
I found this question which is similar but I don't want to force all traffic through the VPN and I haven't been able to find a good guide on how to use firestarter from the command line.
Instead I was thinking of using ufw, but I have little to no experience with firewalls, and I'm hoping the community can help me out.
One idea I had would be to force transmission to use a specific port, say 33442, and then only allow traffic to and from that port from the IP address of the VPN server. I checked out the Ubuntu server guide and I think could do something like this:
sudo ufw enable
sudo ufw deny port tcp from localhost to any port 33442
sudo ufa allow port tcp from localhost to VPNIP port 33442
sudo ufw deny port udp from localhost to any port 33442
sudo ufa allow port udp from localhost to VPNIP port 33442
Does this logic hold its salt? How would you do it? What would I use for VPNIP, the public IP of the VPN server, or should I specify the local subnet range that the VPN connects me to?
Thanks for your help!
Create vpnroute
group:
sudo groupadd vpnroute
Add an iptables
rule that rejects any outgoing network connection made by members of the vpnroute
group that does not go through tun0
interface:
sudo iptables -A OUTPUT -m owner --gid-owner vpnroute \! -o tun0 -j REJECT
Start transmission process as a member of vpnroute
group:
sudo -g vpnroute transmission-gtk &
Here is a complete 'HOW TO' for NOOBS (using debian) on making sure the debian-transmission user group (i.e transmission) only routes data through the vpn
DO NOT use the more lengthy 'How to' for vpn based on complex system scripts...! iptables is THE BEST (and foolproof) METHOD!!! - USING A FEW IPTABLE RULES based on the transmission user and group to control the vpn (not like many more complex 'hack' methods which use systemd scripts, up and down scripts etc...) and it's soooo simple!
Step 1 - Setup: (Assumes transmission is installed and debian-transmission user therefore exists!)
sudo apt-get install iptables
sudo apt-get install iptables-persistent
Step 2 - Create the transmission-ip-rules file
sudo nano transmission-ip-rules
and add the text in the code block below starting from #!/bin/bash
IMPORTANT
- If your local network is not of the form 192.168.1.x Change the NET variable to correspond to your own local network addressing format!!.
- Also be aware of the quirk that 192.168.1.0/25 actually gives the range 192.168.1.0-255!
- Sometimes your interfaces eth0, tun0 (which is the vpn) etc.. maybe different - check with 'ifconfig' and change if needed.
#!/bin/bash
# Set our rules so the debian-transmission user group can only route through the vpn
NET=192.168.1.0/25
GROUP=debian-transmission
IFACE_INTERNAL=eth0
IFACE_VPN=tun0
ALLOW_PORT_FROM_LOCAL=9091
iptables -A OUTPUT -d $NET -p tcp --sport $ALLOW_PORT_FROM_LOCAL -m owner --gid-owner $GROUP -o $IFACE_INTERNAL -j ACCEPT
iptables -A OUTPUT -d $NET -p udp --sport $ALLOW_PORT_FROM_LOCAL -m owner --gid-owner $GROUP -o $IFACE_INTERNAL -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner $GROUP -o $IFACE_VPN -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner $GROUP -o lo -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner $GROUP -j REJECT
# not needed - but added these to properly track data to these interfaces....when using iptables -L -v
iptables -A INPUT -i $IFACE_VPN -j ACCEPT
iptables -A INPUT -i $IFACE_INTERNAL -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
# track any forward (NAT) data for completeness - don't care about interfaces
iptables -A FORWARD
Save the file and then run
sudo iptables -F
sudo chmod +x transmission-ip-rules
sudo ./transmission-ip-rules
then make sure these rules persist between reboots with:
sudo dpkg-reconfigure iptables-persistent
and tap yes to both prompts. DONE!
What is great about this script is that it will track all data through the device! When you issue
sudo iptables -L -v
it will show how much data is going to which interface and which side INPUT or OUTPUT so you can be assured that the vpn script is working properly. Eg;
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1749K 661M ACCEPT all -- tun0 any anywhere anywhere
3416K 3077M ACCEPT all -- eth0 any anywhere anywhere
362K 826M ACCEPT all -- lo any anywhere anywhere
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 all -- any any anywhere anywhere
Chain OUTPUT (policy ACCEPT 2863K packets, 2884M bytes)
pkts bytes target prot opt in out source destination
1260 778K ACCEPT tcp -- any eth0 anywhere 192.168.1.0/ 25 tcp spt:9091 owner GID match debian-transmission
0 0 ACCEPT udp -- any eth0 anywhere 192.168.1.0/ 25 udp spt:9091 owner GID match debian-transmission
1973K 1832M ACCEPT all -- any tun0 anywhere anywhere owner GID match debian-transmission
8880 572K ACCEPT all -- any lo anywhere anywhere owner GID match debian-transmission
13132 939K REJECT all -- any any anywhere anywhere owner GID match debian-transmission reject-with icmp-port-unreachable
This script has been exhaustively tested on connects, disconnects, reboots from the vpn. It works great. Transmission can ONLY use the VPN. The great advantage of this script over the others is that I have made sure as you can see (via iptables -L -v
) that your data tallies with what is pulled over transmission (by adding INPUT (all) and Forward (all) rules for each interface eth0, vpn (tun0)). So you know exactly whats happening!!! The data totals will not tally exactly with transmission - Unfortunately I cannot discriminate on the INPUT side down to the debian-transmission user, and there will be both extra overhead and perhaps other processes using the same VPN, but you will see the data roughly tallies on the INPUT side and is about half on the OUTPUT for the vpn confirming its working.
Another thing to note - it take a while on a vpn disconnect (all traffic stops with transmission) and reconnect for transmission to 'get going' on the new vpn so don't worry if it takes about 5 mins to start torrenting again...
TIP - google 'MAN iptables' and see this article on bandwidth monitoring if you want to know line by line how this script works...
This works for a headless transmission, I am restricting traffic based on the user that is running the transmission service, 10.0.0.0/8
is your internal network you should change it to match your network, tun0
is your OpenVPN interface, eth0
is your LAN connection.
Add sudo
to commands, if you are not root:
iptables -F
(We used the -F switch to flush all existing rules so we start with a clean state from which to add new rules.)
iptables -L
(list current setup)
NET=10.0.0.0/8
GROUP=debian-transmission
IFACE_INTERNAL=eth0
IFACE_VPN=tun0
ALLOW_PORT_FROM_LOCAL=9091
iptables -A OUTPUT -d $NET -p tcp --sport $ALLOW_PORT_FROM_LOCAL -m owner --gid-owner $GROUP -o $IFACE_INTERNAL -j ACCEPT
iptables -A OUTPUT -d $NET -p udp --sport $ALLOW_PORT_FROM_LOCAL -m owner --gid-owner $GROUP -o $IFACE_INTERNAL -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner $GROUP -o $IFACE_VPN -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner $GROUP -o lo -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner $GROUP -j REJECT
make the iptables persistent after restart
apt-get install iptables-persistent
service iptables-persistent start
Ideally you should use a torrent client that has a feature to bind to a specific interface (the VPN interface).
Among torrent clients, Deluge does this. So you can install Deluge and configure the interface in the Preferences and you are set!