Многопользовательская торрент-качалка на transmission

Хочу рассказать о том, как реализовать торрент-демон с разделением по пользователям. В качестве торрент-клиента будет использован transmission-daemon.
Торрент-демон — это программа(сервис), которая выступает в качестве торрент-клиента(качалки) и как правило используется на всяких HTPC, NAS, роутерах и т.п. что бы качать/раздавать торренты не на основном ПК/ноутбуке, а на устройстве, которое всегда включено/онлайн.

Введение, для тех, кто не знаком с тем, что такое transmission-daemon


Одним из распространенных торрент-демонов является transmission-daemon. Для него есть множество GUI-клиентов для разных платформ, которые работают по http и могут подключаться к качалке удаленно, что очень удобно. Использование такого клиента для пользователя не будет отличатся от обычных торрент-клиентов, при этом если клиент закрыть, скачивание/раздача не прекращается, а продолжается на удаленной машине-сервере. Так же у transmission-daemon есть свой «стандартный» web-интерфейс.

Проблема:


И все было бы хорошо, но transmission-daemon хоть и предусматривает авторизацию, но только для одного пользователя. Поэтому если Вы захотите, что бы вашей торрент-качалкой пользовался кто-то еще кроме Вас, то прийдется делить один аккаунт — вы оба сможете просматривать и управлять закачками друг друга, что не очень удобно.

Способ решения


Самым очевидным простым и элегантным, на мой взгляд, решением является запуск transnmission одновременно от разных пользователей. В данном случае в качестве ОС применяется Ubuntu Server 12.10, поэтому можно создать отдельный Upstart User Job для каждого пользователя. Для других дистрибутивов вместо этого можно просто создать init.d скрипты.

Решение


Подготовим систему:

установим transmission-daemon:
sudo apt-get install transmission-daemon
Разрешим выполнение пользовательских демонов или User Jobs, для этого нужно заменить файл "/etc/dbus-1/system.d/Upstart.conf", предварительно сделав бекап старого.
sudo mv /etc/dbus-1/system.d/Upstart.conf /etc/dbus-1/system.d/Upstart.conf.save
новый файл /etc/dbus-1/system.d/Upstart.conf:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE busconfig PUBLIC
  "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">

<busconfig>
  <!-- Only the root user can own the Upstart name -->
  <policy user="root">
    <allow own="com.ubuntu.Upstart" />
  </policy>

  <!-- Allow any user to invoke all of the methods on Upstart, its jobs
       or their instances, and to get and set properties - since Upstart
       isolates commands by user. -->
  <policy context="default">
    <allow send_destination="com.ubuntu.Upstart"
	   send_interface="org.freedesktop.DBus.Introspectable" />
    <allow send_destination="com.ubuntu.Upstart"
	   send_interface="org.freedesktop.DBus.Properties" />
    <allow send_destination="com.ubuntu.Upstart"
	   send_interface="com.ubuntu.Upstart0_6" />
    <allow send_destination="com.ubuntu.Upstart"
	   send_interface="com.ubuntu.Upstart0_6.Job" />
    <allow send_destination="com.ubuntu.Upstart"
	   send_interface="com.ubuntu.Upstart0_6.Instance" />
  </policy>
</busconfig>

Дальше стоит выключить стандартный demon, который запускается от рута при старте системы:

sudo sh -c 'echo "manual" > /etc/init/transmission-daemon.override'
sudo service transmission-daemon stop


Настройка конкретного пользователя:

создаем Upstart User Job

Логинимся под очередным юзером, который будет использовать transmission-daemon и выполняем скрипт:
mkdir $HOME/.init

cat <<End-of-list  > $HOME/.init/transmissiond-$USER.conf
start on $USER-logged-in
stop on runlevel [!2345]

kill timeout 30

respawn

setuid $USER
env HOME=$HOME

pre-start script
  # stop job from continuing if no config file found for daemon
  [ ! -f \$HOME/.transmissiond/transmission-daemon ] && { stop; exit 0; }
  
  # source the config file
  . \$HOME/.transmissiond/transmission-daemon

  # stop job from continuing if admin has not enabled service in
  # config file.
  [ "\$ENABLE_DAEMON" != 0 ] || { stop; exit 0; }
end script

script

  . \$HOME/.transmissiond/transmission-daemon
  exec /usr/bin/transmission-daemon -f \$OPTIONS
end script

End-of-list

