Skip to content

[Debian] [HOWTO] Install rTorrent 0.8.9 with ruTorrent on nginx

There are many guides out there for this task. I will try this one to be comprehensive and also security tightened. In this first part. I will only write about rtorrent. Mostly compiling is not required as most distros already have xmlrpc-c support with rtorrent. (xmlrpc-c is required for rutorrent) And hence you can simply 'apt-get install rtorrent' and proceed on with the configuration of it and rutorrent/web interface. But if you want to compile read on. This tutorial is divided into two parts. Here's the quick review of the things we will do:

rTorrent:

  • Install basic packages (programs/libraries).
  • Compile XMLRPC-C.
  • Compile c-ares.
  • Compile cURL with c-ares support for DNS requests and name resolves asynchronously.
  • Compile libtorrent.
  • Compile rTorrent with xmlrpc-c support.
  • Setup rtorrent configuration file.
  • Setup rtorrent init.d script.

Web Interface:

  • Install nginx & PHP.
  • Config nginx for SCGI/PHP/Authentication .
  • Download rutorrent.
  • Secure the directories and rutorrent user.
  • Add authentication for rutorrent user.

Just in in case if any of you think why do I do this long process instead of installing rtorrent directly from repos, its because this way the performance is improved, if you use more then hundred torrents and rtorrent is slowed down during the start up and hence may end up stuck. rTorrent uses curl and hence compiling curl with c-ares results in a stable rtorrent. For verification check this ticket. Note, I suppose you have the basic knowledge of Linux. Preparation: Never execute every step with 'root' account. Only few steps require root, wherever root is required I have used sudo a.k.a superuser. If your system is clean and if you haven't set up a user account and sudo, follow these steps.

  1. Add the new account to the system. Note: Replace user1 with a name of your choosing. Not every detail is required, just provide UNIX password and you should be fine.

    adduser user1
    
  2. Add the user1 to sudeors (the accounts which can use sudo) . This will give your normal user the ability to have root rights. Use visudo to use user-friendly text-editor called nano. Don't execute 'nano /etc/sudoers'. Using visudo is the best practice.

    visudo
    

Find the line 'root ALL=(ALL) ALL' add your user1 in the next line.

user1 ALL=(ALL) ALL

Save and exit. Now user1 should be able to use sudo. Use it to execute commands which require root. Example, sudo reboot. Now you can proceed on with the steps. 1. Install Basic Packages: These will be the required packages:

sudo apt-get update



sudo apt-get install wget tar htop nano build-essential screen libncurses5-dev libcurl4-openssl-dev libsigc++-2.0-dev

2. Compile XMLRPC-C:

wget http://sourceforge.net/projects/xmlrpc-c/files/Xmlrpc-c%20Super%20Stable/1.16.35/xmlrpc-c-1.16.35.tgz
tar zxfv xmlrpc-c-1.16.35.tgz
cd xmlrpc-c-1.16.35
./configure
make
sudo make install

3. Compile c-ares:

wget http://c-ares.haxx.se/c-ares-1.7.4.tar.gz
tar zxfv c-ares-1.7.4.tar.gz
cd c-ares-1.7.4
./configure
make
sudo make install

4. Compile cURL:

wget http://curl.haxx.se/download/curl-7.21.7.tar.gz
tar zxfv curl-7.21.7.tar.gz
cd curl-7.21.7.tar.gz
./configure --enable-ares

# Output of ./configure should be similar to this, Resolver must be c-ares.
curl version:    7.21.7
Host setup:      i686-pc-linux-gnu
Install prefix:  /usr/local
Compiler:        gcc
SSL support:     enabled (OpenSSL)
SSH support:     enabled (libSSH2)
zlib support:    enabled
krb4 support:    no      (--with-krb4*)
GSSAPI support:  no      (--with-gssapi)
SPNEGO support:  no      (--with-spnego)
TLS-SRP support: no      (--enable-tls-srp)
resolver:        c-ares
ipv6 support:    enabled
IDN support:     enabled
Build libcurl:   Shared=yes, Static=yes
Built-in manual: enabled
Verbose errors:  enabled (--disable-verbose)
SSPI support:    no      (--enable-sspi)
ca cert bundle:  /etc/ssl/certs/ca-certificates.crt
ca cert path:    no
LDAP support:    enabled (OpenLDAP)
LDAPS support:   enabled
RTSP support:    enabled
RTMP support:    no      (--with-librtmp)
Protocols:       DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS LDAP LDAPS POP3 POP3S RTSP SCP SFTP SMTP SMTPS TELNET TFTP

