..
  Copyright (C)  2023  Jeremie Salvi.
  Permission is granted to copy, distribute and/or modify this document
  under the terms of the GNU Free Documentation License, Version 1.3
  or any later version published by the Free Software Foundation;
  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
  A copy of the license is included in the section entitled "GNU
  Free Documentation License".

Installation de ruTorrent
=========================

Prérequis
---------

Pour l'installation de ruTorrent, il faut au minimum avoid les paquets suivants s'installés :

- apache 2.4.x
- rtorrent 0.9.7
- libtorrent 0.13.7
- ruTorrent 3.10

Installation de rtorrent
------------------------

Créer un home directory :

.. code-block:: bash

  mkdir /data/rtorrent
  cd /data/rtorrent

Configurer rtorrent avec le script du développeur : `<https://github.com/rakshasa/rtorrent/wiki/CONFIG-Template>`_

.. code-block:: bash

  curl -Ls "https://raw.githubusercontent.com/wiki/rakshasa/rtorrent/CONFIG-Template.md" \
    | sed -ne "/^######/,/^### END/p" \
    | sed -re "s:/home/USERNAME:$HOME:" > ./.rtorrent.rc

Éditer la config :

.. code-block:: bash

  ## On modifie les chemins
  method.insert = cfg.basedir,  private|const|string, (cat,"/data/rtorrent/")
  method.insert = cfg.watch,    private|const|string, (cat,(cfg.basedir),"torrent/")
  ...
  ## Commenter les lignes suivantes
  #execute.throw = sh, -c, (cat,\
  #    "mkdir -p \"",(cfg.download),"\" ",\
  #    "\"",(cfg.logs),"\" ",\
  #    "\"",(cfg.session),"\" ",\
  #    "\"",(cfg.watch),"/load\" ",\
  #    "\"",(cfg.watch),"/start\" ")
  ...
  ## Maxer l'utilisation de la ram
  pieces.memory.max.set = 1000M
  ...
  ## Loguer les connexions RPC
  log.xmlrpc = (cat, (cfg.logs), "xmlrpc.log")
  ...
  ## Umask pour du 755/644
  system.umask.set = 0022
  ...
  ## On démarre le téléchargement pour tout les torrents déposés dans le dossier
  ## Add torrent
  #schedule2 = watch_load, 11, 10, ((load.verbose, (cat, (cfg.watch), "*.torrent")))
  ## Add & download straight away
  schedule2 = watch_start, 10, 10, ((load.start_verbose, (cat, (cfg.watch), "*.torrent")))
  ...
  ## On lance le socket unix pour la communication avec ruTorrent, en 777 pour qu apache puisse s'y connecter
  #system.daemon.set = true
  network.scgi.open_local = (cat,(session.path),rpc.socket)
  execute.nothrow = chmod,777,(cat,(session.path),rpc.socket)

Créer les répertoires :

.. code-block:: bash

  mkdir {download,log,.session,torrent}

Ajouter un utilisateur rtorrent :

.. code-block:: bash

  adduser --disabled-login --disabled-password --home /data/rtorrent/ --system rtorrent

Affecter les bons droits :

.. code-block:: bash

  chown -R rtorrent:www-data /data/rtorrent/

Lancer rtorrent pour tester la config :

.. code-block:: bash

  sudo -u rtorrent rtorrent

Configuration d'apache
----------------------

On créer le vhost ``/etc/apache2/sites-available/rutorrent.conf`` :

.. code-block:: Apacheconf

  <VirtualHost 192.168.1.100:8083>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    <Directory /var/www/html/>
      Options Indexes Includes FollowSymLinks MultiViews
      AllowOverride all
      Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
  </VirtualHost>

On ouvre le port dans ``/etc/apache2/ports.conf`` :

.. code-block:: Apacheconf

  Listen 8083

On charge la configuration et on redémarre apache :

.. code-block:: bash

  a2ensite rutorrent.conf
  systemctl restart apache2

Installation de ruTorrent
-------------------------

On trouve la dernière version stable `ici <https://github.com/Novik/ruTorrent/releases>`_ :

.. code-block:: bash

  cd /var/wwww
  wget https://github.com/Novik/ruTorrent/archive/v3.10.zip
  unzip v3.10.zip
  mv ruTorrent-3.10/ html
  rm v3.10.zip
  chown -R www-data:www-data html

On modifie la configuration de rutorrent : ``conf/config.php`` :

.. code-block:: bash

  // On commente le chemin socket ip, et on file le soket unix
  //$scgi_port = 5000;
  //$scgi_host = "127.0.0.1";

  // For web->rtorrent link through unix domain socket 
  // (scgi_local in rtorrent conf file), change variables 
  // above to something like this:
  //
  $scgi_port = 0;
  $scgi_host = "unix:///data/rtorrnet/.session/rpc.socket";