Скрипт создаст файл ~/.init/transmissiond-$USER.conf с необходимыми настройками пользовательского демона.
Поле на которое стоит обратить внимание — это "start". В данном случае Job будет стартовать только в случае, если пользователь залогинился в систему, что вовсе не обязательно. Однако, если установлено шифрование домашнего каталога — необходимо, иначе некуда будет сохранять скачанное. Если директория скачивания доступна и до логина пользователя, то "start on $USER-logged-in" можно заменить на "start on runlevel [2345]". В таком случае, однако, Job не нужно делать пользовательским, а можно расположить в /etc/init/

Настраиваем env user-demona:
cat <<End-of-text > $HOME/.transmissiond/transmission-daemon
ENABLE_DAEMON=1
CONFIG_DIR="$HOME/.transmissiond"
OPTIONS="--config-dir \$CONFIG_DIR"
End-of-text


Создаем файл настроек торрент-клиента

Не забудьте заменить pass="*****" на свой пароль. После первого запуска transmission сам скроет пароль хешем — в открытом виде не хранит.
uid=`id -u`
pass="*****" #здесь забиваем пароль пользователя

cat <<End-of-list > $HOME/.transmissiond/settings.json
{
    "alt-speed-down": 100, 
    "alt-speed-enabled": false, 
    "alt-speed-time-begin": 540, 
    "alt-speed-time-day": 127, 
    "alt-speed-time-enabled": false, 
    "alt-speed-time-end": 1020, 
    "alt-speed-up": 100, 
    "bind-address-ipv4": "0.0.0.0", 
    "bind-address-ipv6": "::", 
    "blocklist-enabled": false, 
    "blocklist-url": "http://www.example.com/blocklist", 
    "cache-size-mb": 32, 
    "dht-enabled": true, 
    
    "download-limit": 100, 
    "download-limit-enabled": 0, 
    "download-queue-enabled": true, 
    "download-queue-size": 5, 
    "encryption": 1, 
    "idle-seeding-limit": 30, 
    "idle-seeding-limit-enabled": false, 

    "incomplete-dir-enabled": true, 
    "lpd-enabled": false, 
    "max-peers-global": 200, 
    "message-level": 2, 
    "peer-congestion-algorithm": "", 
    "peer-limit-global": 240, 
    "peer-limit-per-torrent": 60, 
    
    "peer-port-random-high": 65535, 
    "peer-port-random-low": 49152, 
    "peer-port-random-on-start": false, 
    "peer-socket-tos": "default", 
    "pex-enabled": true, 
    "port-forwarding-enabled": true, 
    "preallocation": 1, 
    "prefetch-enabled": 1, 
    "queue-stalled-enabled": true, 
    "queue-stalled-minutes": 30, 
    "ratio-limit": 2, 
    "ratio-limit-enabled": false, 
    "rename-partial-files": true, 
    "rpc-authentication-required": true, 
    "rpc-bind-address": "0.0.0.0", 
    
    "rpc-enabled": true, 
    "rpc-url": "/transmission/", 
    
    "rpc-whitelist": "127.0.0.1", 
    "rpc-whitelist-enabled": false, 
    "scrape-paused-torrents-enabled": true, 
    "script-torrent-done-enabled": false, 
    "script-torrent-done-filename": "", 
    "seed-queue-enabled": false, 
    "seed-queue-size": 10, 
    "speed-limit-down": 256, 
    "speed-limit-down-enabled": false, 
    "speed-limit-up": 256, 
    "speed-limit-up-enabled": false, 
    "start-added-torrents": true, 
    "trash-original-torrent-files": false, 
    "umask": 18, 
    "upload-limit": 100, 
    "upload-limit-enabled": 0, 
    "upload-slots-per-torrent": 14, 
    "utp-enabled": true,

    "download-dir": "$HOME/downloads", 
    "incomplete-dir": "$HOME/downloads/incomplete", 
    "peer-port": $((51413 + $uid - 1000)), 
    "rpc-username": "$USER", 
    "rpc-password": "$pass", 
    "rpc-port": $((9091 + $uid - 1000)) 
}
End-of-list

Каждый торрент-демон будет висеть на своем отдельном порте, как для входящих торрент-соединений, так и для управления-интерфейса. Номер порта (веб интерфейс) конкретного пользователя вычисляется по формуле rpc-port = 9091 + $uid - 1000 Таким образом пользователь с uid 1000 сможет зайти на веб-интерфейс по server:9091, а пользователь с uid 1010 — по server:9101. peer-port вычисляется аналогично.
Все недокачанные торренты будут лежать в ~/downloads/incomplete, а готовые — в ~/downloads.