# Continue Compiling cURL:
# After ./configure do the following;
make
sudo make install

5. Compile libtorrent:

wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.12.9.tar.gz
tar zxfv libtorrent-0.12.9.tar.gz
cd libtorrent-0.12.9
./configure
make
sudo make install

6. Compile rTorrent

wget http://libtorrent.rakshasa.no/downloads/rtorrent-0.8.9.tar.gz
tar zxfv rtorrent-0.8.9.tar.gz
cd rtorrent-0.8.9
./configure --with-xmlrpc-c
make
sudo make install

7. Setup rTorrent: rTorrent needs a config file to initialize it. Download it and edit it.

wget http://libtorrent.rakshasa.no/export/1243/trunk/rtorrent/doc/rtorrent.rc -O ~/.rtorrent.rc
nano ~/.rtorrent.rc

It's explained very well, read through it and optimize it according to your needs. Just add this line at the end of file.

OLD:

encoding_list = UTF-8
http_capath=/etc/ssl/certs
scgi_local = /tmp/scgi.socket
schedule = chmod,0,0,"execute=chmod,777,/tmp/scgi.socket"


New: (use this)

encoding_list = UTF-8
scgi_local = /home/rtorrent/scgi.socket
execute = chmod,ug=rw\,o=,/home/rtorrent/scgi.socket
execute = chgrp,rtorrent-nginx,/home/rtorrent/scgi.socket

The execute lines are for setting permissions on the Unix domain socket file that rtorrent and nginx will use to communicate. These will be dependent on how you want to set up your permissions. This is a very important security step to take if you are doing this on a shared server, as any user that has read/write access on the socket file could execute arbitrary code by sending commands to rtorrent! In my case, I set up a separate user for running rtorrent (named rtorrent) and a separate user for running nginx (named nginx). I then created a group called rtorrent-nginx, and only have my rtorrent and nginx users added to it. Source: https://blog.abevoelker.com/rtorrent_xmlrpc_over_nginx_scgi/

If you don't want to start rtorent at every boot you can use a init.d script.

#!/bin/bash
### BEGIN INIT INFO
# Provides:          rtorrent
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start/stop rtorrent daemon
### END INIT INFO

# This script is an init script to run rtorrent in the background,
# using a screen. The script was designed and tested for Debian
# systems, but may work on other systems. On Debian, enable it by
# moving the script to "/etc/init.d/rtorrent" and issuing the command
# "update-rc.d rtorrent defaults 99"

USER=x # username to run rtorrent under
RTORRENT=/usr/local/bin/rtorrent # rtorrent binary
SCREEN=/usr/bin/screen # screen binary
SCREEN_NAME=rtorrent # screen name (this way you can screen -r rtorrent)
PIDFILE=/var/run/rtorrent.pid # pidfile
SOCKET=/tmp/scgi.socket

case "$1" in

    start)
        echo "Starting rtorrent."
        start-stop-daemon --start --background --oknodo
            --pidfile "$PIDFILE" --make-pidfile
            --chuid $USER
            --exec $SCREEN -- -DmUS $SCREEN_NAME $RTORRENT
        if [[ $? -ne 0 ]]; then
            echo "Error: rtorrent failed to start."
            exit 1
        fi
        echo "rtorrent started successfully."
        ;;

    stop)
        echo "Stopping rtorrent."
        start-stop-daemon --stop --oknodo --pidfile "$PIDFILE"
        rm -rf -- $SOCKET
        if [[ $? -ne 0 ]]; then
            echo "Error: failed to stop rtorrent process."
            exit 1
        fi
        echo "rtorrent stopped successfully."
        ;;

    restart|force-reload)
        "$0" stop
        sleep 1
        "$0" start || exit 1
        ;;

    *)
        echo "Usage: $0 [start|stop|restart]"
        exit 1
        ;;