Améliorations
-------------

  Si on veut mettre des limites de connection, on rajoute au ``.rtorrent.rc`` :

.. code-block:: bash

  # Global upload and download rate in KiB.
  # "0" for unlimited
  throttle.global_down.max_rate.set_kb = 1000
  throttle.global_up.max_rate.set_kb = 1000

Si on veut que rtorrent arrête le téléchargement en cas d'espace disque faible :

.. code-block:: bash

  # Close torrents when disk-space is low. 
  schedule2 = low_diskspace,5,60,close_low_diskspace=5000M

Si on veut que le plugin mediainfo fonctionne :

.. code-block:: bash

  apt install mediainfo

Si on veut que le plugin spectrogram fonctionne :

.. code-block:: bash

  aptitude install sox

Si on veut que le pluggin unpack marche :

.. code-block:: bash

  apt install unrar

Pour optimiser les downloads avec peu de seed :

.. code-block:: bash

  ## Tracker-less torrent and UDP tracker support
  ## (conservative settings for 'private' trackers, change for 'public')
  dht.mode.set = on
  # port for DTH (default 6881)
  #dht.port.set = 6881
  # Use peer exchange
  protocol.pex.set = yes
  # DTH use udp by default
  trackers.use_udp.set = yes

Pour avoir le pays des peers, il faut installer GeoIP :

.. code-block:: bash

  apt install php-geoip geoip-database
  systemctl restart apache2.service
  systemctl restart php7.3-fpm.service

Iptables
--------

On Ajoute les règles suivantes dans notre firewall :

.. code-block:: bash

  ip6tables -A INPUT -i enp1s0 -p tcp --dport 50000 -j ACCEPT
  ip6tables -A INPUT -i enp1s0 -p udp --dport 6881 -j ACCEPT
  iptables -A INPUT -i enp1s0 -p tcp --dport 50000 -j ACCEPT
  iptables -A INPUT -i enp1s0 -p udp --dport 6881 -j ACCEPT

Script de gestion
-----------------

Si on ne veut pas que rtorrent se lance automatiquement au démarrage via systemd,
on peut faire un script tout simple qui démarre rtorrent en mode daemon
et configure les règles iptables. 

.. important:: Pour cela, il faut d'abord aller dans ``/data/rtorrent/.rtorrent.rc`` et modifier le paramètre : ``system.daemon.set = true``

Voici le script qui permet de démarrer ou arrêter rtorrent. 

.. warning:: Attention, rtorrent met du temps à s'arrêter, il à beaucoup de connections à fermer.

.. code-block:: bash

  #!/bin/bash

  function start {
    ps -elf | grep /usr/bin/rtorrent | grep -v "sudo\|grep"
    if (( $? == 0 )); then
      printf "rtorrent alerady started\n"
      exit 1
    fi
    printf "starting rtorrent...\n"
    sudo -u rtorrent nohup /usr/bin/rtorrent &
    ip6tables -A INPUT -i enp1s0 -p tcp --dport 50000 -j ACCEPT
    ip6tables -A INPUT -i enp1s0 -p udp --dport 6881 -j ACCEPT
    iptables -A INPUT -i enp1s0 -p tcp --dport 50000 -j ACCEPT
    iptables -A INPUT -i enp1s0 -p udp --dport 6881 -j ACCEPT
  }

  function stop {
    ps -elf | grep /usr/bin/rtorrent | grep -v "sudo\|grep"
    if (( $? == 1 )); then
      printf "rtorrent alerady stoped\n"
      exit 1
    fi
    printf "stoping rtorrent...\n"
    kill $(cat /data/rtorrent/.session/rtorrent.pid)
    ip6tables -D INPUT -i enp1s0 -p tcp --dport 50000 -j ACCEPT
    ip6tables -D INPUT -i enp1s0 -p udp --dport 6881 -j ACCEPT
    iptables -D INPUT -i enp1s0 -p tcp --dport 50000 -j ACCEPT
    iptables -D INPUT -i enp1s0 -p udp --dport 6881 -j ACCEPT
  }

  function usage {
  cat <<EOF
  rtorrent.sh

    start or stop rtorrent

  -h --help     : Print this help
  -s --start    : Start rtorrent
  --stop        : Stop rtorrent
  EOF
    exit 0
  }

  ##################
  # MAIN
  ##################

  if [[ -z $1 ]]; then
    usage
    exit 1
  fi

  options=$(getopt -o sh -l start,stop,help -- "$@")
  if [ $? != 0 ]
  then
    usage
    exit 1
  fi
  eval set -- "$options"
  while true; do
    case "$1" in
      -s|--start)
        start
        break
        ;;
      --stop)
        stop
        break
        ;;
      -h|--help)
        usage
        ;;
      *)
        usage
        shift
        break
        ;;
    esac
    shift
  done
  exit 0;