В том случае, если используется, шифрование домашней директории пользователя, нужно что бы демон стартовал только когда пользователь залогинен, поэтому добавляем в конце .bashrc соответсвующий ивент, что бы Upstart знал, что пора запускать transmission:
    echo "# start user specific daemons" >> "$HOME/.bashrc"
    echo "initctl emit $USER-logged-in" >> "$HOME/.bashrc"

и еще, наверное, желательно что бы если юзер сделал логаут — демон продолжал крутиться:
mv "$HOME/.ecryptfs/auto-umount" "$HOME/.ecryptfs/_auto-umount"

По желанию можно также сделать проксирование через nginx/apache что бы разные пользователи могли заходить на интерфейс через разные домены, например.

Заключение


Каждый пользователь, с которым проделаны манипуляции из «Настройка конкретного пользователя», может пользоваться своим собственным transmission-daemon, не мешая другим и не перемешивая скачанное. Если объединить это с ftp/samba/..., то пользователи смогут и забирать скачанные файлы.
Манипуляции можно засунуть в скрипт и тогда достаточно будет для каждого нового пользователя выполнить одну команду и все — можно пользоваться.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 17

    +1
    Для такой затеи категорически необходим шейпер, который бы делил канал.
      0
      Да, согласен. Еще не помешал бы интерфейс для логина пользователей (вариант с шифрованным домашним каталогом). Возможно, рассмотрю отдельно.
      +1
      Unix-way в правильной обертке.
      Но для такой затеи хочется, что бы разделение пользователей проводилось самим демоном и он рулил скоростью между пользовательскими закачками.

      Вы сами пользуетесь таким решением? Могли бы описать, есть ли проблемы с делением канала между экземплярами transmission?
        0
        Пользуюсь. Проблем нет, т.к. пользователей мало (2.5 :) ), а канал — честные 100 Мбит. Дальше пользователей будет больше и шейпер действительно нужен. Реализовывать разделение по пользователям средствами самого демона, на сколько мне известно, разработчики не планируют.
        0
        lxc(или openvz)-виртуалку каждому юзеру под торренты, всего и делов, шейпить тогда вообще не составит труда.
          0
          хотя можно поступить проще,
          -i --bind-address-ipv4 Where to listen for peer connections
          вешать на отдельный айпи-адрес трансмишн каждого пользуна. и уже исходя из этого правила для шейпера писать.
          • UFO just landed and posted this here
              0
              я предлагал контейнерную виртуализацию, там не сильно критично по процу. скорее надо посчитать сколько дисков надо чтобы 50 человек не просаживали i/o на рейде.
            0
            А на FreeBSD подобное не запустить? Там с шейпингом проблем бы не было вообще.
              0
              transmission-daemon для freebsd есть, так что проблем быть не должно.
              0
              Так делать нельзя. Даже один торрент-демон, дай ему волю, порвет и канал и диски. А вы их собираетесь запускать несколько и они знать не будут друг о друге. Как разные трекеры будут на одном айпи считать рейтинг? Как коннектиться? Не, это не решение. :(
                0
                Так у каждого экземпляра же будет свой клиентский порт. Да и не забывайте про нат, когда на трекере с одного айпи сидят 10 человек, но у них разные порты.
                  0
                  Трекеры рейтинг не по айпи, а по passkey учитывают, тут проблем как раз никаких нет. Как верно заметил BupycNet, у всех свои порты. Конектиктся тоже по разным портам. Я для удобства конекта сделал nginx прокси — у каждого юзера свой поддомен.
                  Лучшего решения для разделения пользователей transmission-daemon на данный момент нет, к сожалению. Поэтому да, нужно настраивать шейпер. На мой взгляд, если настроить шейпер, то решение вполне элегантное.
                  0
                  Я бы запускал один демон, но по отдельному каталогу для пользователя — куда ложить торент файл, и откуда забирать результат.
                  Использовал такой подход для rtorrent на роутере, для разделения фильмы/сериалы/музыка/… по отдельным каталогам, но одим пользователем.
                    0
                    В transmission это затруднительно реализовать. К тому же проблема остается с тем, что юзеры видят и могут влиять друг на друга.
                    0
                    Многопользовательськая? OK.
                      0
                      Орфография… А если по смыслу, то да, пользователей больше одного :)

                    Only users with full accounts can post comments. Log in, please.