Restricting Transmission to the VPN interface on Ubuntu Linux

This Howto describes restricting the Transmission BitTorrent client to the VPN connection. It is mandatory to have followed the Linux firewall Howto before going through this Howto. The firewall ruleset presented in the Linux firewall Howto is extended here.

Requirements

The reference system for this Howto is running Ubuntu Linux 13.10 with a firewall set up as described in the Linux firewall Howto.

Needed files

  • ferm.confferm configuration file with rules for Transmission.

Installation

Install the transmission package on your system by executing:

$ sudo apt-get install transmission

Configuring Transmission

Your firewall needs to be set up to only allow a single (but large) port range for Transmission's communication. Therefore you need to know which ports Transmission uses. Not all needed configuration parameters are available from within the preferences dialog — the most important ones are only present in the configuration file.

Here the list of relevant configuration parameters for this Howto:

Configuration parameterConfiguration filePreferences
bind-address-ipv4 
bind-address-ipv6 
peer-port
peer-port-random-high 
peer-port-random-low 
peer-port-random-on-start
port-forwarding-enabled
rpc-bind-address
rpc-port
rpc-white-list
rpc-whitelist-enabled

Transmission's configuration file is ~/.config/transmission/settings.json. Should this file not exist yet, you need to start Transmission once and close it again. Make sure Transmission is not running and open ~/.config/transmission/settings.json with your favorite text editor.

Transmission listens on all IPv4 and IPv6 addresses available on your system, thus the bind-ipv4-address parameter is set to 0.0.0.0 and the bind-address-ipv6 parameter is set to ::.

"bind-address-ipv4": "0.0.0.0",
"bind-address-ipv6": "::",

The peer-port is used to connect to other BitTorrent clients. The port range between peer-port-random-low and peer-port-random-high limits the total number of concurrent peer connections your client can handle – in this case 49151. Randomizing the peer port (peer-port-random-on-start) obfuscates the id of your BitTorrent client because initial connections always originate from different ports. Randomizing ports generally makes it harder for observers to correlate client connections.

"peer-port": 51413,
"peer-port-random-high": 65535,
"peer-port-random-low": 16384,
"peer-port-random-on-start": true,

For effective firewalling, it is important to disable automatic UPnP or NAT-PMP port forwarding (port-forwarding-enabled).

"port-forwarding-enabled": false,

The rpc-bind-address is used to allow external control connections to Transmission. The Transmission web interface listens on every IPv4 interface on port 9091, but only 127.0.0.1 is whitelisted per default. You could add your local network to the whitelist and reflect these changes in the ruleset for $DEV_LAN in the firewall configuration.

"rpc-bind-address": "0.0.0.0",
"rpc-port": 9091,
"rpc-whitelist": "127.0.0.1",
"rpc-whitelist-enabled": true,

Set up ferm rules

Transmission receives inbound and generates outbound traffic which respectively goes through the INPUT and OUTPUT chains. You need to allow TCP and UDP packets on the VPN interface in both directions, but not on the LAN interface.

It is very easy to adapt the firewall configuration from the Linux firewall Howto. Open the ferm configuration file /etc/ferm/ferm.conf.

Define a new variable containing the port range Transmission is allowed to use.

# Ports Transmission is allowed to use.
@def $PORT_TRANSMISSION = 16384:65535;

Locate the conditional that checks if the VPN connection is active and allow TCP and UDP packets on the ports defined in $PORT_TRANSMISSION to pass on $DEV_VPN in both the INPUT and the OUTPUT chain.

@if $VPN_ACTIVE {
    domain ip {
        chain INPUT {
	    interface $DEV_VPN {
                proto (tcp udp) dport $PORT_TRANSMISSION ACCEPT;
            }
	}
        chain OUTPUT {
            outerface $DEV_VPN {
                [..]
                proto (tcp udp) dport $PORT_TRANSMISSION ACCEPT; 
		[..]
            }
        }
    }
}

Reload the ferm firewall configuration by executing:

$ sudo ferm --interactive /etc/ferm/ferm.conf

Test

Add a Torrent file to Transmission and wait until the transfer starts. Then disconnect the VPN connection – all transfers are stopped immediately. After the VPN connection is active again Transmission resumes all transfers.

sysctl tweaks for BitTorrent clients

BitTorrent applications do not perform very well on stock Linux systems. It is important to increase the port range for local applications so you can open many connections at the same time and to tune the firewall connection tracker:

  • Generic TCP States need to timeout way faster
  • Established, but inactive connections need to timeout faster
  • After timeout, states should be cleared immediately
  • The number of tracked connections needs to be increased

The issue with many concurrent TCP sessions is that your system needs to track and timeout them. If the number of connections increases, the workload for connection tracking increases at the same time. If connections do not timeout fast, their states need to be kept in memory. Increasing the number of tracked connections only works well if timeouts are lowered. Otherwise your system sooner or later will always run out of free slots to track further connections. BitTorrent applications benefit from these tweaks when scanning for trackers or when negotiating data transfer chunks with many many peers.

These settings are very aggressive and might not suite your regular desktop use. If e.g. SSH sessions time out too fast, net.netfilter.nf_conntrack_generic_timeout and net.netfilter.nf_conntrack_tcp_timeout_established are your friends.

Add the following lines to /etc/sysctl.conf to tweak your system for better BitTorrent performance. Timeout values are given in seconds.

net.ipv4.ip_local_port_range = 16384 65535
net.netfilter.nf_conntrack_generic_timeout = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 1
net.netfilter.nf_conntrack_max = 1048576

Reload all sysctl variables from /etc/sysctl.conf.

$ sudo sysctl -p /etc/sysctl.conf

After increasing the number of concurrent client connections in your BitTorrent client you should experience way better network performance when peering with other BitTorrent users.

If you experience any problems after following this Howto, please contact support@ipredator.se. For error corrections or feedback please write an email to feedback@ipredator.se. Of course we are also available via our Online Chat.