Slowbro used tail whip, Your defences were lowered

HowTo: Setup a Multi-User Ubuntu Seedbox.

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. 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. Don’t actually put the dashes “———-” in the text files when you’re editing them. I just used them to denote where the code you’re putting into the files starts and ends. Also, 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 (but not easy… someone hacks your root and you’re screwed).

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


Setup Apache (anything between the dashes goes in the text file the line above opened)

a2enmod ssl
a2enmod auth_digest
a2enmod scgi
nano /etc/apache2/apache2.conf
# Scroll to the bottom and add this.  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 /RPC2 127.0.0.1:30000
# user2
SCGIMount /RPC3 127.0.0.1:30100
# user2
SCGIMount /RPC4 127.0.0.1:30200 

servername localhost
---------------------------------------------------------------
/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
nano /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:

/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.

This is where I diverge from many is 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:

a2enmod userdir
nano /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:

nano /etc/sudoers

Find “root   ALL=(ALL:ALL) ALL” and put this right bellow it:
<user1>  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
nano 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
nano .rtorrent.rc
# Make sure you replace the three <user> with the actual username. Also make sure
# you change the <port> toward the bottom to the correct SCGIMount port of the user.
---------------------------------------------------------------------------
# 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.
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?
session = /home/user1/rtorrent/work
# Watch a directory for new torrents, and stop those that have been
# deleted.
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
# The ip address reported to the tracker.
# 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
# Alternative calls to bind and ip that should handle dynamic ip's.
#schedule = ip_tick,0,1800,ip=rakshasa
#schedule = bind_tick,0,1800,bind=rakshasa
# Encryption options, set to none (default) or any combination of the following:
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
#
# The example value allows incoming encrypted connections, starts unencrypted
# outgoing connections but retries with encryption if they fail, preferring
# plaintext to RC4 encryption after the encrypted handshake
#
encryption = allow_incoming,try_outgoing,enable_retry,prefer_plaintext
# Enable DHT support for trackerless torrents or when all trackers are down.
# May be set to "disable" (completely disable DHT), "off" (do not start DHT),
# "auto" (start and stop DHT as needed), or "on" (start DHT immediately).
# The default is "off". For DHT to work, a session directory must be defined.
#
dht = disable
# UDP port to use for DHT.
#
# dht_port = 6881
# Enable peer exchange (for torrents not marked private)
#
peer_exchange = no
#
# Do not modify the following parameters unless you know what you're doing.
#
# Hash read-ahead controls how many MB to request the kernel to read
# ahead. If the value is too low the disk may not be fully utilized,
# while if too high the kernel might not be able to keep the read
# pages in memory thus end up trashing.
#hash_read_ahead = 10
# Interval between attempts to check the hash, in milliseconds.
#hash_interval = 100
# Number of attempts to check the hash while using the mincore status,
# before forcing. Overworked systems might need lower values to get a
# decent hash checking rate.
#hash_max_tries = 10
# 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
nano ~/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.