Co to buduje
Węzeł pamięci masowej z qBittorrent działającym jako nieuprzywilejowana usługa: niedokończone dane zapisywane są do warstwy NVMe, ukończone pliki przenoszone są do pięćdziesięcioterabajtowej warstwy masowej, wszystko jest własnością wspólnej grupy, tak aby drugie konto mogło odczytywać je przez SFTP bez żadnych przenosin uprawnień, a interfejs webowy jest osiągalny tylko przez uwierzytelnione proxy.
Oczywiste podejście polega na zainstalowaniu pakietu, klikaniu w interfejsie i kontynuowaniu dnia. To działa przez dwa tygodnie, aż pojawi się pierwszy plik z niewłaściwą grupą, a Twój użytkownik synchronizujący nie będzie mógł go odczytać, a do tego czasu będą już czterdzieści tysięcy plików z niewłaściwą grupą.
Zanim zaczniesz
- S-50: pięćdziesiąt terabajtów pamięci masowej na jednej terabajtowej warstwie NVMe, na porcie dziesięciogigabitowy. Ruch jest nielimitowany przy uczciwym użytkowaniu, a polityka dozwolonego użytku jest krótka i konkretna w kwestii tego, co może przez nią przechodzić. Prawa do dystrybucji są Twoim problemem, a nie przypisem.
- Debian 13, root i nazwa hosta taka jak
box.example.com.
1. Użytkownicy, grupy, układ
apt update && apt install -y qbittorrent-nox nginx apache2-utils acl
groupadd -g 3000 media
useradd -r -g media -u 3000 -d /srv/qbt -m -s /usr/sbin/nologin qbt
useradd -m -G media syncDwa konta, jedna grupa. Demon działa jako qbt i nigdy się nie loguje; sync to konto, na które pobierasz pliki i które nie może nic zapisywać. Teraz katalogi i dwie flagi, które sprawiają, że to działa na stałe:
install -d -o qbt -g media -m 2775 /srv/nvme/incomplete
install -d -o qbt -g media -m 2775 /srv/bulk/complete
setfacl -d -m g:media:rwx /srv/bulk/complete
setfacl -d -m g:media:rwx /srv/nvme/incompleteTryb 2775 ustawia bit setgid, więc każdy plik utworzony w środku dziedziczy grupę media zamiast podstawowej grupy tworzącego użytkownika. Domyślna ACL przyznaje następnie tej grupie prawa odczytu i zapisu do nowych wpisów, niezależnie od umask procesu. Razem oznaczają, że kwestia uprawnień jest rozstrzygnięta raz, a nie po każdym pobraniu.
Na S-50 warstwa masowa i NVMe to osobne urządzenia blokowe. Potwierdź, które jest które, zanim zaangażujesz się w ścieżki:
lsblk -o NAME,SIZE,ROTA,MOUNTPOINT2. Demon
Uruchom go raz, aby zapisał plik konfiguracyjny, następnie zatrzymaj go i edytuj ten plik. Walka z interfejsem o ustawienia, które są w pliku tekstowym, to strata popołudnia.
sudo -u qbt qbittorrent-nox --webui-port=8080 &
sleep 5 && pkill -u qbt qbittorrent-noxEdytuj /srv/qbt/.config/qBittorrent/qBittorrent.conf, aby sekcje [BitTorrent] i [Preferences] zawierały:
[BitTorrent]
Session\DefaultSavePath=/srv/bulk/complete
Session\TempPath=/srv/nvme/incomplete
Session\TempPathEnabled=true
Session\Port=51413
Session\DiskCacheSize=2048
Session\MaxConnections=800
Session\MaxUploads=40
Session\GlobalMaxSeedingMinutes=-1
Session\Preallocation=true
[Preferences]
WebUI\Address=127.0.0.1
WebUI\Port=8080
WebUI\LocalHostAuth=false
WebUI\CSRFProtection=true
Downloads\UseIncompleteExtension=trueStaging na NVMe to cała sztuczka. Zapisy torrenta są małe i rozproszone, co jest najgorszym możliwym wzorcem dla warstwy masowej; NVMe je pochłania, a ukończony plik przenosi się jako jedna sekwencyjna kopia. Prelokacja zapobiega fragmentacji na wejściu.
3. Jednostka, która nie może zboczyć
/etc/systemd/system/qbittorrent.service:
[Unit]
Description=qBittorrent
After=network-online.target
Wants=network-online.target
[Service]
User=qbt
Group=media
UMask=0002
ExecStart=/usr/bin/qbittorrent-nox
Restart=on-failure
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
ReadWritePaths=/srv/qbt /srv/nvme/incomplete /srv/bulk/complete
LimitNOFILE=65535
[Install]
WantedBy=multi-user.targetUMask=0002 i Group=media to to, co utrzymuje nowe pliki z możliwością zapisu przez grupę. Bez pierwszego, setgid daje właściwą grupę plików, których nikt w tej grupie nie może zapisywać, co jest subtelnym i irytującym półsukcesem.
systemctl daemon-reload && systemctl enable --now qbittorrent4. Jądro i zapora ogniowa
Dziesięć gigabitów z kilkoma setkami peerów wymaga większych buforów gniazd i tabeli połączeń, która się nie zapełni:
cat > /etc/sysctl.d/70-seedbox.conf <<EOF
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.tcp_wmem = 4096 65536 33554432
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.netfilter.nf_conntrack_max = 524288
EOF
sysctl --systemZapora ogniowa: port torrentowy otwarty na obu rodzinach, SSH i HTTPS otwarte, interfejs webowy związany z loopbackiem, więc nie potrzebuje niczego.
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif lo accept
ip6 nexthdr icmpv6 accept
ip protocol icmp accept
tcp dport { 22, 443 } accept
tcp dport 51413 accept
udp dport 51413 accept
}
}5. Interfejs za proxy
certbot certonly --standalone -d box.example.com
htpasswd -c /etc/nginx/qbt.htpasswd youserver {
listen 443 ssl;
server_name box.example.com;
ssl_certificate /etc/letsencrypt/live/box.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/box.example.com/privkey.pem;
client_max_body_size 100m;
location / {
auth_basic "closed";
auth_basic_user_file /etc/nginx/qbt.htpasswd;
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-Host $http_host;
proxy_http_version 1.1;
}
}Weryfikacja
Użyj czegoś z dużym, dobrze wysianym rojem i jednoznaczną licencją. Aktualny obraz instalatora Debiana to tradycyjny wybór i nasyca port dziesięciogigabitowy bardziej przekonująco niż cokolwiek innego, co możesz legalnie przetestować.
Dodaj torrent przez interfejs, a następnie obserwuj, jak zapełnia się warstwa staging:
watch -n2 "du -sh /srv/nvme/incomplete /srv/bulk/complete"Podczas działania potwierdź, że port jest faktycznie osiągalny, a nie tylko otwarty w Twojej własnej zaporze, ponieważ nieosiągalny port produkuje seedbox, który pobiera zadowalająco i sieje do nikogo:
ss -tn state established sport = :51413 | wc -lPrzychodzące połączenia na tym porcie oznaczają, że peerzy Cię znaleźli. Zero, przy dużej liczbie połączeń wychodzących, oznacza, że to tylko Ty dzwonisz.
Gdy pobieranie się zakończy, sprawdź trzy rzeczy, dla których istnieje ta konstrukcja:
ls -l /srv/nvme/incomplete
ls -ln /srv/bulk/complete
sudo -u sync cat /srv/bulk/complete/*.iso > /dev/null && echo "sync can read"Katalog staging jest pusty, ukończone pliki mają grupę 3000 z prawami odczytu i zapisu dla grupy, a konto sync może je odczytać bez ręcznej poprawy uprawnień. To trzecie polecenie to to, które dowodzi, że setgid i ACL zadziałały.
Na koniec udowodnij, że interfejs nie jest wystawiony:
curl -m5 http://box.example.com:8080/ ; echo "exit $?"
curl -sI https://box.example.com/ | head -1Pierwsze powinno zakończyć się błędem połączenia, drugie powinno zwrócić 401. Cokolwiek innego oznacza, że wiązanie adresu w kroku drugim nie zadziałało.
Później
Ustaw globalny współczynnik seedowania lub limit czasu seedowania, chyba że zamierzasz seedować wszystko na zawsze, ponieważ pięćdziesiąt terabajtów zapełnia się szybciej, niż ktokolwiek się spodziewa. Jeśli skarga dotycząca ruchu z Twojej instancji dotrze do nas, proces jest opisany na stronie nadużyć: jest przekazywana do Ciebie, a my nie przeszukujemy Twojego dysku.