esac

I haven't written it, I have tweaked it a bit for this tutorial/setup. Replace the USER value with your username.

References:

RTorrentXMLRPCGuide

[The reason I compile curl with c-ares specially for rTorrent

Original init script for rTorrent

In this second part, I will be working on web interface (rutorrent) to work with rTorrent and nginx. I will be using nginx as my web server. You can use any Web Server which supports SCGI and PHP. Apache's process is very easy though. Proceed if you wish you use nginx. As I have described before we need a web server which has SCGI module. We can use RPC plugin for rutorrent but I remember, it has performance issues, hence SCGI module comes in. Here'sthe overview of the following steps:

Web Interface:

  • Install nginx & PHP.
  • Config nginx for SCGI/PHP/Authentication .
  • Download rutorrent.
  • Add authentication for rutorrent user.
  • Secure the directories and rutorrent user.
  • Configure rutorrent and plugins.

Side Note for Squeeze/Lenny Users: Debian's Lenny/Squeeze repositories has old build of nginx which didn't consist of SCGI module and it also doesn't contain PHP5-FPM and hence I had to update my repos (/etc/apt/sources.list) to wheezy, only for nginx and php5-fpm. SCGI Module appeared first in nginx 0.8.42. before updating sources.list to wheezy, check if nginx is exact 0.8.42 or higher and also if php5-fpm exists or not, if both or single are negative, you must update your repos to wheezy. After installation. I, of course reverted back to squeeze repos.

Install nginx package:

apt-get install nginx

Create the document root for nginx:

mkdir /var/www

Change the owner of document root to www-data as per future configuration of nginx:

chown www-data:www-data /var/www

Install & Configure PHP5

We will get PHP5 to work in nginx through PHP5-FPM. Few plugins of rutorrent require certain PHP5 modules and you can install them later. I will install only php5-cli,php5-geoip and geoip-database on my system

apt-get install php5-cli php5-fpm php5-geoip geoip-database

Next, open /etc/php5/fpm/php.ini and uncomment the line cgi.fix_pathinfo=1: (On most PHP versions, the value is default 1)

nano /etc/php5/fpm/php.ini

It should look like this:

[...]
cgi.fix_pathinfo=1
[...]

Open /etc/php5/fpm/pool.d/www.conf and find 'listen' line, it should be like this:

listen = /var/run/php-fpm/php-fpm.sock

You may want to create folder php-fpm if it doesn't exist:

mkdir /var/run/php-fpm

Configure nginx for PHP/SCGI/Authentication:

This can be a tricky part. I would recommend you to check official documents of nginx. Its explained well although. Main configuration file:

/etc/nginx/nginx.conf

My nginx.conf looks like this. Some explanation: worker_processes = nginx workers, according to people, good practice is to keep this value equal to your CPU cores. server_tokens off = Turns off nginx version in the headers log_format = Easily readable log format ( /var/log/nginx/access.log) include /etc/nginx/sites-enabled/rtorrent = Includes execution of main rtorrent vhost file which includes most important configurations.

user www-data;
worker_processes 2;
pid /var/run/nginx.pid;

events {
        worker_connections 768;
}

http {
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        server_tokens off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

       log_format main '$remote_addr - $remote_user [$time_local] '
           '"$request" $status  $body_bytes_sent "$http_referer" '
           '"$http_user_agent" "$http_x_forwarded_for"';

        access_log /var/log/nginx/access.log main;
        error_log /var/log/nginx/error.log warn;

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/rtorrent;
}

We will be editing now rtorrent vhost, Mine looks like this. Remember, this includes password protected rutorrent directory, PHP configuration, RPC link between rtorrent and nginx and some other blocks to secure up your web server. I highly recommend you to read nginx's official links. At the end of the post, references have been posted. Bit explanation: root = document root usually /var/www/ or /srv/http/ location \~ .php$ = PHP configuration block location \~ ^/RPC2$ = RPC2 configuration block auth_basic and auth_basic_user_file = realm and password containing file respectively which will be created by htpasswd.py in the next step.

nano /etc/nginx/sites-available/rtorrent



server {
        listen 80;
        root /var/www/;
        index index.php index.html index.htm;
        server_name             localhost;
        auth_basic                "Restricted";
        auth_basic_user_file  /etc/nginx/.auth;

        if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
                return 403;   }

        if ($http_user_agent ~* msnbot|scrapbot) {
                return 403;   }

  # Pass all .php files onto a php-fpm/php-fcgi server.
  # Zero-day exploit defense. http://forum.nginx.org/read.php?2,88845,pag$
  # Won't work properly (404 error) if the file is not stored on this ser$
  # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on an$

        location ~ .php$ {
                try_files $uri =404;
                fastcgi_split_path_info  ^(.+.php)(/.+)$;
                include                        fastcgi_params;
                fastcgi_index               index.php;
                fastcgi_param             SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass                unix:/var/run/php-fpm/php-fpm.sock;
        }

        location ~ ^/RPC2$ {
                scgi_pass                  unix:/tmp/scgi.socket;
                include                      scgi_params;
                auth_basic                "Restricted";
                auth_basic_user_file  /etc/nginx/.auth;
        }

        location ~ ^/(?:share|conf) {
            deny all;
        }

        location ~ /.svn {
            deny all;
        }

        location ~ /.ht {
            deny all;
        }

        location  /  {
                # First attempt to serve request as file, then
                # as directory, then fall back to index.html
                try_files $uri $uri/ /index.html;
        }
}

