Doze construções

Uma seedbox em um nó de armazenamento de 50 TB, com permissões que seguram

qBittorrent em um S-50 com camada de staging NVMe, uma unit endurecida, permissões de grupo que sobrevivem a cada novo download e um proxy que mantém a interface fora da internet pública.

O que este guia constrói

Um storage node executando qBittorrent como um serviço sem privilégios: dados incompletos gravados no tier NVMe, dados concluídos movidos para o tier de armazenamento de cinquenta terabytes, tudo pertencente a um grupo compartilhado para que uma segunda conta possa ler via SFTP sem qualquer arqueologia de chmod, e uma interface web acessível apenas através de um proxy autenticado.

A abordagem óbvia é instalar o pacote, clicar pela interface e seguir o dia. Isso funciona por duas semanas, até o primeiro arquivo chegar com o grupo errado e seu usuário de sincronização não conseguir lê-lo, e a essa altura já existem quarenta mil arquivos com o grupo errado.

Antes de começar

  • Um S-50: cinquenta terabytes de armazenamento em massa atrás de um tier NVMe de um terabyte, em uma porta de dez gigabits. O tráfego é sem medição sob uso justo, e a política de uso aceitável é curta e específica sobre o que pode passar por ela. Os direitos de distribuição são problema seu, não uma nota de rodapé.
  • Debian 13, root, e um hostname como box.example.com.

1. Usuários, grupos, estrutura

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

Duas contas, um grupo. O daemon executa como qbt e nunca faz login; sync é a conta com a qual você puxa arquivos e não pode escrever nada. Agora os diretórios, e as duas flags que tornam isso 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

A modalidade 2775 define o bit setgid, então todo arquivo criado dentro herda o grupo media em vez do grupo primário do usuário criador. A ACL padrão concede a esse grupo leitura e escrita em novas entradas, independentemente do umask do processo. Juntas, elas significam que a questão de permissão é respondida uma vez, em vez de após cada download.

Em um S-50, o tier de armazenamento em massa e o NVMe são dispositivos de bloco separados. Confirme qual é qual antes de comprometer os caminhos:

lsblk -o NAME,SIZE,ROTA,MOUNTPOINT

2. O daemon

Inicie-o uma vez para que ele escreva um arquivo de configuração, então pare-o e edite esse arquivo. Lutar contra a interface por configurações que vivem em um arquivo de texto é um desperdício de tarde.

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

Edite /srv/qbt/.config/qBittorrent/qBittorrent.conf para que as seções [BitTorrent] e [Preferences] contenham:

[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

O staging no NVMe é todo o truque. As escritas de torrent são pequenas e dispersas, o que é o pior padrão possível para o tier de armazenamento em massa; o NVMe as absorve, e o arquivo concluído atravessa como uma cópia sequencial. A pré-alocação impede a fragmentação no caminho.

3. Uma unit que não pode vagar

/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 são o que mantém novos arquivos com permissão de escrita no grupo. Sem o primeiro, o setgid dá a você o grupo certo em arquivos que ninguém naquele grupo pode escrever, o que é um meio-sucesso sutil e irritante.

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

4. Kernel e firewall

Dez gigabits com várias centenas de pares precisa de buffers de socket maiores e uma tabela de conexões que não encha:

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: a porta de torrent aberta em ambas as famílias, SSH e HTTPS abertos, a interface web vinculada ao loopback e, portanto, precisando de nada.

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. A interface, atrás de um 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;
  }
}

Verifique

Use algo com um enxame grande e bem semeado e uma licença inequívoca. Uma imagem atual do instalador Debian é a escolha tradicional e satura uma porta de dez gigabits mais convincentemente do que qualquer outra coisa que você pode testar legalmente.

Adicione o torrent pela interface, então observe o tier de staging encher:

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

Enquanto roda, confirme que a porta é genuinamente alcançável, em vez de meramente aberta no seu próprio firewall, já que uma porta inalcançável produz um seedbox que baixa de forma aceitável e semeia para ninguém:

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

Conexões de entrada nessa porta significam que peers o encontraram. Zero, com muitas conexões de saída, significa que apenas você está discando para fora.

Quando o download terminar, verifique as três coisas para as quais este build existe:

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

O diretório de staging está vazio, os arquivos concluídos mostram o grupo 3000 com leitura e escrita no grupo, e a conta sync pode lê-los sem qualquer correção manual de permissão. Esse terceiro comando é o que prova que o investimento em setgid e ACL valeu a pena.

Finalmente, prove que a interface não está exposta:

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

O primeiro deve falhar na conexão, o segundo deve retornar 401. Qualquer outra coisa e a vinculação de endereço no passo dois não foi aplicada.

Depois

Defina uma razão global de seeding ou um limite de tempo de compartilhamento, a menos que você pretenda semear tudo para sempre, porque cinquenta terabytes enche mais rápido do que qualquer um espera. Se uma reclamação chegar até nós sobre tráfego da sua instância, o processo está descrito na página de abuso: é encaminhada para você, e nós não procuramos no seu disco.

Pronto quando você estiver

Escolha uma cidade. Escolha um tamanho. Pague em cripto.

Sem formulários sobre quem você é, sem esperar aprovação de um humano, sem ligação para verificar nada. O pagamento é confirmado e as credenciais chegam na sua caixa de entrada.