Dodici build

Una seedbox su un nodo di storage da 50 TB, con permessi che reggono

qBittorrent su una S-50 con un tier di staging NVMe, un'unità indurita, permessi di gruppo che sopravvivono a ogni nuovo download e un proxy che tiene l'interfaccia fuori dall'internet pubblico.

Cosa si ottiene

Un storage node che esegue qBittorrent come servizio non privilegiato: i dati incompleti vengono scritti sul livello NVMe, i file completati vengono spostati sul livello bulk da cinquanta terabyte, tutto di proprietà di un gruppo condiviso così che un secondo account possa leggerli via SFTP senza alcuna archeologia di chmod, e un'interfaccia web raggiungibile solo attraverso un proxy autenticato.

L'approccio ovvio è installare il pacchetto, fare clic sull'interfaccia e continuare con la propria giornata. Funziona per un paio di settimane, finché non arriva il primo file con il gruppo sbagliato e il tuo utente di sincronizzazione non riesce a leggerlo, e a quel punto ci sono quarantamila file con il gruppo sbagliato.

Prima di iniziare

  • Un S-50: cinquanta terabyte di bulk dietro un livello NVMe da un terabyte, su una porta da dieci gigabit. Il traffico è illimitato secondo il fair use, e la politica di utilizzo accettabile è breve e specifica su ciò che può attraversarlo. I diritti di distribuzione sono un problema tuo, non una nota a piè di pagina.
  • Debian 13, root, e un hostname come box.example.com.

1. Utenti, gruppi, struttura

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 sync

Due account, un gruppo. Il demone gira come qbt e non accede mai; sync è l'account con cui si scaricano i file e non può scrivere nulla. Ora le directory e le due flag che rendono questo lavoro permanente:

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/incomplete

La modalità 2775 imposta il bit setgid, quindi ogni file creato all'interno eredita il gruppo media invece del gruppo primario dell'utente che lo crea. La ACL predefinita concede poi a quel gruppo lettura e scrittura sulle nuove voci indipendentemente dall'umask del processo. Insieme significano che la questione dei permessi viene risolta una volta per tutte, piuttosto che dopo ogni download.

Su un S-50 il livello bulk e il NVMe sono dispositivi a blocchi separati. Conferma quale è quale prima di impegnarti con i percorsi:

lsblk -o NAME,SIZE,ROTA,MOUNTPOINT

2. Il demone

Avvialo una volta così scrive un file di configurazione, poi fermalo e modifica quel file. Lottare con l'interfaccia per le impostazioni che vivono in un file di testo è una perdita di tempo.

sudo -u qbt qbittorrent-nox --webui-port=8080 &
sleep 5 && pkill -u qbt qbittorrent-nox

Modifica /srv/qbt/.config/qBittorrent/qBittorrent.conf in modo che le sezioni [BitTorrent] e [Preferences] contengano:

[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=true

Lo staging su NVMe è il vero trucco. Le scritture dei torrent sono piccole e sparse, che è il pattern peggiore possibile per il livello bulk; il NVMe le assorbe, e il file completato viene spostato come un'unica copia sequenziale. La preallocazione ferma la frammentazione durante il flusso.

3. Una unit che non può vagare

/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.target

UMask=0002 e Group=media sono ciò che mantiene i nuovi file scrivibili dal gruppo. Senza la prima, il setgid ti dà il gruppo giusto su file che nessuno in quel gruppo può scrivere, che è un mezzo-successo sottile e irritante.

systemctl daemon-reload && systemctl enable --now qbittorrent

4. Kernel e firewall

Dieci gigabit con diverse centinaia di peer richiedono buffer di socket più grandi e una tabella di connessioni che non si riempia:

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 --system

Firewall: la porta torrent aperta su entrambe le famiglie, SSH e HTTPS aperte, l'interfaccia web vincolata a loopback e quindi non necessita di nulla.

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. L'interfaccia, dietro un proxy

certbot certonly --standalone -d box.example.com
htpasswd -c /etc/nginx/qbt.htpasswd you
server {
  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;
  }
}

Verifica

Usa qualcosa con uno sciame grande e ben seminato e una licenza inequivocabile. Un'immagine corrente dell'installer Debian è la scelta tradizionale e satura una porta da dieci gigabit in modo più convincente di qualsiasi altra cosa tu possa testare legalmente.

Aggiungi il torrent tramite l'interfaccia, poi guarda il livello di staging riempirsi:

watch -n2 "du -sh /srv/nvme/incomplete /srv/bulk/complete"

Mentre gira, conferma che la porta sia realmente raggiungibile piuttosto che semplicemente aperta nel tuo firewall, dato che una porta irraggiungibile produce un seedbox che scarica accettabilmente e semina a nessuno:

ss -tn state established sport = :51413 | wc -l

Connessioni in entrata su quella porta significano che i peer ti hanno trovato. Zero, con molte connessioni in uscita, significa che solo tu stai chiamando fuori.

Quando il download è completato, controlla le tre cose per cui questa build esiste:

ls -l /srv/nvme/incomplete
ls -ln /srv/bulk/complete
sudo -u sync cat /srv/bulk/complete/*.iso > /dev/null && echo "sync can read"

La directory staging è vuota, i file completati mostrano il gruppo 3000 con lettura e scrittura di gruppo, e l'account sync può leggerli senza alcuna correzione manuale dei permessi. Quel terzo comando è quello che dimostra che setgid e ACL hanno funzionato.

Infine, prova che l'interfaccia non sia esposta:

curl -m5 http://box.example.com:8080/ ; echo "exit $?"
curl -sI https://box.example.com/ | head -1

La prima dovrebbe fallire sulla connessione, la seconda dovrebbe restituire 401. Qualsiasi altra cosa e il binding dell'indirizzo del passo due non ha funzionato.

Dopo

Imposta un rapporto di seeding globale o un limite di tempo di condivisione a meno che tu non intenda seminare tutto per sempre, perché cinquanta terabyte si riempiono più velocemente di quanto chiunque si aspetti. Se una lamentela arriva a noi riguardo al traffico dalla tua istanza, il processo è descritto nella pagina abuse: viene inoltrata a te, e noi non andiamo a frugare nel tuo disco.

Pronto quando lo sei

Scegli una città. Scegli una dimensione. Paga in criptovaluta.

Nessun modulo su chi sei, nessuna attesa per l'approvazione di una persona, nessuna chiamata per verificare nulla. La fattura viene saldata e le credenziali arrivano nella tua casella di posta.