Арендные сидбоксы берут от 10 евро в месяц за то, что мой сервер делает бесплатно.
seedbox-sg — автоматизированный скрипт установщик собственного seedbox и в этой статье разберу, что под капотом: от тредовой модели rtorrent 0.16 до снапшотов DHT-состояния при остановке. Всё проверено на живых боксах.
Классическая связка rtorrent + ruTorrent до сих пор лучший выбор для сидбокса на десятки тысяч раздач: у qBittorrent к этим объёмам разваливается UI, у Transmission — беднее экосистема трекерных плагинов. Вопрос был только в том, что ставить её по гайдам десятилетней давности больше нельзя.
Первый: dht.port.set — no-op. Команда молча ничего не делает (порт переопределяется через dht.override_port.set), при этом UDP-порт DHT по умолчанию равен listen-порту BitTorrent — то есть правильная конфигурация это «не задавать ничего», а поле порта в настройках ruTorrent бьёт в мёртвый сеттер. seedbox-sg подменяет алиасы методов, и поле начинает честно хранить введённое.
Второй: disable убивает тумблер. Если в конфиге стоит
Остался третий, общий для всех версий: rtorrent не сохраняет рантайм-настройки — что накликано в веб-морде, умирает с рестартом. seedbox-sg решает это снапшотом: ExecStop юнита перед SIGINT снимает живые значения DHT/PEX по SCGI в
Глобальные unchoked-слоты — главный регулятор: 400 на гигабите дают ~2.5 Мбит на пира и предсказуемую нагрузку на диск вместо seek-шторма. Семантику seed-лимитов пришлось выкапывать из фабрики загрузок: при стоковых -1 сеттер просто пропускается, и сиды наследуют профиль докачек. А вот ручные сокет-буферы (
Замеры на синтетике: ~24 КБ RSS на раздачу (50k ≈ 1.5–3 ГБ структур плюс piece-кэш), multicall 16 полей на 2000 раздач — 51 мс, чистая остановка — секунды. Загрузка сессии при холодном старте — примерно 30 мс на торрент, на 35k это минуты: нормально для демона, который стартует раз в квартал.
если выдаст:
bash: wget: command not found
надо установить wget:
Скрипт сам соберёт rtorrent из исходников, развернёт ruTorrent с автологином по HTTPS (самоподписанный ECDSA-сертификат; с
Есть
После отработки скрипта, будет показан технический вывод, данные надо сохранить
для подключения помимо веб интерфейса можно использовать FileZilla по sftp
seedbox-sg — автоматизированный скрипт установщик собственного seedbox и в этой статье разберу, что под капотом: от тредовой модели rtorrent 0.16 до снапшотов DHT-состояния при остановке. Всё проверено на живых боксах.
Что такое seedbox и зачем он на своём сервере
Seedbox — это сервер для торрентов, который сидирует 24/7 вместо вашего домашнего компьютера: держит рейтинг на приватных трекерах, раздаёт на скорости канала дата-центра и не зависит от домашнего провайдера. Готовые seedbox-хостинги продают то же самое за абонентку, но любой VPS или дедик с Ubuntu или Debian превращается в полноценный сидбокс бесплатно — нужен только правильный стек: rtorrent как демон, ruTorrent как веб-морда, nginx, php-fpm и systemd, чтобы всё это переживало ребуты.Классическая связка rtorrent + ruTorrent до сих пор лучший выбор для сидбокса на десятки тысяч раздач: у qBittorrent к этим объёмам разваливается UI, у Transmission — беднее экосистема трекерных плагинов. Вопрос был только в том, что ставить её по гайдам десятилетней давности больше нельзя.
rtorrent 0.16: что изменилось под капотом
Ветка 0.16 — это фактически другой клиент, и большинство «известных фактов» о rtorrent устарели:- Многопоточность. Исторический потолок «rtorrent задыхается после 20–30 тысяч раздач» был следствием однопоточного main loop. В 0.16 сеть, диск, трекеры, сессия и SCGI живут в отдельных тредах. Я проверил на живом процессе:
session.saveна 2000 раздач возвращает управление за 3 мс, а resume-файлы дописывает фоновый session-тред за 1.6 секунды. Экстраполяция на 50k — около минуты фоном при интервале сохранения 30 минут. Main loop не блокируется вообще. - Авторазмер сокетов. Команды
network.max_open_files.setиnetwork.http.max_open.set, кочующие по всем гайдам, в 0.16 превращены в no-op заглушки. SocketManager сам масштабируется от RLIMIT_NOFILE процесса: при лимите в миллион дескрипторов HTTP-категория получает 128 слотов, файловая — 4096, остальное уходит пирам. Правильный тюнинг теперь — одна строкаLimitNOFILE=1048576в systemd-юните, и ничего в конфиге. - Сборка. C++20 (нужен gcc 11+, поэтому Ubuntu 20.04 мимо), XML-RPC через системный tinyxml2 — мёртвая зависимость xmlrpc-c больше не нужна в принципе.
- Совместимость сессии. Формат session-каталога не менялся: те же тройки
hash.torrent/.libtorrent_resume/.rtorrent, те же bencode-ключи. Это и делает возможной миграцию со старых боксов без перехеширования.
Архитектура seedbox-sg: как это работает
Скрипт — один bash-файл на 1234 строки, идемпотентный: повторный запуск ничего не ломает и не перекачивает. Версии всех компонентов запинены (rtorrent/libtorrent 0.16.15, ruTorrent 5.3.4, dumptorrent 1.7.0, autodl по SHA коммитов) и переопределяются переменными окружения.Процессы и сокеты
Вместо screen + cron + самодельного rtcheck — шаблонные systemd-юниты.rtorrent@юзер.service запускает клиент в родном daemon-режиме 0.16, чистит stale-lock в ExecStartPre, отдаёт SIGINT с таймаутом в полчаса (сброс сессии на десятках тысяч раздач — это минуты, и убивать его SIGKILL'ом — потерять resume-данные). Вся цепочка общения — unix-сокеты: rtorrent слушает SCGI на ~/.rtorrent.sock, php-fpm крутит отдельный пул от пользователя сидбокса (pm = ondemand — ноль процессов в простое; дефолтный пул www отключается, его 5 idle-воркеров на сидбоксе не нужны никому), nginx ходит в него через /run/php/rutorrent.sock. TCP внутри машины нет вообще.nginx без ловушек
Конфиг рендерится под фактическое окружение: синтаксис http2 выбирается по версии nginx (директиваhttp2 on появилась в 1.25.1, Ubuntu 24.04 ставит 1.24 — там нужен флаг у listen), IPv6-блоки комментируются, если стека нет (иначе socket() падает на VPS с ipv6.disable=1). Из полезного под нагрузку: TLS session cache (UI ruTorrent поллит постоянно — без резюмирования это CPU на хендшейках), буферизованный access_log, gzip на JSON (ответы на 35k раздач жмутся в ~10 раз), браузерный кэш статики.Плагины, которые «не работают»
Свежий ruTorrent 5.3.4 из коробки сыплет предупреждениями, и у каждого своя причина: плагину dump нужен бинарь dumptorrent (собирается cmake'ом из исходников, ссылка на которые лежит в самом плагине), _cloudflare ищет python — в Ubuntu есть только python3, а для обхода Cloudflare ему нужен pip-модуль cloudscraper. Скрипт решает это изолированным venv в /opt и явными путями в$pathToExternals — заодно исчезает PATH-поиск на каждый запрос. Декларация несуществующего fin.sh у erasedata гасится заглушкой, register_argc_argv включается в пуле. Плагин autodl-irssi отдельная история: его master несовместим с ruTorrent 5.x сразу по двум слоям (разметка диалога и сменившийся API rDirBrowser) — seedbox-sg чекаутит незамерженный PR с фиксом разметки и добивает API-слой точечным патчем. Тяжёлые на больших каталогах trafic, history и xmpp отключаются через override в plugins.ini.DHT и обмен пирами: почему у всех сломано
Здесь закопаны два капкана rtorrent 0.16, о которых не пишет никто.Первый: dht.port.set — no-op. Команда молча ничего не делает (порт переопределяется через dht.override_port.set), при этом UDP-порт DHT по умолчанию равен listen-порту BitTorrent — то есть правильная конфигурация это «не задавать ничего», а поле порта в настройках ruTorrent бьёт в мёртвый сеттер. seedbox-sg подменяет алиасы методов, и поле начинает честно хранить введённое.
Второй: disable убивает тумблер. Если в конфиге стоит
dht.mode.set = disable, rtorrent пропускает инициализацию DHT-роутера при старте — и включение галочки в веб-интерфейсе молча не работает до рестарта («server start skipped, manager is uninitialized» в дебаг-логе). Правильное «выключено» — режим off: роутер инициализирован, сервер остановлен, UDP не слушается, трафика ноль, но GUI-переключатель живой в обе стороны.Остался третий, общий для всех версий: rtorrent не сохраняет рантайм-настройки — что накликано в веб-морде, умирает с рестартом. seedbox-sg решает это снапшотом: ExecStop юнита перед SIGINT снимает живые значения DHT/PEX по SCGI в
~/.rtorrent.d/gui-state.rc, а конфиг импортирует этот файл после своих дефолтов. Галочки в ruTorrent переживают рестарты. Бутстрап-нод в 0.16, кстати, нет захардкоженных — скрипт прописывает три роутера явно, иначе холодный старт DHT не бутстрапится никогда. И да: у торрентов с private=1 libtorrent отключает DHT и PEX принудительно — глобальные настройки не сливают приватные раздачи, это проверено по исходникам.Тюнинг под 50 000 раздач: цифры вместо карго-культа
Каждое значение выведено из механики 0.16 и проверено чтением применённых значений с живого процесса:
Код:
throttle.max_uploads.set = 8 # слоты на раздачу (сток 50 — балласт)
throttle.max_uploads.global.set = 400 # ≈ канал_Мбит / 2.5
throttle.max_downloads.global.set = 60 # докачки не душат отдачу
throttle.min_peers.seed.set = 3 # при -1 сиды живут по normal=100 —
throttle.max_peers.seed.set = 60 # это сотни лишних fd на пустом месте
trackers.numwant.set = 24 # сиду список пиров не нужен
network.xmlrpc.size_limit.set = 256M # multicall на 50k ≈ 27 МиБ ответа
Глобальные unchoked-слоты — главный регулятор: 400 на гигабите дают ~2.5 Мбит на пира и предсказуемую нагрузку на диск вместо seek-шторма. Семантику seed-лимитов пришлось выкапывать из фабрики загрузок: при стоковых -1 сеттер просто пропускается, и сиды наследуют профиль докачек. А вот ручные сокет-буферы (
network.send_buffer.size), которые советует каждый второй гайд, из конфига выброшены: явный SO_SNDBUF отключает kernel autotuning, и ядро перестаёт само надувать горячие соединения. Правильное место для этого — sysctl (BBR + fq + tcp_wmem до 16M), он в скрипте есть.Замеры на синтетике: ~24 КБ RSS на раздачу (50k ≈ 1.5–3 ГБ структур плюс piece-кэш), multicall 16 полей на 2000 раздач — 51 мс, чистая остановка — секунды. Загрузка сессии при холодном старте — примерно 30 мс на торрент, на 35k это минуты: нормально для демона, который стартует раз в квартал.
Установка: одна команда
Bash:
wget https://sysadmin.guru/sh/seedbox-sg.sh
chmod +x seedbox-sg.sh
./seedbox-sg.sh --user guru
если выдаст:
bash: wget: command not found
надо установить wget:
apt install wgetСкрипт сам соберёт rtorrent из исходников, развернёт ruTorrent с автологином по HTTPS (самоподписанный ECDSA-сертификат; с
--domain останется добить certbot'ом), поднимет ufw и переведёт SSH на случайный порт — с защитой от отстрела себе ноги: старый порт остаётся открытым до ручной проверки входа, итоговая сводка показывает новый порт крупно. BT-порт выбирается случайно из диапазона выше ephemeral (61000–65500), SSH — ниже (10000–32767): исходящие соединения физически не могут занять слушающий порт. Выбор запоминается в /etc/seedbox-sg и переживает перезапуски скрипта.Есть
--lite — вариант seedbox lite без ffmpeg и mediainfo для минимальных VPS, --no-autodl, --keep-ssh, --no-ufw и явные --dht/--no-dht --pex/--no-pex (по умолчанию включены; повседневное переключение — галочками в ruTorrent, они теперь работают и сохраняются).После отработки скрипта, будет показан технический вывод, данные надо сохранить
для подключения помимо веб интерфейса можно использовать FileZilla по sftp