1

Pitch: Anonimato de verdade: por que fugimos de CDN e apostamos no Tor via Arti

Estamos construindo o Zero Note, um app de notas criptografadas de ponta a ponta e sem cadastro pessoal (sem e-mail, sem telefone, sem nome). Um dos princípios do projeto é que o servidor é burro: ele guarda blobs cifrados e não consegue ler nada. Mas criptografia no conteúdo resolve só metade do problema. A outra metade é metadado de conexão e é sobre isso que quero falar aqui: a decisão de tirar o servidor de trás de qualquer CDN de terceiros e expor um endereço .onion usando Arti, a implementação do Tor em Rust.

O problema que criptografia não resolve

Cifrar o conteúdo da nota é a parte "fácil". O problema chato é que, mesmo com tudo cifrado, alguém no meio do caminho ainda enxerga:

  • o IP de quem conectou;
  • quando e com que frequência essa conta sincroniza;
  • o tamanho aproximado de cada objeto trafegado.

Nenhuma dessas coisas é "conteúdo", mas juntas elas já dizem bastante sobre quem é a pessoa e o que ela está fazendo. Um adversário não precisa ler a nota se consegue correlacionar IP + horário + padrão de uso.

Por que isso descarta CDN gerenciado

A tentação óbvia seria colocar um CDN/proxy gerenciado na frente (Cloudflare e afins) por causa de TLS fácil, proteção contra DDoS e performance. O problema: esse tipo de serviço vê e normalmente registra o IP de cada conexão na própria borda da rede, antes de qualquer linha de código nosso rodar. Não importa o quão cuidadoso o nosso backend, ou seja, o vazamento já aconteceu uma camada antes.

Por isso a decisão foi: servidor próprio, em VPS, sem CDN de terceiros. A pilha ficou:

CamadaEscolhaMotivo
AplicaçãoRust (axum)Reaproveita o mesmo núcleo de criptografia do cliente
MetadadosPostgreSQLLogin, autenticação OPAQUE, sessões
BlobsMinIO (S3-compatible)Nunca exposto direto ao cliente, tudo passa pela aplicação
BordaCaddy/nginx no próprio VPSTLS, com logs de acesso desligados (sem IP, sem user agent completo)
Camada anônimaTor via ArtiEndereço .onion nativo, sem IP de origem visível

Arti: Tor, mas em Rust

A parte que mais vale comentar é o Tor. A decisão não foi "vamos adicionar Tor como feature exótica depois" é desde o início, com o .onion sempre disponível em paralelo ao acesso clearnet normal (que continua existindo porque Tor tem latência maior, pode ser bloqueado por operadoras, e nem toda loja de app aceita dependência exclusiva de Tor).

A escolha de implementação foi Arti em vez do daemon tor tradicional em C, por três razões práticas:

  1. É mantido pelo próprio Tor Project não é um fork de terceiros nem uma reimplementação não-oficial;
  2. É a reescrita oficial em Rust, e o próprio Tor Project pretende substituir o daemon C por ele a médio prazo;
  3. Evita misturar duas linguagens/stacks no servidor, já que a aplicação inteira é Rust (axum).

No app, vai existir nas Configurações "Conexão anônima (Tor)" ligada por padrão. Quando equanto ligada, o tráfego passa pelo .onion, escondendo o IP tanto do operador do servidor quanto de qualquer observador de rede no meio do caminho. Resolvemos deixar como opcional isso devido ao aumento de consumo de bateria que tem.

É importante ser honesto sobre o que isso resolve e o que não resolve:

  • Resolve: o operador do servidor e um observador de rede deixam de ver o IP de origem de quem usa o .onion.
  • Não resolve: o conteúdo. Esse já estava protegido antes, por criptografia ponta a ponta independente do Tor. Tor protege o metadado de conexão, não o conteúdo.

Antes de ir para produção, ainda temos umas validações pendentes: desempenho do serviço onion sob carga esperada, estabilidade do processo por período longo (dias) e compatibilidade com a versão do axum escolhida. Se algo falhar de forma grave nesses testes, a decisão é revisitada, mas a intenção declarada é não precisar rodar o daemon tor em paralelo como plano B.

Dois anonimatos diferentes, para um entendimento maior das escolhas

Um ponto que gerou confusão interna no início do projeto, e vale deixar explícito: existem dois anonimatos separados, e é fácil misturá-los por engano.

  1. Anonimato de quem usa o app: vem do Tor, da ausência de IP em logs e da criptografia ponta a ponta. Não depende de qual empresa hospeda o servidor.
  2. Anonimato de quem opera o serviço: é sobre o provedor de VPS saber (ou não) quem é a empresa por trás do servidor. Isso é segurança operacional do negócio, não da pessoa que escreve a nota.

Separar essas duas coisas destrava a escolha de provedor: dá pra priorizar custo-benefício e estabilidade de infraestrutura sem comprometer a privacidade de quem usa o produto. No caso do Zero Note, e da zerox1b, a decisão foi Hetzner (Alemanha, sob RGPD), mesmo exigindo KYC da empresa, porque esse KYC é sobre quem opera o negócio, não sobre quem escreve as notas. Quem precisa de distância entre a infraestrutura e o registro público (ex.: Njalla) ou de um provedor já alinhado com o discurso de privacidade (ex.: 1984 Hosting, na Islândia) está resolvendo o segundo problema, não o primeiro. Como a nosso plano é apenas fornecer anonimato para o usuário, optamos pela Hetzner.

Resumindo

Se o objetivo é anonimato de verdade para quem usa o produto, dá para listar três decisões de infraestrutura que, juntas, fecham boa parte do buraco que a criptografia sozinha não fecha:

  1. Nenhum CDN de terceiros na frente: ele vê o IP antes do seu código rodar.
  2. .onion desde o início, via Arti, não como feature tardia.
  3. Separar anonimato do usuário de anonimato do operador: são problemas diferentes, com soluções diferentes, e misturá-los trava decisões que não precisam travar.

Esse é um corte do que estamos decidindo no Zero Note. Pretendo trazer mais artigos conforme o projeto avança, próximo na fila deve ser a hierarquia de chaves.

Carregando publicação patrocinada...