Setup a Mutli-User Seedbox on Ubuntu

As prices on VPSes and dedicated servers continue to drop, more and more people in the torrenting community are getting seedboxes. While there are many managed options out there, often the best deals are managing your own server. Setting up a seedbox is easier than ever before with how much info is freely available. All one really needs is the ability to reasonably navigate command line interface, Google, and patience. It also helps to get involved in a community that can help you (IRC or forum).

This is a guide to setup rtorrent with ruTorrent as a webui frontend on Ubuntu. It has been tested on 11.04 (Natty Narwhal) both Desktop and Server additions, and will be still compatible with all future versions of ubuntu. It can be easily adapted onto any distribution as well. We will also setup SSL (https), password protection using realms, and user host directories (so non-root users can host files), and I will include how to make this a multi-user setup.

SSH into your new box as root. If you need an SSH client, I would suggest KiTTY. It's a fork from PuTTY that adds very useful features like reconnect on wake-up and transparency (true transparency, not the fake copy your background stuff).

A few possibly not so obvious things for beginners. Lines that start with pound signs (#) are comments. If they appear in the midst of commands, don't actually paste them in the terminal, they are just instructions. However, paste them into the text documents as they are very helpful in the future. Last, make sure you replace things like <user> with the actual user name.

Let's begin. Start off by charging your password to something you can remember

passwd  

Now let's get the system up to date

apt-get update  
apt-get upgrade  

Install all the prerequisites and other useful programs

apt-get install fluxbox nmap makepasswd ccrypt vnstat sysstat xterm eterm vnc4server tightvncserver vnstat unrar-free thunar irssi irssi-scripts libcppunit-doc libcppunit-dev unzip zip php5-geoip curl libcurl3 php5-curl php5-cli apache2 apache2.2-common apache2-utils autoconf automake autotools-dev binutils build-essential bzip2 ca-certificates comerr-dev cpp cpp-4.5 dpkg-dev file g++ g++-4.5 gawk gcc gcc-4.5 libapache2-mod-php5 libapache2-mod-scgi libapr1 libaprutil1 libc6-dev libcurl3 libcurl4-openssl-dev libexpat1 libidn11 libidn11-dev libkrb5-dev libmagic1 libncurses5 libncurses5-dev libneon27 libpcre3 libpq5 libsigc++-2.0-dev libsqlite0 libsqlite3-0 libssl-dev libstdc++6-4.5-dev libsvn1 libtool libxml2 linux-libc-dev lynx m4 make mime-support nano ntp ntpdate openssl patch perl perl-modules php5 php5-cgi php5-common php5-sqlite php5-xmlrpc pkg-config screen sqlite ssl-cert subversion ucf zlib1g-dev libncursesw5-dev aptitude znc  

Lets setup Apache

a2enmod ssl  
a2enmod auth_digest  
a2enmod scgi

Open up /etc/apache2/apache2.conf and scroll to the bottom and add the following. You need an SCGIMount for each user. I like to make mine be /RPCBOB (instead of RPC2/3/4) if the username is bob instead of numbers so I can remember them. You do not need one for root.

# user1
SCGIMount /RPCUSER1 127.0.0.1:30000  
# user2
SCGIMount /RPCUSER2 127.0.0.1:30100  
# user3
SCGIMount /RPCUSER3 127.0.0.1:30200

servername localhost  

And restart it so it accepts the new changes:

/etc/init.d/apache2 restart  

Check Apache by putting "http://serverIP" into your browser

Setup Apache for SSL (HTTPS). The openssl command will ask you lots of questions about the certificate. Just put fake info in or leave everything default.

openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/apache.pem -keyout /etc/apache2/apache.pem  
chmod 600 /etc/apache2/apache.pem  
mv /etc/apache2/sites-available/default /etc/apache2/sites-available/default.old  

Now lets setup our virtual hosting by opening up /etc/apache2/sites-available/default

<VirtualHost *:80>  
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/
    <Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>old
    ErrorLog /var/log/apache2/error.log
    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn
    CustomLog /var/log/apache2/access.log combined
    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>
</VirtualHost>  
<VirtualHost *:443>  
    NameVirtualHost *:443
    ServerAdmin webmaster@localhost
    SSLEngine On
    SSLCertificateFile /etc/apache2/apache.pem
    DocumentRoot /var/www/
    <Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog /var/log/apache2/error.log
    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn
    CustomLog /var/log/apache2/access.log combined
    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>
</VirtualHost>  

Now restart Apache again:

/etc/init.d/apache2 restart

and verify SSL works by loading "https://serverIP" in your browser. You'll get a warning about the certificate which is fine. (Because it is self signed.

This is where I diverge from many as I like to use host folders for each individual user instead of just putting everything at /var/www/. There are many benefits to this. First, each user gets a separate copy of ruTorrent. This is a big deal as I’ve had users break their ruTorrents beyond recovery. If everyone is on the same ruTorrent, this causes a huge problem. Also, this way each user can also host files instead of only root. To setup individual user host directories just enable the module.

a2enmod userdir  

Now we create the apache configuration for the user's directories: vi /etc/apache2/conf.d/userdirs

UserDir www  
UserDir disabled root

<Directory /home/*/www/>  
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
</Directory>  

Well check that later once we have made the user account.

Now to compile xmlrpc, libtorrent, and rtorrent:

mkdir source  
cd source  
svn co https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced/ xmlrpc-c  
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.2.tar.gz  
wget http://libtorrent.rakshasa.no/downloads/rtorrent-0.9.2.tar.gz  
tar -xvzf libtorrent-0.13.2.tar.gz  
tar -xvzf rtorrent-0.9.2.tar.gz  
cd xmlrpc-c  
./configure --disable-cplusplus
make  
make install  
cd ../libtorrent-0.13.2  
./autogen.s
./configure
make  
make install  
cd ../rtorrent-0.9.2  
./autogen.sh
./configure --with-xmlrpc-c
make  
make install  
ldconfig  

Add your users:

adduser user1  
adduser user2  
adduser user3  

If you want any of your users to have root privileges (I'd definitely suggest you have your user account have sudo) do this:

vim /etc/sudoers  
# WARNING: You are basically giving them permission to destory your server at this point. Only give out sudo for those you trust!
# Find “root   ALL=(ALL:ALL) ALL” and put this right bellow it:
user1  ALL=(ALL:ALL) ALL  
user2  ALL=(ALL:ALL) ALL  

Now login to one of your new user and finish setting up the user host directories:

login –f user1  
mkdir www  
cd www  
echo "IT WORKS" > test.txt  

Now in your browser load https://IP/~user1. It should browse the ~/www directory which should have the test.txt we just made in it. Open it up. The problem here is we don’t actually want our user’s home directory browsable. To fix this:

wget http://i.imgur.com/lGnyZ.png  

Add the following to a new file index.html

<html>  
<head>  
<title>BADASS</title>  
</head>  
<body>  
<img src='lGnyZ.png'/>  
</body>  
</html>  

Load the same url again and have a laugh.

Now to get rtorrent finished up:

cd ~  
mkdir –p rtorrent/watch  
mkdir rtorrent/data  
mkdir rtorrent/work  
vi .rtorrent.rc

Make sure you replace the three with the actual username. Also make sure you change the toward the bottom to the correct SCGIMount port of the user.

~/.rtorrent.rc
# This is an example resource file for rTorrent. Copy to
# ~/.rtorrent.rc and enable/modify the options as needed. Remember to
# uncomment the options you wish to enable.
# Maximum and minimum number of peers to connect to per torrent.
min_peers = 40  
max_peers = 100

# Same as above but for seeding completed torrents (-1 = same as downloading)
min_peers_seed = 10  
max_peers_seed = 50

# Maximum number of simultanious uploads per torrent.
#max_uploads = 15
# Global upload and download rate in KiB. "0" for unlimited.
download_rate = 0  
upload_rate = 0

# Default directory to save the downloaded torrents.
# ----- CHANGE THIS LINE FOR DIFFERENT USERS -----
directory = /home/user1/rtorrent/data

# Default session directory. Make sure you don't run multiple instance
# of rtorrent using the same session directory. Perhaps using a
# relative path?
# ----- CHANGE THIS LINE FOR DIFFERENT USERS -----
session = /home/user1/rtorrent/work  
# Watch a directory for new torrents, and stop those that have been
# deleted.
# ----- CHANGE THIS LINE FOR DIFFERENT USERS -----
schedule = watch_directory,5,5,"load_start=/home/user1/rtorrent/watch/*.torrent"  
schedule = untied_directory,5,5,stop_untied=

# Close torrents when diskspace is low.
schedule = low_diskspace,5,60,close_low_diskspace=2024M

# Uncomment both this and bind if your server has multiple IPs.
#ip = 127.0.0.1
#ip = rakshasa.no

# The ip address the listening socket and outgoing connections is
# bound to.
#bind = 127.0.0.1
#bind = rakshasa.no
# Port range to use for listening.
port_range = 30001-30001  
# Start opening ports at a random position within the port range.
port_random = no  
# Check hash for finished torrents. Might be usefull until the bug is
# fixed that causes lack of diskspace not to be properly reported.
check_hash = no

# Set whetever the client should try to connect to UDP trackers.
#use_udp_trackers = yes

#Encryption
encryption = require,require_RC4,enable_retry.allow_incoming

#Disable DHT
dht = disable

# Enable peer exchange (for torrents not marked private)
peer_exchange = no

# Must modify in Apache to be effective (and remember to modify in ruTorrent config)
scgi_port = 127.0.0.1:<port>  
# Scheduling examples
#schedule = throttle_1,23:30:00,24:00:00,download_rate=450
#schedule = throttle_2,23:30:00,24:00:00,upload_rate=40
#schedule = throttle_3,08:00:00,24:00:00,download_rate=200
#schedule = throttle_4,08:00:00,24:00:00,upload_rate=20

Now to add some aliases to make things easier.

nano ~/.bashrc  
# Go to the bottom and add:
alias rstart='screen -dmS rtorrent rtorrent'  
alias rt='stty stop undef; stty start undef; screen -x rtorrent'  

To start rtorrent the first time, simply run rtorrent. Hopefully it will open up without errors. Assuming it does, close it by hitting CTRL + Q (For future reference, becareful not to do it twice. Doing it twice force quits rtorrent which can cause some problems. It may take some time to shutdown). From now on, we want to run rtorrent in screen (so that it runs in the background). To do this, run rstart. This will start rtorrent in a screen session detached in the background. To re-attach it, run rt. This should bring up rtorrent looking like it did the first time. To detach the screen and keep rtorrent running, press CTRL+A, release, then press D. If you ever forget what your aliases are, simply type alias to get a list.

To setup ruTorrent:

cd ~/www/  
svn checkout http://rutorrent.googlecode.com/svn/trunk/rutorrent  
cd rutorrent/plugins  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/autotools  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/cookies  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/data  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/datadir  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/diskspace  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/edit  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/erasedata  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/extsearch  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/feeds  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/geoip  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/ratio  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/_getdir  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/rpc  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/rss  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/scheduler  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/seedingtime  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/tracklabels  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/trafic  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/unpack  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/throttle  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/source  
svn checkout http://rutorrent-logoff.googlecode.com/svn/trunk/ logoff  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/_task  
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins/theme  
chmod -R 777 ~/www/rutorrent/share  
vi ~/www/rutorrent/conf/config.php  
# Set topDirectory to /home// 
# Set scgi_port to the correct port for that user
# Set XMLRPCMountPoint to the correct one (/RPC....)

To test it out, load https://IP/~user/rutorrent (keep the tilda ~). Hopefully it will load with no errors.
Now you and all your friends can use the seedbox to its full potential.
I suggest heading over to the Ubuntu site, and downloading the latest ISO just to see how fast it is. Who knows, I might end up connecting too you ;)