Como transformar o Discourse em um tracker privado de BitTorrent
Análise técnica, arquitetural, operacional e jurídica para criar um plugin de Discourse integrado a um tracker privado de BitTorrent.
Como transformar o Discourse em um tracker privado de BitTorrent
É tecnicamente possível transformar uma comunidade Discourse na interface de um tracker privado de BitTorrent. O Discourse pode cuidar das contas, convites, grupos, catálogo, pesquisa, comentários, moderação, reputação e páginas de cada torrent. O que ele não deve fazer, numa instalação séria, é processar diretamente todo o tráfego de announce dos clientes BitTorrent: essa parte possui características de carga, protocolo e segurança diferentes das de um fórum Ruby on Rails.
O desenho recomendado é, portanto, um plugin de Discourse acompanhado por um tracker dedicado. Para o usuário, tudo parece parte do Discourse. Por baixo, o plugin é a autoridade de membros e catálogo, enquanto um serviço pequeno e especializado recebe os anúncios dos clientes, mantém os peers ativos e envia estatísticas agregadas de volta ao plugin.
Esta análise parte de um uso legítimo: distribuição privada de arquivos próprios, licenciados, em domínio público, software livre, imagens de sistemas, acervos institucionais ou outros materiais cuja circulação tenha sido autorizada. O protocolo BitTorrent é uma tecnologia neutra; a legalidade depende do conteúdo e das autorizações. A arquitetura deve nascer com política de direitos autorais, canal de denúncia e rastreabilidade administrativa.
Resumo executivo
Resposta curta: sim, é possível e a ideia é boa, desde que o Discourse não seja forçado a virar o próprio daemon de tracker.
A melhor solução é desenvolver um projeto provisoriamente chamado discourse-private-tracker, composto por duas partes:
- Plugin do Discourse: gerencia usuários, convites, grupos, uploads de metadados
.torrent, páginas de catálogo, permissões, downloads personalizados, passkeys, moderação, relatórios e estatísticas consolidadas. - Tracker sidecar: serviço independente, inicialmente apenas HTTPS, que valida passkeys e info-hashes, devolve peers, mantém sessões de swarm em memória ou Redis e publica deltas de tráfego para o Discourse.
O melhor ponto de partida para o sidecar é o Chihaya, escrito em Go. O projeto foi criado justamente para integrar BitTorrent a ambientes existentes, oferece frontends HTTP e UDP, armazenamento substituível, Redis, Prometheus e uma cadeia de middlewares anteriores e posteriores ao announce. Sua licença é BSD de duas cláusulas, favorável a adaptações. A autenticação por passkey e a contabilidade individual ainda precisariam ser implementadas como middleware próprio.
O Torrust Tracker é a segunda melhor base: moderno, ativo, escrito em Rust, com modos privado e por lista permitida, API de administração, HTTP, TLS, UDP, IPv4/IPv6 e persistência. Entretanto, sua própria lista de desenvolvimento ainda apresenta estatísticas específicas por peer e torrent como trabalho pendente. Ele resolve autorização e matchmaking melhor do que resolve a contabilidade tradicional por usuário.
Para uma prova de conceito muito pequena, bittorrent-tracker permite criar rapidamente um servidor Node.js com filtro assíncrono por info-hash e segredo. É excelente para validar a experiência, mas exigirá uma camada própria de persistência e contabilidade antes de operar como tracker privado completo.
UNIT3D já entrega praticamente todas as funções de um tracker privado, inclusive passkeys, peers, razão de compartilhamento, limites e moderação. Contudo, ele é uma aplicação Laravel completa, não uma biblioteca para Discourse. Usá-lo junto ao Discourse resultaria em dois produtos e dois modelos de usuários; adaptar seu UNIT3D-Announce exigiria desacoplar o serviço do banco e dos conceitos internos do UNIT3D.
Não foi encontrado, na busca pelo diretório oficial de plugins do Discourse, no repositório que cataloga plugins conhecidos e no GitHub, um plugin atual e mantido que transforme o Discourse em tracker privado. A ideia parece suficientemente inédita para justificar um projeto próprio.
Veredito
| Pergunta | Resposta |
|---|---|
| É possível? | Sim. O sistema de plugins do Discourse permite backend Rails, tabelas, rotas, controladores, jobs e interface Ember. |
| Um componente de tema é suficiente? | Não. Tema altera interface; passkeys, autorização, parsing e persistência exigem plugin de servidor. |
| O Discourse deve receber os announces? | Somente numa prova de conceito pequena. Em produção, use um serviço dedicado. |
| Melhor arquitetura | Plugin Discourse + Chihaya com middleware próprio + Redis + PostgreSQL. |
| Caminho mais rápido para um tracker completo | Instalar UNIT3D separado e unificar login; não transforma verdadeiramente o Discourse. |
| Caminho mais simples para provar a ideia | Plugin mínimo + bittorrent-tracker em Node.js, apenas HTTPS e sem razão punitiva. |
| Dificuldade | Média para um protótipo; alta para uma comunidade confiável e resistente a fraude. |
| Maior risco técnico | Contabilidade correta, vazamento de passkeys, abuso do endpoint e compatibilidade de clientes. |
| Maior risco não técnico | Distribuição não autorizada e tratamento de endereços IP e históricos de uso. |
Metodologia e critérios
A pesquisa examinou as especificações oficiais do BitTorrent, o código e a documentação atuais do Discourse, o modelo oficial de plugin, os catálogos conhecidos de plugins e os repositórios dos principais trackers abertos.
As alternativas foram avaliadas por: atividade de manutenção; adequação a tracker privado; autenticação; lista permitida de torrents; contabilidade individual; extensibilidade; desempenho; suporte a HTTP/HTTPS, UDP e IPv6; persistência; observabilidade; licença; acoplamento; dificuldade de integração com o Discourse; e risco operacional.
As datas de atividade dos repositórios foram verificadas em 24 de agosto de 2026. Estimativas de tempo, capacidade e custo são projeções de engenharia, não promessas dos projetos citados. O documento não substitui uma análise jurídica aplicada ao país de hospedagem, à entidade operadora e ao conteúdo distribuído.
O que significa “transformar o Discourse em tracker”
Um tracker privado moderno é a combinação de pelo menos quatro produtos:
- Comunidade: cadastro, convites, regras, fóruns, mensagens, denúncias e moderação.
- Índice: catálogo pesquisável de torrents, categorias, descrições, arquivos, tamanhos e estatísticas.
- Tracker de protocolo: endpoint que recebe
announcedos clientes e devolve a lista de peers da mesma swarm. - Contabilidade: atribuição de upload, download, tempo de seed e conclusão a uma conta.
O Discourse já é muito competente no primeiro item e oferece grande parte da fundação do segundo. O plugin acrescentaria o restante do índice e a ligação com os dois últimos. Os arquivos grandes não passam pelo Discourse nem pelo tracker: continuam sendo transferidos diretamente entre clientes BitTorrent. O fórum hospeda apenas páginas, metadados e os pequenos arquivos .torrent.
O que já pode ser reaproveitado do Discourse
- Contas, e-mail, sessões, autenticação social, 2FA e recuperação.
- Convites, aprovação manual e configuração de comunidade fechada.
- Grupos para membros, uploaders, moderadores e equipe.
- Categorias privadas com permissões separadas de ver, responder e criar.
- Tópicos, comentários, pesquisa, tags, notificações, chat e mensagens.
- Flags, silenciamento, suspensão, auditoria e fila de revisão.
- Badges, níveis de confiança e histórico comunitário.
- API REST, webhooks, jobs em Sidekiq, PostgreSQL e Redis.
- Armazenamento externo e uploads seguros, quando configurados corretamente.
- Extensão de backend e frontend por plugins.
A documentação de desenvolvimento confirma que o núcleo tem backend Ruby on Rails e frontend Ember e que plugins podem alterar os dois lados. O guia oficial mostra como um plugin define um Rails::Engine, controladores, rotas e módulos isolados; o esqueleto oficial já inclui diretórios para modelos, migrações, interface e testes.
O que precisa ser construído
- Parser e validador seguro de metainfo BitTorrent.
- Registro de torrents por info-hash.
- Download personalizado do
.torrentpor usuário. - Geração, rotação e revogação de passkeys.
- Serviço de
announceescrape. - Lista de torrents permitidos.
- Estado de seeders, leechers e peers.
- Contabilidade por usuário e por torrent.
- Políticas de ratio, seed time, freeleech e download slots, caso desejadas.
- Telas administrativas e páginas de estatísticas.
- Integração segura entre plugin e sidecar.
- Proteções contra falsificação, vazamento e abuso.
- Política jurídica e de privacidade específica.
Como o protocolo funciona
A BEP 3 define a distribuição BitTorrent como a interação entre um servidor web, um arquivo de metainfo, um tracker, um seeder inicial e os clientes finais. O .torrent é um dicionário em bencode. Seu campo superior announce informa o tracker; o dicionário info descreve os arquivos e as peças.
O info_hash de BitTorrent v1 é o SHA-1 dos bytes bencoded do dicionário info. Isso produz uma regra fundamental para o plugin:
O endereço
announcepode ser personalizado sem alterar a swarm, porque fica fora deinfo. Inserir ou mudarprivate=1dentro deinfo, por outro lado, altera o info-hash.
Assim, o sistema pode armazenar um metainfo canônico, sem segredo, e gerar no momento do download uma cópia cuja URL seja semelhante a:
https://tracker.example/announce/PASSKEY_DO_USUARIO
O cliente passa a enviar periodicamente requisições com info_hash, peer_id, porta, bytes enviados, bytes baixados, bytes restantes e eventos como started, completed e stopped. O tracker valida a passkey e o torrent, registra o peer e devolve outros endereços da mesma swarm.
Torrent privado não significa criptografado ou anônimo
A BEP 27 define private=1. Clientes compatíveis devem anunciar apenas ao tracker privado e não usar mecanismos externos de descoberta. Isso reduz o vazamento por DHT, PEX e descoberta local, mas não criptografa o conteúdo e não oculta peers uns dos outros. Cada peer precisa conhecer o IP e a porta dos demais para transferir dados.
Clientes modificados podem desobedecer à regra. Remover private=1 altera o info-hash e cria outra swarm, mas não impede alguém que já tenha o conteúdo de redistribuí-lo. “Privado” significa acesso controlado ao tracker, não DRM.
Por que começar apenas com HTTPS
A BEP 15 reduz bastante o custo de anúncios usando UDP, mas seu campo key não é uma credencial padronizada de conta; normalmente é escolhido pelo cliente. Passkeys em caminhos HTTPS são mais compatíveis com o modelo tradicional de trackers privados, mais fáceis de revogar, registrar e proteger por proxy.
Para o MVP, a recomendação é:
https://tracker.example/announce/{passkey};https://tracker.example/scrape/{passkey}ou scrape desativado;- respostas compactas de peers;
- IPv4 e IPv6;
- intervalo inicial entre 30 e 45 minutos, com mínimo protegido;
- UDP e WebTorrent deixados para versões posteriores.
Arquiteturas possíveis
Opção A — Tudo dentro do Discourse
O plugin cria um controlador Rails em /tracker/announce/:passkey, consulta PostgreSQL/Redis e devolve bencode.
Vantagens: uma implantação, acesso direto aos usuários, código conceitualmente simples e ótimo para demonstrar a ideia.
Problemas: cada cliente chama o endpoint repetidamente mesmo sem navegar no fórum; a carga concorre com páginas, API e Sidekiq; respostas de tracker não combinam com middleware web comum; atualizações do Discourse podem afetar o endpoint; UDP não cabe naturalmente no Rails; e um ataque ao announce pode degradar toda a comunidade.
Veredito: aceitável somente para laboratório ou grupo muito pequeno. Não é a arquitetura a publicar como plugin geral.
Opção B — Plugin + tracker sidecar
O Discourse é a fonte de verdade para contas, catálogo e decisões administrativas. O sidecar recebe announces, usa cache local/Redis para autorizar e envia eventos agregados a uma fila.
Vantagens: isolamento de carga e falhas; liberdade para Go ou Rust; atualização independente; melhor desempenho; possibilidade de múltiplas réplicas; métricas próprias; e uma interface de integração explícita.
Problemas: dois processos, contrato entre serviços, consistência eventual e mais trabalho de implantação.
Veredito: arquitetura recomendada.
Opção C — Discourse + UNIT3D separados
UNIT3D funciona como tracker e índice; Discourse permanece como fórum. Um provedor OIDC comum ou integração de SSO mantém uma identidade aproximada nos dois sistemas.
Vantagens: funções maduras de tracker privado ficam prontas mais rapidamente. O código atual do UNIT3D já verifica passkey, grupo, cliente, torrent, intervalo mínimo, conexões e slots no controlador de announce.
Problemas: catálogo, perfis, permissões e moderação duplicados; integração visual imperfeita; sincronização de banimentos; dois bancos; e pouca vantagem real em “transformar o Discourse”.
Veredito: melhor para colocar um tracker convencional no ar, pior para concretizar esta ideia como produto distinto.
Opção D — Adaptar o UNIT3D-Announce ao plugin
O serviço UNIT3D-Announce é um tracker Rust de alto desempenho que já trabalha com passkeys e estatísticas. Poderia ser bifurcado e receber uma nova camada de repositório compatível com as tabelas do plugin.
Vantagens: lógica específica de tracker privado já existente e desempenho documentado muito superior ao controlador PHP do UNIT3D.
Problemas: forte acoplamento atual ao modelo UNIT3D, adaptação invasiva, licença AGPL e manutenção de um fork complexo.
Veredito: opção válida para uma segunda geração, após estabilizar o modelo de dados e entender as regras desejadas.
Arquitetura recomendada
Navegador
|
v
Discourse + discourse-private-tracker
|-- contas, convites, grupos e 2FA
|-- tópicos, catálogo, pesquisa e comentários
|-- upload/validação do metainfo
|-- download personalizado com passkey
|-- administração, denúncias e estatísticas
|
+---- PostgreSQL: catálogo, usuários e totais consolidados
+---- Sidekiq: validação, agregação, alertas e limpeza
+---- armazenamento de objetos: metainfo canônico
|
+---- API interna autenticada -------------------+
|
Cliente BitTorrent v
| Tracker sidecar Chihaya
| HTTPS announce com passkey |-- middleware de autenticação
+---------------------------------------->|-- lista permitida de info-hashes
|-- peers ativos e scrape
|-- deltas de upload/download
|-- limites e métricas
|
+-- Redis próprio
+-- fila de eventos
+-- Prometheus
Divisão de responsabilidades
| Responsabilidade | Discourse/plugin | Sidecar |
|---|---|---|
| Cadastro, login, 2FA e convites | Sim | Não |
| Grupos e suspensão | Sim | Cache da decisão |
| Página e comentários do torrent | Sim | Não |
Parsing e aprovação do .torrent |
Sim | Recebe info-hash permitido |
| Personalização do arquivo baixado | Sim | Não |
| Validação rápida de passkey | Fonte de verdade | Execução em cache |
| Announce e resposta de peers | Não | Sim |
| Peers ativos | Exibe agregados | Fonte operacional |
| Histórico de tráfego | Consolida | Produz deltas |
| Ratio e políticas | Define e aplica | Faz bloqueio imediato em cache |
| Logs comunitários | Sim | Não |
| Métricas de protocolo | Exibe resumo | Prometheus |
Escolha do motor de tracker
| Projeto | Pontos fortes | Limitações para esta ideia | Uso recomendado |
|---|---|---|---|
| Chihaya | Go; HTTP/UDP; IPv4/IPv6; Redis; Prometheus; alta disponibilidade; middlewares; BSD-2-Clause | Autenticação por conta e ratio precisam de middleware próprio; releases formais antigas exigem fixar e testar um commit atual | Base recomendada para produção personalizada |
| Torrust Tracker | Rust; ativo; TLS; API; modo privado e whitelist; SQLite/MySQL/PostgreSQL; BEP 27 | Chaves são o mecanismo de autenticação, mas estatísticas detalhadas por peer/torrent ainda aparecem no roadmap; AGPL | Alternativa moderna se ratio não for central ou se houver disposição para contribuir/forkar |
| bittorrent-tracker | Node.js; API simples; HTTP/UDP/WebSocket; filtro assíncrono; eventos; MIT | Estado e contabilidade de tracker privado precisam ser construídos; não é um portal completo | Melhor para prova de conceito rápida |
| UNIT3D-Announce | Rust; passkey e contabilidade maduras; desempenho; regras de tracker privado | Vinculado às tabelas e regras do UNIT3D; AGPL | Fork para versão avançada, não para primeiro MVP |
| Aquatic | Rust; alto desempenho; HTTP/UDP/WebTorrent; listas de info-hash; Prometheus; Apache-2.0 | Focado em tracker aberto; sem identidade e ratio prontos | Grandes swarms sem contabilidade individual |
| opentracker | C; mínimo consumo; muito simples; HTTP/UDP | Deliberadamente aberto, sem persistência e pouco adequado a usuários/passkeys | Não recomendado para este produto |
| Ocelot | Modelo clássico de tracker privado e integração histórica com Gazelle | Repositório original sem alterações de código desde 2015, somente IPv4 e forte acoplamento ao esquema Gazelle/MySQL | Referência histórica, não base nova |
Por que Chihaya vence
A arquitetura oficial do Chihaya separa frontends de protocolo, lógica e armazenamento. Uma cadeia configurável de PreHook atua antes da resposta e PostHook executa tarefas assíncronas depois dela. O repositório atual já inclui middlewares de aprovação de cliente, JWT, aprovação de torrent e intervalo variável.
Essa estrutura corresponde quase exatamente ao necessário:
PreHook PasskeyAuth: extrai passkey, consulta cache e rejeita conta inválida.PreHook TorrentApproval: rejeita info-hash não aprovado.PreHook Policy: aplica banimento, limite de peers e cliente bloqueado.PostHook Accounting: calcula deltas válidos e publica eventos.- Storage Redis: guarda peers ativos e swarms.
- Prometheus: mede announces, erros, latência e volume.
O antigo chihaya-privtrak-middleware serve como referência conceitual para deltas por usuário e info-hash, mas declara estar em estágio inicial e não deve ser adotado sem auditoria e atualização.
Modelo do plugin Discourse
Estrutura sugerida
discourse-private-tracker/
├── plugin.rb
├── config/
│ ├── routes.rb
│ ├── settings.yml
│ └── locales/
├── lib/discourse_private_tracker/
│ ├── engine.rb
│ ├── torrent_parser.rb
│ ├── torrent_personalizer.rb
│ ├── passkey_service.rb
│ └── tracker_client.rb
├── app/
│ ├── controllers/discourse_private_tracker/
│ ├── models/discourse_private_tracker/
│ ├── serializers/
│ └── jobs/
├── db/migrate/
├── assets/javascripts/discourse/
├── stylesheets/
├── spec/
└── test/javascripts/
O plugin deve usar um Rails::Engine isolado, conforme o guia atual de estrutura e autoloading, em vez de concentrar classes em plugin.rb. A interface deve usar a API JavaScript e plugin outlets estáveis; alterações diretas de classes internas devem ser evitadas porque o próprio Discourse alerta que esse mecanismo pode quebrar com mudanças no núcleo.
Modelo de dados mínimo
| Tabela | Campos principais | Finalidade |
|---|---|---|
private_tracker_accounts |
user_id, passkey_digest, status, uploaded, downloaded, seed_seconds, last_announce_at |
Estado de tracker ligado ao usuário Discourse |
private_tracker_torrents |
topic_id, info_hash_v1, info_hash_v2, name, size, file_count, private, status, uploader_id |
Catálogo técnico e ligação com tópico |
private_tracker_downloads |
user_id, torrent_id, downloaded_at, passkey_version |
Auditoria de obtenção do metainfo |
private_tracker_transfers |
user_id, torrent_id, uploaded, downloaded, seed_seconds, completed_at |
Totais consolidados por usuário e torrent |
private_tracker_accounting_batches |
event_id, received_at, payload_digest, processed_at |
Idempotência na comunicação do sidecar |
private_tracker_moderation_events |
ator, alvo, ação, motivo, timestamps | Rotação, bloqueio, remoção e revisão |
private_tracker_reports |
torrent, denunciante, fundamento, estado, decisão | Denúncias e direitos autorais |
Peers ativos não devem ser gravados em uma linha PostgreSQL a cada announce. Eles pertencem ao sidecar/Redis e expiram por TTL. PostgreSQL recebe somente totais agregados, conclusões e eventos administrativos que precisem sobreviver.
Tópico como unidade editorial
Cada torrent aprovado pode corresponder a um tópico numa categoria restrita. O primeiro post contém descrição, origem, licença, instruções e imagens; comentários funcionam normalmente. O plugin associa o topic_id ao registro técnico e injeta acima das respostas:
- botão de baixar
.torrent; - tamanho e número de arquivos;
- seeders, leechers e concluídos;
- estado de aprovação;
- categoria e tags;
- crédito ao uploader;
- alerta de ausência de seed;
- ações de denúncia para membros;
- ações de moderação para equipe.
Para navegação em volume, uma rota própria /torrents deve oferecer filtros por categoria, atividade, tamanho, data e estado. Não convém tentar transformar a lista normal de tópicos em uma tabela de tracker por meio de alterações frágeis no frontend.
Fluxos completos
1. Entrada e autorização do membro
- O Discourse opera como comunidade fechada, com convite ou aprovação manual.
- O usuário confirma e-mail e configura 2FA conforme a política.
- Um job cria
private_tracker_accountscom estadopendingouenabled. - A passkey aleatória é produzida com CSPRNG, mostrada somente quando necessária e armazenada como digest pesquisável, nunca em texto nos logs.
- O sidecar recebe uma atualização assinada ou atualiza seu cache sob demanda.
- Suspender o usuário no Discourse revoga imediatamente o acesso no tracker.
Não use o trust_level como única autorização. Níveis de confiança mudam por atividade social; acesso ao tracker deve ser um estado explícito ou grupo administrável.
2. Envio de um torrent
- O uploader cria localmente o
.torrentdos arquivos que já possui e pretende semear. - Envia o metainfo por formulário do plugin, junto de descrição e comprovação de autorização quando aplicável.
- O plugin limita tamanho, lê bytes com biblioteca bencode e rejeita estruturas malformadas, profundas ou excessivas.
- Valida nomes, caminhos, tamanhos, número de arquivos, peças, trackers existentes e versões v1/v2.
- Garante
private=1. Se precisar acrescentá-lo, informa que o info-hash muda e gera uma nova versão canônica. - Remove
announce-list,nodese trackers externos. Web seeds só permanecem quando aprovados. - Calcula o info-hash diretamente dos bytes canônicos do dicionário
info. - Verifica duplicidade e cria um tópico em estado de revisão.
- Um moderador aprova conteúdo, categoria e licença.
- O plugin envia o info-hash para a lista permitida do sidecar.
- O uploader baixa sua cópia personalizada e inicia o seed.
O parser não deve confiar em nomes de arquivos. Caminhos absolutos, .., caracteres nulos, componentes reservados e árvores v2 inválidas precisam ser rejeitados ou normalizados apenas para exibição. A BEP 52 alerta explicitamente para sanitização de . e .. e para validação canônica antes de recalcular hashes.
3. Download personalizado
- O membro abre o tópico e solicita o arquivo.
- O controller verifica login, estado da conta, permissão da categoria e política de download.
- Recupera o metainfo canônico.
- Substitui somente os campos superiores de tracker por uma URL com a passkey atual.
- Reencoda de forma canônica sem modificar o dicionário
info. - Confere novamente o info-hash antes de responder.
- Envia
Content-Type: application/x-bittorrent,Content-Disposition: attachmenteCache-Control: private, no-store. - Registra a entrega sem registrar a passkey bruta.
Esse arquivo não deve usar uma URL temporária que expire em poucas horas: o cliente precisa anunciar enquanto estiver semeando durante dias ou meses. A passkey é revogável, mas persistente até rotação.
4. Announce
- O cliente solicita
GET /announce/{passkey}com os campos do protocolo. - O proxy encaminha o IP real somente a partir de proxies confiáveis.
- O sidecar limita tamanho e sintaxe antes de qualquer acesso externo.
- O middleware transforma a passkey em digest e consulta cache.
- Verifica conta habilitada, info-hash permitido, intervalo mínimo,
peer_id, porta e contadores. - Calcula o delta em relação à sessão anterior do mesmo usuário, torrent e peer.
- Atualiza o peer ativo com TTL e escolhe uma amostra de peers da swarm.
- Responde imediatamente em bencode.
- Em
PostHook, publica o delta de contabilidade numa fila. - Um job agrega os eventos e atualiza os totais no PostgreSQL.
5. Rotação de passkey
- Usuário ou moderador solicita rotação por suspeita de vazamento.
- O plugin gera nova credencial, aumenta
passkey_versione invalida a anterior. - O sidecar recebe revogação de alta prioridade.
- Torrents antigos passam a receber
failure reasonsem revelar detalhes da conta. - O usuário baixa novamente os metadados ou substitui o tracker no cliente.
- O evento fica na auditoria administrativa.
Uma opção avançada é passkey diferente por torrent ou por download. Ela reduz o impacto de vazamento, mas multiplica registros e torna a experiência de rotação mais trabalhosa. Para o MVP, uma passkey por usuário é suficiente; passkeys por torrent podem vir depois.
6. Remoção e denúncia
- A denúncia entra no plugin e pode ocultar preventivamente o botão de download.
- O moderador altera o torrent para
blocked. - O sidecar remove o info-hash da lista permitida.
- Announces passam a falhar e nenhum peer novo é apresentado.
- O metainfo e os registros administrativos são preservados pelo prazo da política, sem manter conteúdo que nunca esteve no servidor.
- A decisão, fundamento e comunicação ficam auditáveis.
Bloquear o tracker não apaga cópias já distribuídas nem impede peers que já se conhecem de continuar uma conexão existente. A ação limita novas descobertas e demonstra resposta administrativa; ela não é um mecanismo de revogação criptográfica.
Contrato entre Discourse e sidecar
O sidecar não deve consultar a API pública do Discourse em cada announce. Isso transferiria latência e carga para o fórum. Use sincronização orientada a eventos e cache local.
Comandos do plugin para o sidecar
PUT /internal/v1/users/{user_id}
DELETE /internal/v1/users/{user_id}/passkeys/{version}
PUT /internal/v1/torrents/{info_hash}
DELETE /internal/v1/torrents/{info_hash}
POST /internal/v1/policies/reload
GET /internal/v1/health
Eventos do sidecar
{
"event_id": "01J...",
"user_id": 42,
"torrent_id": 913,
"peer_fingerprint": "digest",
"uploaded_delta": 1048576,
"downloaded_delta": 0,
"seed_seconds_delta": 1800,
"event": "update",
"observed_at": "2026-08-24T18:00:00Z"
}
Use mTLS ou HMAC com timestamp e nonce para chamadas internas. Tokens administrativos nunca devem aparecer em query strings. A API de administração fica numa rede privada, inacessível pela internet. Eventos têm IDs únicos e processamento idempotente; reenviar um lote não pode duplicar créditos.
Cache e consistência
- Cache positivo de usuário/passkey: curto, por exemplo 5 minutos.
- Cache negativo: muito curto, para não perpetuar erro de sincronização.
- Banimentos e rotações: canal de invalidação imediato.
- Info-hashes permitidos: snapshot local mais eventos incrementais.
- Falha do Discourse: tracker continua com cache por uma janela limitada.
- Falha da fila: eventos ficam em spool durável no sidecar.
- Reconciliação: job diário compara totais, torrents e usuários.
Contabilidade e ratio
Os campos uploaded e downloaded são informados pelo próprio cliente. Portanto, ratio de tracker privado é uma métrica útil de incentivo, mas não uma medição criptograficamente confiável. Clientes modificados podem mentir.
Regras mínimas para reduzir fraude e erro
- Contadores devem ser inteiros não negativos e monotônicos dentro da sessão.
- Reinício do cliente abre uma nova sessão controlada, não um delta negativo.
- Delta máximo deve ser compatível com tempo decorrido e um teto configurável.
downloaded + leftdeve ser plausível em relação ao tamanho, admitindo rechecks.completeddeve ser idempotente.- O mesmo
peer_idem locais incompatíveis gera alerta, não banimento automático. - Muitas passkeys no mesmo IP não significam fraude por si só: NAT e seedboxes são comuns.
- Mudança de IP também não é fraude por si só: conexões móveis e VPNs mudam.
- Créditos especiais, freeleech e double upload devem ser aplicados no agregador, com versão da política registrada.
- Correções administrativas precisam gerar lançamentos de ajuste, não edição silenciosa.
Política inicial recomendada
Não comece com banimento automático por ratio. Nas primeiras versões, exiba upload, download, tempo de seed e torrents semeados, mas use intervenções graduais:
- aviso;
- limitação de novos downloads;
- período de recuperação;
- revisão humana;
- suspensão somente após evidência consistente.
Um sistema pequeno ganha mais com metas de tempo de seed e pedidos de reseed do que com uma economia complexa de bônus.
Segurança
Ameaças prioritárias
| Ameaça | Consequência | Controle principal |
|---|---|---|
| Vazamento de passkey | Terceiro anuncia e atribui tráfego à vítima | rotação imediata, digest no banco, logs redigidos, HTTPS |
.torrent malformado |
consumo de CPU/memória, parser crash ou caminhos perigosos | limites rígidos, parser canônico, fuzzing, processamento isolado |
| Announce flood | indisponibilidade do tracker ou fórum | sidecar isolado, rate limits por token/IP, intervalos e proteção de borda |
| Falsificação de contadores | ratio e reputação incorretos | deltas monotônicos, limites plausíveis, alertas e revisão |
| Enumeração de swarms | exposição de catálogo e atividade | info-hash whitelist, scrape autenticado, sem full scrape público |
| Usuário suspenso ainda ativo | acesso após banimento | invalidação push e TTL curto |
| Proxy mal configurado | IPs falsos nos logs e peers | confiar apenas em endereços explícitos do proxy |
| Logs contendo segredos | comprometimento em backup ou observabilidade | filtro de URL, nunca registrar caminho completo do announce |
| CSRF em administração | alteração de política | controles nativos do Discourse, POST autenticado e permissões Guardian |
| SSRF por web seed | servidor acessa destinos internos | não buscar URLs do torrent; allowlist se houver verificação externa |
| XSS em nomes de arquivos | ataque à interface do catálogo | escapar toda saída; nomes são bytes não confiáveis |
| Plugin quebrado após atualização | perda de acesso ou exposição | CI contra versões suportadas e staging antes de atualizar Discourse |
Passkeys
- Gere pelo menos 32 bytes aleatórios e represente em base64url ou hexadecimal.
- Não derive do ID do usuário, e-mail ou senha.
- Armazene
HMAC-SHA-256(chave_do_servidor, passkey)para permitir busca sem guardar o segredo bruto. - Separe a chave HMAC dos bancos e backups.
- Nunca mostre a passkey em HTML reutilizável, analytics, referer ou logs.
- O endpoint de download insere a credencial diretamente no arquivo.
- Permita rotação por usuário e por moderador.
- Apague a passkey de mensagens de erro e páginas de suporte.
- Configure Nginx, CDN e APM para registrar
/announce/[REDACTED].
Uploads seguros
O código atual do Discourse possui uploads seguros ligados ao contexto de posts privados e pode produzir URLs assinadas em armazenamento externo. A configuração exige armazenamento S3 antes de habilitar secure_uploads, conforme as validações do próprio projeto. Para esta aplicação há duas escolhas válidas:
- Usar uploads seguros do Discourse para o metainfo canônico, garantindo que o tópico esteja numa categoria restrita.
- Usar um bucket privado exclusivo do plugin e servir o arquivo somente pelo controller personalizado.
A segunda opção torna a personalização e o controle de cache mais explícitos. Em nenhuma delas o objeto canônico deve conter passkey.
Privacidade inerente ao BitTorrent
Membros de uma swarm recebem IP e porta de outros membros. O operador também associa conta, passkey, info-hash, IP, cliente, tempo e contadores. Isso forma um conjunto sensível do ponto de vista de privacidade operacional, mesmo quando o conteúdo é legítimo.
O produto deve explicar claramente:
- quais dados são coletados;
- para que são usados;
- por quanto tempo ficam;
- quem da equipe pode vê-los;
- que outros peers verão o IP durante a transferência;
- como solicitar acesso, correção e eliminação quando aplicável;
- quais dados precisam ser preservados por obrigação ou defesa de direitos.
Aspectos jurídicos no Brasil
Direitos autorais
A Lei nº 9.610/1998 reserva ao titular formas de reprodução, distribuição e disponibilização de obras. Ser um grupo fechado ou exigir convite não transforma automaticamente uma cópia não autorizada em uso permitido.
Uma operação defensável deve aceitar somente:
- material criado pelo uploader;
- software e mídia sob licença que permita redistribuição;
- domínio público verificado;
- conteúdo institucional com autorização documentada;
- backups e datasets cuja circulação entre membros esteja permitida.
O formulário de envio deve exigir declaração de origem e base de autorização. Categorias de maior risco podem exigir prova documental antes da publicação. Deve haver termos, política de retirada, canal de contato e registro das decisões.
Registros e responsabilidade do provedor
O Marco Civil da Internet, Lei nº 12.965/2014, contém regras sobre sigilo, disponibilização de registros e guarda de registros de acesso para determinados provedores de aplicações constituídos como pessoa jurídica, em atividade organizada, profissional e com fins econômicos. A incidência concreta e os prazos aplicáveis dependem da natureza da operação; devem ser definidos com assessoria jurídica antes do lançamento.
Não confunda retenção obrigatória de registros com autorização para guardar tudo indefinidamente. Logs técnicos, eventos de moderação e contabilidade devem ter finalidades e prazos diferentes.
LGPD
A LGPD, Lei nº 13.709/2018, exige finalidade, necessidade, segurança, transparência e direitos dos titulares. Neste sistema, IP deixa de ser um identificador técnico isolado porque está diretamente associado à conta, ao histórico e à atividade.
A ANPD publica guia e checklist de segurança para agentes de pequeno porte. A página atual de comunicação de incidentes explica que incidentes confirmados envolvendo dados pessoais e capazes de causar risco ou dano relevante podem exigir comunicação à ANPD e aos titulares.
Antes de operar:
- faça inventário de dados e bases legais;
- documente retenção;
- limite acesso administrativo;
- proteja backups;
- estabeleça canal para titulares;
- prepare resposta a incidentes;
- avalie um RIPD se escala, monitoramento ou risco justificarem;
- obtenha revisão jurídica específica.
Infraestrutura recomendada
Ambiente pequeno
VPS 1: Discourse oficial em contêiner
PostgreSQL + Redis + Sidekiq + plugin
VPS 2: tracker sidecar
Chihaya customizado + Redis + Prometheus
Armazenamento:
bucket S3 compatível privado para metainfo e backups
Seed inicial:
qBittorrent ou Transmission em servidor separado
É possível começar numa única máquina com contêineres separados, mas separar o tracker reduz o impacto de flood e facilita escalar. O domínio também deve ser separado, por exemplo forum.exemplo.org e tracker.exemplo.org.
Componentes
| Componente | Escolha inicial | Motivo |
|---|---|---|
| Comunidade | Discourse self-hosted | plugin de servidor exige controle da instalação |
| Tracker | Chihaya com middleware próprio | desenho extensível e licença permissiva |
| Catálogo | tabelas do plugin + tópicos | une metadados estruturados e discussão |
| Banco durável | PostgreSQL do Discourse | integra usuários e catálogo |
| Estado efêmero | Redis separado do tracker | peers e cache não disputam com o fórum |
| Fila | Redis Streams, NATS JetStream ou HTTP em lotes com spool | entrega de eventos e retentativa |
| Objetos | S3 compatível privado | metainfo canônico, backup e URLs controladas |
| Proxy | Nginx ou HAProxy | TLS, IP real, limites e logs redigidos |
| Métricas | Prometheus + Grafana | saúde do tracker e capacidade |
| Logs | Loki ou equivalente, com redaction | investigação sem expor passkeys |
| Seeder | qBittorrent/Transmission isolado | disponibilidade inicial do conteúdo autorizado |
Não compartilhe automaticamente o Redis do Discourse com o tracker. Use instância, ACL ou pelo menos credenciais, namespace e limites separados. O tracker deve poder falhar sem corromper sessões e filas do fórum.
Etapas de desenvolvimento
Fase 0 — Prova técnica, 3 a 7 dias
- Subir Discourse de desenvolvimento.
- Criar plugin pelo esqueleto oficial.
- Associar um registro de torrent a um tópico.
- Aceitar um
.torrentde teste autorizado. - Personalizar apenas o campo
announce. - Executar um tracker local simples.
- Transferir um pequeno arquivo entre dois clientes.
- Confirmar que DHT e PEX ficam desativados.
Saída: prova de que metainfo, passkey e experiência no tópico funcionam.
Fase 1 — Protótipo funcional, 2 a 4 semanas
- Contas de tracker ligadas a usuários.
- Passkey por usuário e rotação.
- Upload, parsing e aprovação manual.
- Catálogo
/torrentsbásico. - Download personalizado.
- Sidecar HTTPS com lista permitida.
- Seeders/leechers na página.
- Suspensão sincronizada.
- Logs redigidos e testes principais.
Decisão importante: nesta fase, contabilize atividade para observação, mas não aplique punição automática por ratio.
Fase 2 — MVP confiável, 6 a 10 semanas adicionais
- Chihaya e middlewares próprios.
- Fila durável e eventos idempotentes.
- Contabilidade por usuário/torrent.
- Seed time, reseed e políticas graduais.
- Painel administrativo.
- Denúncias e retirada.
- Métricas, alertas e backups.
- Fuzz tests para bencode.
- Testes com qBittorrent, Transmission, Deluge, rTorrent e libtorrent.
- Staging para atualizações do Discourse.
Fase 3 — Produção ampliada, 2 a 4 meses adicionais
- IPv6 completo.
- Réplicas do tracker e Redis HA.
- Passkey por torrent opcional.
- Clientes permitidos ou observados.
- Freeleech, bônus e slots, apenas se a comunidade realmente precisar.
- API documentada para automação.
- Exportação e exclusão de dados.
- Auditoria externa de segurança.
- Procedimentos jurídicos e de incidentes testados.
As durações são estimativas para uma pessoa experiente em Rails/Discourse e Go. Quem estiver aprendendo as duas plataformas deve multiplicar os prazos. A complexidade principal não é desenhar a tela; é manter autorização e contabilidade corretas sob concorrência, falhas e clientes não confiáveis.
Testes indispensáveis
Plugin
- Migrações em instalação nova e atualização.
- Permissões para anônimo, membro, uploader, moderador e administrador.
- Download negado após suspensão.
- Passkey nunca presente em serializer, log ou HTML.
- Info-hash igual antes e depois da personalização do
announce. - Upload duplicado e torrent bloqueado.
- Tópico movido entre categorias com permissões diferentes.
- Remoção, restauração e retenção de metainfo.
- Compatibilidade com versão estável e
tests-passeddo Discourse.
Parser
- Bencode truncado, chaves fora de ordem e inteiros inválidos.
- Estruturas profundamente aninhadas.
- Milhões de arquivos declarados em objeto pequeno.
- Tamanhos negativos, overflow e somas inconsistentes.
- Caminhos absolutos,
.., caracteres nulos e Unicode problemático. - v1, v2 e híbrido.
private=0, ausente e duplicado.- Múltiplos trackers, DHT nodes e web seeds.
- Round-trip preservando exatamente o dicionário
info.
Tracker
- Passkey válida, inválida, revogada e rotacionada.
- Torrent permitido, pendente e bloqueado.
started, atualização,completed,stoppede timeout.- Dois peers atrás do mesmo NAT.
- IPv4 e IPv6.
- Contadores reiniciados após crash do cliente.
- Reenvio do mesmo lote sem duplicar créditos.
- Fórum indisponível e fila indisponível.
- Flood, announce antes do intervalo e payload excessivo.
- Nenhuma passkey em métricas ou logs.
Teste de ponta a ponta
- Criar arquivo aleatório autorizado.
- Gerar torrent privado.
- Publicar e aprovar.
- Baixar como usuário A e iniciar seed.
- Baixar como usuário B e concluir transferência.
- Conferir peers e contadores.
- Rotacionar passkey de B e observar falha controlada.
- Baixar novamente e recuperar acesso.
- Bloquear torrent e confirmar que novos announces falham.
- Restaurar a partir de backup em ambiente limpo.
Critérios de aceitação do MVP
O produto só deve ser chamado de tracker privado funcional quando:
- nenhum torrent não aprovado consegue anunciar;
- nenhum membro suspenso continua autenticando após a janela definida;
.torrentbaixado por um usuário não contém a passkey de outro;- personalizar o announce não muda o info-hash;
- passkeys não aparecem em logs, analytics ou erros;
- eventos reenviados não duplicam tráfego;
- o tracker continua respondendo durante indisponibilidade curta do fórum;
- a falha do tracker não derruba o Discourse;
- anônimos não veem catálogo, arquivos ou estatísticas;
- a equipe consegue bloquear torrent e conta rapidamente;
- backup e restauração foram ensaiados;
- política de conteúdo, privacidade e denúncia está publicada.
Custos e capacidade
Para uma comunidade pequena, o custo de infraestrutura tende a ser modesto porque o tracker não transporta os arquivos; ele troca mensagens pequenas de descoberta. O tráfego pesado ocorre entre peers e no seeder inicial.
Uma implantação inicial pode operar com:
- Discourse em configuração compatível com suas exigências oficiais;
- sidecar com 1 a 2 vCPU e 1 a 2 GB de RAM;
- Redis pequeno para peers;
- armazenamento de objetos quase irrelevante em volume, pois
.torrenté pequeno; - monitoramento e backups.
Esses números são estimativas, não requisitos garantidos. Capacidade depende de usuários simultâneos, intervalo de announce, número de torrents e política de retenção. Faça teste de carga com a distribuição esperada, não apenas benchmark de requisições vazias.
O verdadeiro custo está no desenvolvimento, atualizações do Discourse, moderação, segurança e gestão jurídica. Um tracker tecnicamente leve pode ser operacionalmente exigente.
O que não construir no começo
- UDP autenticado.
- Aplicativo móvel próprio.
- Streaming no navegador.
- Integrações com debrid.
- DHT privado customizado.
- Sistema de moedas e loja de bônus.
- Convites negociáveis.
- Ranks automáticos complexos.
- Scraper de terceiros.
- Metadados automáticos para todas as mídias.
- IA moderando direitos autorais.
- Cliente BitTorrent próprio.
- Alterações profundas no núcleo do Discourse.
Esses itens aumentam superfície de abuso e manutenção sem provar o valor central: comunidade Discourse, publicação controlada e distribuição P2P privada.
Alternativa pragmática sem desenvolver tudo
Se o objetivo principal for operar um tracker convencional rapidamente, instale UNIT3D e mantenha o Discourse como comunidade externa. Use um provedor de identidade comum, links cruzados e criação automática de tópicos para torrents aprovados. É menos elegante, mas reduz muito o trabalho inicial.
Se o objetivo for realmente criar um produto novo e potencialmente publicável para outras comunidades Discourse, construa o plugin + sidecar. Esse projeto tem uma proposta clara: transformar tópicos privados em distribuições P2P autorizadas sem substituir a comunidade por um frontend clássico de tracker.
Recomendações práticas
Escolha recomendada
- Nomeie provisoriamente o projeto
discourse-private-tracker. - Faça o plugin ser a autoridade de usuário, catálogo e política.
- Use Chihaya com middleware próprio como sidecar de produção.
- Comece apenas com announce HTTPS e torrents v1 privados.
- Use tópicos como páginas editoriais e uma rota
/torrentspara filtros. - Gere o
.torrentpersonalizado no download; nunca armazene passkeys nos objetos. - Mantenha peers em Redis e totais consolidados em PostgreSQL.
- Sincronize bloqueios imediatamente e demais dados por eventos idempotentes.
- Não puna ratio automaticamente no MVP.
- Restrinja o projeto a conteúdo autorizado e implemente retirada antes do lançamento.
Primeira especificação de produto
O primeiro lançamento precisa de apenas seis telas:
- catálogo de torrents;
- página do torrent integrada ao tópico;
- formulário de envio;
- fila de aprovação;
- painel pessoal com atividade e rotação de passkey;
- painel administrativo de usuários, torrents e saúde do tracker.
Primeira decisão de engenharia
Antes de escrever toda a interface, construa um experimento vertical:
tópico privado -> upload canônico -> aprovação -> download personalizado
-> qBittorrent A -> announce -> qBittorrent B -> transferência -> estatística no tópico
Se esse percurso funcionar com dois clientes reais, passkey rotacionável e bloqueio imediato, a ideia está tecnicamente provada. Só então vale investir em ratio, badges e automações.
Conclusão
Transformar o Discourse em um tracker privado é possível e pode resultar num produto interessante. O Discourse resolve justamente a parte que muitos softwares de tracker tratam de maneira secundária: comunidade, conversação, identidade, confiança e moderação. O protocolo BitTorrent acrescenta uma forma eficiente de distribuir arquivos sem transformar o servidor web num repositório de grandes downloads.
A implementação correta não coloca o announce dentro do fórum. Ela cria um plugin de integração profundo e um tracker sidecar especializado. Entre as bases pesquisadas, Chihaya oferece o melhor encaixe arquitetural; Torrust é a alternativa moderna; bittorrent-tracker é o caminho de protótipo; e UNIT3D é a referência para funções e regras, mas não deve ser fundido ao Discourse no primeiro momento.
O projeto é de dificuldade média para demonstrar e alta para operar com segurança. Um protótipo legítimo pode surgir em poucas semanas. Um tracker público para terceiros, com contabilidade confiável, políticas, privacidade, atualização contínua e resistência a abuso, é um produto de meses. Ainda assim, a ideia é tecnicamente coerente, relativamente original e vale um protótipo vertical.
Fontes consultadas
- Discourse — repositório oficial
- Discourse — introdução à arquitetura e plugins
- Discourse — estrutura de plugin com Rails Engine
- Discourse — API JavaScript para plugins
- Discourse — plugin outlets
- Discourse — esqueleto oficial de plugin
- Discourse — catálogo de plugins conhecidos
- Discourse — diretório oficial de plugins
- Discourse — grupos e permissões de categorias
- Discourse — comunidade fechada ou privada
- Discourse — controlador de uploads
- Discourse — regras de segurança de uploads
- BitTorrent BEP 3 — especificação do protocolo
- BitTorrent BEP 15 — protocolo UDP para tracker
- BitTorrent BEP 27 — torrents privados
- BitTorrent BEP 52 — protocolo e metainfo v2
- Chihaya — tracker extensível em Go
- Chihaya — arquitetura de middlewares e storage
- Chihaya — licença BSD-2-Clause
- Chihaya Privtrak Middleware — referência experimental
- Torrust Tracker — tracker moderno em Rust
- Torrust Index — API e catálogo de torrents
- UNIT3D — plataforma completa de tracker privado
- UNIT3D — controlador de announce
- UNIT3D-Announce — tracker Rust de alto desempenho
- bittorrent-tracker — implementação Node.js
- Aquatic — tracker de alto desempenho em Rust
- opentracker — tracker aberto minimalista
- Ocelot — tracker histórico do Gazelle
- bencode — biblioteca Ruby
- Bendy — biblioteca bencode canônica para Rust
- Lei nº 9.610/1998 — Direitos Autorais
- Lei nº 12.965/2014 — Marco Civil da Internet
- Lei nº 13.709/2018 — LGPD
- ANPD — guia de segurança para agentes de pequeno porte
- ANPD — comunicação de incidente de segurança
Nota sobre atualidade
Pesquisa concluída em 24 de agosto de 2026. Discourse, Chihaya, Torrust, UNIT3D e suas APIs evoluem continuamente. Confirme versões, licenças, compatibilidade e documentação oficial antes de iniciar a implementação. Aspectos jurídicos exigem avaliação profissional aplicada ao conteúdo, à operação e à jurisdição escolhida.