Providing Secure Access to the Transmission Web Interface

Recently I needed to set up a dedicated BitTorrent client to manage the download of a multitude of enormous torrents. Way beyond the “I’ll just leave the desktop on overnight to finish these downloads” stage but not wanting to infest my proper server with endless gigabytes of torrent junk, I looked to my Raspberry Pi for a solution.

The hardware side of the solution comprised the Raspberry Pi and an external USB hard drive, while the software solution came in the form of the Lighttpd web server and the Transmission BitTorrent client/daemon. Both Lighttpd and Transmission are available in the default Raspbian repositories.

Now, you don’t actually need Lighttpd at all in order to download torrents with the Transmission daemon. But you do need it if you require secure remote access to Transmission’s web interface for torrent management. Transmission’s web interface only supports plain http, so I’ve used Lighttpd to provide both user authentication and secure access to Transmission.

After installing Lighttpd and Transmission, adding rules to iptables for the BitTorrent ports and mounting an external hard drive to store all those precious videos of kittens, our attention turns to configuring Lighttpd.

But just before we get there, there’s a small change to make to Transmission’s own settings file. Stop the Transmission daemon (essential, as otherwise it will overwrite any changes we make to the configuration file) and open the Transmission settings file with the following commands:

$ sudo /etc/init.d/transmission-daemon stop
$ sudo nano /etc/transmission-daemon/settings.json

Now set the value of “rpc-authentication-required” to false as we will be using Lighttpd to authenticate users instead. Make any other changes to the configuration file that you want (the options are all explained here) before saving and closing the file. Now start transmission again (see the command above, but replace ‘stop’ with ‘start).

The first step of configuring Lightppd is to install the apache2-utils package. Installing a package associated with a different web server that we’re not using might seem bizarre, but it contains the useful htpasswd and htdigest tools which can be used to generate authentication files for Lighttpd. In this instance, we’re going to use htdigest to create a file containing usernames and passwords that can be used in conjunction with Lightppd to enforce password protected access to Transmission’s web interface using the following commands.

# sudo aptitude install apache2-utils
$ cd /etc/lighttpd/
$ sudo htdigest digest.txt -c 'TransmissionWebInterface' username_one
$ cat digest.txt

Replace ‘username_one’ with the name of the first user you want to grant access to Transmission’s web interface. If you want to grant more than one user access, run the htdigest command again  but without ‘-c’. Running htdigest with ‘-c’ destroys any existing digest.txt file before creating a new one, whereas running htdigest without ‘-c’ appends to the existing file instead. The cat command simply confirms what has been added to the digest.txt file – a list of users (and their password hashes) who will be allowed to access Transmission’s web interface. The text ‘TransmissionWebInterface’ in the htdigest command is known as the realm that the credentials are valid for. I’ve used ‘TransmissionWebInterface’ rather than simply ‘Transmission’ to avoid possible confusion as ‘Transmission’ is the text in the (otherwise identical) credentials prompt that Transmission’s own RPC authentication procedure presents if you’ve forgotten to turn it off.

Now, before leaving the /etc/lighttpd directory, we must create a security certificate for Lighttpd in order to provide secure https access to Transmission’s web interface. The openssl command is used for this. It requires responses to a number of questions. Look here if you need help answering them.

# sudo openssl req -new -x509 -keyout certificate.pem -out certificate.pem -days 365 -nodes
$ sudo chown www-data:www-data certificate.pem
$ sudo chmod 0600 certificate.pem

Now it is time to delve into the lighttpd.conf file itself. Edit it with the nano text editor by issuing the following command.

$ sudo nano /etc/lighttpd/lighttpd.conf

Before I show you the modifications to the configuration file, I will summarise what I want to accomplish.

  1. We want to be able to easily access the Transmission daemon running on our Raspberry Pi from anywhere in the world by typing a simple address like http://www.ourdomain.com/transmission
  2. We want the connection to be secure, so we automatically redirect any request for http://www.ourdomain.com/transmission to https://www.ourdomain.com/transmission
  3. We want to restrict access to a limited set of users, so we request a username and password from any visitor to https://www.ourdomain.com/transmission

This can all be accomplished with the following lighttpd.conf file

server.modules = (
"mod_access",
"mod_alias",
"mod_auth",
"mod_compress",
"mod_proxy",
"mod_redirect",
#"mod_rewrite",
)

server.document-root = "/var/www"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www-data"
server.groupname = "www-data"
server.port = 80

index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )

# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

# Auth directives
auth.backend = "htdigest"
auth.backend.htdigest.userfile = "/etc/lighttpd/digest.txt"
auth.debug = 1

# Force https for certain URLs
$SERVER["socket"] == ":80" {
$HTTP["url"] =~ "^/transmission" {
url.redirect = ( "^/(.*)" => "https://www.ourdomain.com:443/transmission/web/" )
}
server.document-root = "/var/www"
}

# Supply SSL certrificate for the https connection
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/lighttpd/certificate.pem"
# Restrict access to only those users in the digest.txt file
$HTTP["url"] =~ "^/transmission*" {
auth.require = ( "" =>
(
"method" => "digest",
"realm" => "TransmissionWebInterface",
"require" => "valid-user"
) )
# Use proxy to redirect authenticated users to Transmission's own web interface
proxy.debug = 1
proxy.server = ( "" =>
( (
"host" => "127.0.0.1",
"port" => 9091
) )
)
}
}

The lighttpd.conf file can be downloaded here (with the bonus of better formatting than above!). Don’t just overwrite your existing lighttpd.conf file with this one, as you’ll lose any changes you’ve already made to it. Also you’ll need to alter http://www.ourdomain.com to whatever your domain is and also pay attention to whether or not the names or locations of certificate.pem and digest.txt are correct if you deviated from the instructions for creating them earlier.

The modified lighttpd.conf configuration can be tested with the command below. It should return ‘Syntax OK’, in which case you can restart Lighttpd to apply the changes to the webserver. If not, then it should at least provide a line number for where it found a problem. If it does give an error, double check that all the required server modules have been added at the top of the file before doing anything else.

$ lighttpd -t -f /etc/lighttpd/lighttpd.conf
Syntax OK
$ sudo /etc/init.d/lighttpd restart

Now that Lighttpd has accepted the new configuration file, you can test it by pointing your browser at http://www.ourdomain.com/transmission . The first sign that everything’s working properly should be a warning message saying that the site’s security certificate is not to be trusted. This is fine – the browser is alerting the user as it doesn’t recognise the certificate as being from a trusted certificate provider. Indeed, it shouldn’t for it’s the home-made certificate we generated earlier using the openssl command. Depending on your browser, ‘Proceed Anyway’ or ‘Add security exception’ to convince your browser that the certificate is to be trusted.

Now a login prompt should appear. Along with the boxes for entering a username and password, the text ‘TransmissionWebInterface’ should appear. If it reads only ‘Transmission’, go back and read about disabling Transmission’s RPC authorisation. Enter the username and password you created for the digest.txt file and you should be rewarded with the Transmission web interface displayed in your browser.

3 thoughts on “Providing Secure Access to the Transmission Web Interface

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s