Хочу рассказать о том, как реализовать торрент-демон с разделением по пользователям. В качестве торрент-клиента будет использован transmission-daemon.
Торрент-демон — это программа(сервис), которая выступает в качестве торрент-клиента(качалки) и как правило используется на всяких HTPC, NAS, роутерах и т.п. что бы качать/раздавать торренты не на основном ПК/ноутбуке, а на устройстве, которое всегда включено/онлайн.
Введение, для тех, кто не знаком с тем, что такое transmission-daemon
Одним из распространенных торрент-демонов является transmission-daemon. Для него есть множество GUI-клиентов для разных платформ, которые работают по http и могут подключаться к качалке удаленно, что очень удобно. Использование такого клиента для пользователя не будет отличатся от обычных торрент-клиентов, при этом если клиент закрыть, скачивание/раздача не прекращается, а продолжается на удаленной машине-сервере. Так же у transmission-daemon есть свой «стандартный» web-интерфейс.
Проблема:
И все было бы хорошо, но transmission-daemon, хоть и предусматривает авторизацию, но только для одного пользователя. Поэтому если Вы захотите, что бы вашей торрент-качалкой пользовался кто-то еще кроме Вас, то прийдется делить один аккаунт — вы оба сможете просматривать и управлять закачками друг друга, что не очень удобно.
Способ решения
Самым очевидным простым и элегантным, на мой взгляд, решением является запуск transnmission одновременно от разных пользователей. В данном случае в качестве ОС применяется Ubuntu(12.10 Server), поэтому можно создать отдельный 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 ] &# 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 сможет зайти на веб-интерфейс по http://server:9091
, а пользователь с uid 1010 — по http://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/..., то пользователи смогут и забирать скачанные файлы.
Манипуляции можно засунуть в скрипт и тогда достаточно будет для каждого нового пользователя выполнить одну команду и все — можно пользоваться.
Автор: DaylightIsBurning