Add authentication on nginx: After we have done all the configuration, now its time to secure the Web Server with password protected your document root. Remember I used /etc/nginx directory which contains my .auth file. You should use your home directory and edit the above configurations according to your .auth file location.

cd /etc/nginx/
wget http://trac.edgewall.org/export/10734/trunk/contrib/htpasswd.py
python htpasswd.py -c -b .auth <username> <password>
rm -rf htpasswd.py

Add a PHP file to your document root to test if PHP works. For instance do the following:

nano /var/www/test.php

Add these three lines in test.php:

<?php phpinfo(); ?>

Restart nginx and php5-fpm:

/etc/init.d/nginx restart && /etc/init.d/php5-fpm restart

Use your web browser and point it toward test.php, Example URL: 192.168.1.101/info.php By now, PHP should work. You should be able to see information regarding PHP/PHP Modules, etc in you browser.

Download and configure rutorrent:

You will need subversion to download latest built of rutorrent. Execute

apt-get install subversion
cd /var/www
svn co http://rutorrent.googlecode.com/svn/trunk/rutorrent

Now, edit the config.php

nano /var/www/rutorrent/conf/config.php

Give the scgi_port and scgi_host these values and it must look like this:

[..]
        $scgi_port = 0;
        $scgi_host = "unix:///tmp/scgi.socket";
[..]

Configuring Plugins:

You may need some plugins for enhancing rutorrent experience. Check the official website for rutorrent plugins:

http://code.google.com/p/rutorrent/wiki/Plugins

Here's what I do for plugins:

cd /var/www/rutorrent/
rm -rf plugins
svn co http://rutorrent.googlecode.com/svn/trunk/plugins/

This is not a good practice though but I do this and later delete the plugins I don't need. Common Errors regarding plugins: If this error occurs "Web-server user can't access 'stat' program. Some functionality will be unavailable". Follow these steps:

cd /var/www/rutorrent
ln -s /usr/bin/stat stat
nano /var/www/rutorrent/conf/config.php
## Scroll down and make the 'stat' line look like this ##
"stat"  => '/var/www/rutorrent/stat',

References:

Basic SCGI usage

Authentication usage

Useful configuration examples to secure /RPC2 mount point

One more useful page where you can find good examples of securing your files/directories on nginx

Also you can add some fastcgi parameters from this valuable post just in case you get random 503 errors

Thanks to this person for pointing out a huge wrong config which can be found in most guides

Also check this post for understanding deeply about this bad config

Nice comprehensive guide for securing nginx

Back to top