ArchLinux - Install rTorrent, Flood and SFTP

A complete tutorial for installing Flood alongside rTorrent, a hardenned Nginx reverse proxy, an SFTP configuration, with all those features using service accounts for a greater global security.

Install rTorrent#

As rTorrent package is always up-to-date on Arch repository, it's not needed to compile it.

# pacman -S rtorrent

Install Nginx#

# pacman -S nginx-mainline
  • Enable and start nginx:
# systemctl enable nginx.service
# systemctl start nginx.service

Configure Nginx#

  • Change the default conf:
# mkdir /etc/nginx/auth
# mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.default
# vim /etc/nginx/nginx.conf
  • And add this conf:
user http;
worker_processes auto;
# PID error: https://bugs.archlinux.org/task/46500
# pid /run/nginx.pid;
pcre_jit on;

events {
        worker_connections 1024;
        multi_accept on;
        use epoll;
}

http {
        charset UTF-8;

        ##
        # Basic Settings
        ##
        server_names_hash_bucket_size 128;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 4096;
        server_tokens off;
        # server_name_in_redirect off;
        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##
        gzip off;

        ##
        # Virtual Host Configs
        ##
        include /etc/nginx/servers-enabled/*;

        ##
        # Anti-DDoS
        ##
        #Requete maximun par ip
        limit_req_zone $binary_remote_addr zone=flood:10m rate=100r/s;
        limit_req zone=flood burst=100 nodelay;
        #Connexions maximum par ip
        limit_conn_zone $binary_remote_addr zone=ddos:10m;
        limit_conn ddos 100;
}
  • Create following directories:
# mkdir /etc/nginx/servers-available
# mkdir /etc/nginx/servers-enabled
  • Create the server domain config:
# vim /etc/nginx/servers-available/flood.conf
  • And add the conf:
server {
 listen 80;
 listen [::]:80;
 server_name seedbox2.myowncloud.cf;
 # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
 return 301 https://$server_name$request_uri; # $server_name is server side so more secure than $host that can be modified in http header
}

##
# BLOCK SERVEUR HTTPS
##
server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 server_name seedbox.domain.example.org;

##
# SSL
##
 ssl_certificate /etc/nginx/ssl/flood.crt;
 ssl_certificate_key /etc/nginx/ssl/flood.key;
 ssl_protocols TLSv1.3;
 ssl_prefer_server_ciphers on;
 #ssl_ciphers TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256;
 ssl_ecdh_curve secp384r1;
 # ssl optimizations
 ssl_session_timeout 5m;
 ssl_session_cache shared:SSL:20m;
 ssl_session_tickets off;

##
# OTHER
##
 resolver 1.1.1.1 1.0.0.1 valid=300s;
 resolver_timeout 5s;

##
# SECURITY
##
 add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
 add_header X-Frame-Options DENY;
 add_header X-Content-Type-Options nosniff;
 add_header X-XSS-Protection "1; mode=block";

 # flood
 location / {
  proxy_pass http://127.0.0.1:3000;
  rewrite ^/(.*) /$1 break;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_cache_bypass $http_upgrade;
 }

 # Transdroid / Transdrone
 location /RPC2 {
  auth_basic "Restricted area";
  auth_basic_user_file /etc/nginx/auth/seedbox_auth;
  scgi_pass 127.0.0.1:5000;
  include scgi_params;
 }

}
  • Don't forget to change server_name seedbox.domain.example.org; with your own domain and create a CNAME entry in your DNS configuration.
  • Enable the server:
# ln -s /etc/nginx/servers-available/flood.conf /etc/nginx/servers-enabled/flood.conf

Configure SSL#

Self-signed#

  • Add certificate folder:
# mkdir /etc/nginx/ssl
  • Generate self-signed certificate:
# cd /etc/nginx/ssl
# openssl ecparam -genkey -name secp384r1 -out seedbox.key
# openssl req -new -key seedbox.key -sha256 -out seedbox.csr
# openssl req -x509 -days 3650 -sha256 -key seedbox.key -in seedbox.csr -out seedbox.crt
  • Modify files rights:
# chmod 644 /etc/nginx/ssl/*.crt
# chmod 640 /etc/nginx/ssl/*.key

Add an user#

  • Create an user:
# useradd --shell /bin/bash --create-home sdbox
# passwd sdbox
  • Create needed folder for rtorrent:
# mkdir -p /home/sdbox/{torrents,watch,.session}
  • Create rtorrent config file:
# vim /home/sdbox/.rtorrent.rc
  • Paste the config:
network.scgi.open_port = 127.0.0.1:5000
encoding.add = UTF-8
network.port_range.set = 45000-65000
network.port_random.set = no
pieces.hash.on_completion.set = no
directory.default.set = /home/sdbox/torrents
session.path.set = /home/sdbox/.session
protocol.encryption.set = allow_incoming, try_outgoing, enable_retry
trackers.use_udp.set = yes
dht.mode.set = off
protocol.pex.set = no
throttle.min_peers.normal.set = 40
throttle.max_peers.normal.set = 150
throttle.min_peers.seed.set = 10
throttle.max_peers.seed.set = 70
throttle.max_uploads.set = 40
  • Give user permissions:
# chown --recursive sdbox:sdbox /home/sdbox
# chown root:root /home/sdbox
# chmod 755 /home/sdbox
  • In order to do not install apache-tools, manually generate the auth file for sdbox user (it will write over the file and don't forget to change the password in the command):
$ echo -n "sdbox:" | sudo tee /etc/nginx/auth/seedbox_auth && openssl passwd -apr1 password | sudo tee -a /etc/nginx/auth/seedbox_auth
  • Protect the authentification file:
# chmod 600 /etc/nginx/auth/seedbox_auth
# chown http:http /etc/nginx/auth/*

Create a rTorrent service#

  • Create the file /etc/systemd/system/rtorrent.service (because /etc/systemd/user/ doesn't work) containing:
[Unit]
Description=rTorrent Daemon
After=network.target

[Service]
Type=simple
User=sdbox
ExecStart=/usr/bin/rtorrent -o system.daemon.set=true
WorkingDirectory=%h
Restart=on-failure

[Install]
WantedBy=multi-user.target
  • Install tmux if not yet installed to start rtorrent manually in tmux if the service file is not working:
# pacman -S --needed tmux
  • Enable rtorrent at boot time and manually start it:
$ systemctl enable rtorrent
$ systemctl start rtorrent

Install optional tools#

pacman -S mediainfo unrar

Install flood#

Pre-Requisites#

You can install nodejs and npm globally with pacman -S nodejs npm or use nodenv.

Install dependencies of node-gyp: pacman -S python2 make gcc.

System preparation#

  • Create a flood user:
# useradd -m flood -s /bin/zsh
# passwd flood
  • Install flood in /srv/flood and connect as flood user:
# cd /srv
# git clone https://github.com/jfurrow/flood.git flood
# chown -R flood:flood /srv/flood
# cd /srv/flood
# su flood
  • Install nodenv (still as flood user)
    • sudo pacman -S gcc make
    • git clone https://github.com/nodenv/nodenv.git ~/.nodenv
    • $ cd ~/.nodenv && src/configure && make -C src
    • echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.zshrc
    • ~/.nodenv/bin/nodenv init
    • echo 'eval "$(nodenv init -)"' >> ~/.zshrc
    • source ~/.zshrc
    • curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
  • Install node-build
    • mkdir -p "$(nodenv root)"/plugins
    • git clone https://github.com/nodenv/node-build.git "$(nodenv root)"/plugins/node-build
  • Install a node version: nodenv install 10.15.3
  • Set this version for the flood folder
    • cd /srv/flood/
    • nodenv local 10.15.3

Configuration#

Copy the config file:

$ cp config.template.js config.js

Then edit the file and comment the line with floodServerProxy and generate a very long and random secret for secret.

Compiling assets#

  • npm i: install dependencies
  • npm run build: compile assets

Service#

Create /etc/systemd/system/flood.service:

[Unit]
Description=Flood, web interface for rTorrent
After=network.target

[Service]
User=flood
ExecStart=/home/flood/.nodenv/bin/nodenv exec npm start /srv/flood
WorkingDirectory=/srv/flood/
Restart=on-failure

[Install]
WantedBy=multi-user.target

Start flood#

# systemctl start flood.service

Configure SFTP#

Requirement#

All previous steps are working and a SSH server is already installed, configured and working.

SFTP setup#

  • Create an user:
# useradd --create-home sftpuser
# passwd sftpuser
  • Modify the sshd config (/etc/ssh/sshd_config) and add these lines at the end:
# Need to be at the end
Match User sftpuser
        ChrootDirectory %h
        ForceCommand internal-sftp
        AllowTcpForwarding no
        PermitTunnel no
        X11Forwarding no
        AllowTcpForwarding no
        PermitTTY no
  • Restart the sshd server:
# systemctl restart sshd.service
  • Change chroot directory rights, this is required or sftp won't let you connect. The home directory must be owned by root and not writable by another user or group. This includes the path leading to the directory.
# chown root:root /home/sftpuser
# chmod 755 /home/sftpuser
  • You won't be able to connect in sftp if your user has /usr/bin/nologin shell as it's not defined in the /etc/shells. To disable normal ssh login, add /usr/bin/nologin in /etc/shells and change sdbox shell:
# usermod -s /usr/bin/nologin sftpuser
  • Test ssh access: (access should be refused if /usr/bin/nologin is used or PermitTTY no is set in sshd configuration)
# ssh sftpuser@localhost -p $SSH_PORT$
  • Test sftp access: (sftp user should be placed in the chroot environment)
# sftp -P $SSH_PORT$ sftpuser@localhost
  • Create the torrent folder to let sftp user access to sdbox download folder:
# mkdir /home/sftpuser/torrents
  • Give the torrent folder the appropriate rights:
# chown sftpuser:sftpuser /home/sftpuser/torrents

As sftpuser will be chrooted in his home directory (/home/sftpuser/) he won't be able to access /home/sdbox/torrents/ and a symbolic link like ln -s /home/sdbox/torrents /home/sftpuser/torrents won't work because it is outside the chroot environment. For sftpuser accessing via sftp to the chroot environment, /home/sftpuser/ will be the root directory / so the symbolic link to /home/sdbox/torrents will in fact be wrong as /home/sftpuser/home/sdbox/torrents doesn't exist.

We can't directly chroot sftpuser in /home/sdbox/torrents because that will require to change the /home/sdbox/torrents folder ownership to root:root and so sdbox user won't be able to access it anymore.

We must chroot sftp user because letting him access to the whole system would be a security issue.

So we will give sftp user two home directory: one SFTP home that is locked down by root (/home/sftpuser/) and one home he can write to (/home/sftpuser/torrents/) so sshd will be satisfied and the system will remain secure. To do that, we will make the sdbox folder (the writable home directory) appear as a subdirectory inside the SFTP home directory:

# mount --bind /home/sdbox/torrents /home/sftpuser/torrents

We can also add this into /etc/fstab to make this configuration permanent even after a reboot:

# echo '/home/sdbox/torrents /home/sftpuser/torrents none bind' >> /etc/fstab

SFTP user is now ready to access the sdbox download folder via SFTP.

Thanks to the great ArchLinux wiki.

Share