
Como o curl, mas atravessa as proteções anti-bot do Anubis e do Cloudflare.
$ nix run github:fzakaria/anubis-fetch -- --text https://lore.kernel.org/
Uma CLI em Go para buscar URLs protegidas por desafios de prova de trabalho do Anubis. Ela resolve desafios legados de SHA-256 e WASM em processo, com Chromium headless como fallback.
Sites como lore.kernel.org e kernel.org usam o Anubis para exigir prova de trabalho antes de servir uma página. Um cliente HTTP simples pode receber a página de desafio em vez do conteúdo solicitado. O anubis-fetch resolve o desafio, envia a resposta e escreve a página resultante em stdout.
req para imitar a impressão digital TLS e HTTP/2 do Chrome. Isso pode ajudar com verificações passivas de bots, incluindo as da Cloudflare. Para os métodos fast e slow do Anubis, a ferramenta calcula um nonce e envia a resposta diretamente. Para os métodos WASM sha256, argon2id e hashx, ela baixa o módulo do site e o executa em Go com wazero.chromedp, executa o código de desafio servido pelo site.O fallback de navegador lida com os métodos preact e metarefresh do Anubis, e com páginas de desafio da Cloudflare (respostas com cf-mitigated: challenge). A ferramenta também recorre ao fallback quando a dificuldade do SHA-256 legado excede seu limite, a execução WASM falha ou expira, ou o Anubis rejeita uma solução. Use --browser para começar com o Chromium, ou --no-browser para exigir o caminho HTTP. Todos os três métodos WASM funcionam com --no-browser.
O solucionador nativo evita iniciar um processo de navegador para cada busca. O Chromium ainda está incluído no pacote Nix para desafios que precisam do fallback.
Tempos aproximados de busca para o caminho SHA-256 original:
| Caminho | Tempo real | Precisa de Chromium |
|---|---|---|
| Solucionador SHA-256 em processo | ~0,6s | Não |
| Fallback de navegador | ~2,0s | Sim |
Tempos de busca WASM contra um servidor Anubis local com dificuldade 2:
| Método WASM | Tempo real mediano | Precisa de Chromium |
|---|---|---|
| SHA-256 | ~0,025s | Não |
| Argon2id | ~0,55s-2,33s | Não |
| HashX | ~0,041s | Não |
Para os métodos fast e slow, o Anubis incorpora o desafio na página:
{"rules":{"algorithm":"fast","difficulty":4},
"challenge":{"id":"...","method":"fast","randomData":"6214bd88...","difficulty":4}}
O solucionador procura um nonce tal que hex(sha256(randomData || nonce)) comece com difficulty caracteres zero. O nonce é codificado como uma string decimal. A resposta é enviada ao Anubis:
GET /.within.website/x/cmd/anubis/api/pass-challenge?id=...&response=<hash>&nonce=<n>&redir=<url>&elapsedTime=<ms>
Uma resposta bem-sucedida define um cookie de autenticação e redireciona para a página solicitada. A dificuldade 4 exige cerca de 65.536 hashes em média.
Para sha256, argon2id e hashx, o Anubis serve um módulo WebAssembly que implementa a prova de trabalho. O anubis-fetch baixa o módulo, decodifica os dados hex do desafio em bytes e passa os dados e a dificuldade para o módulo. O módulo procura um nonce e retorna o nonce e o hash para envio ao mesmo endpoint acima.
O módulo é executado dentro do processo Go usando wazero, então esses métodos funcionam com --no-browser. A execução tem limites de memória e tempo. O módulo define as regras de dificuldade; números de dificuldade WASM não são diretamente comparáveis ao método SHA-256 legado.
Execute diretamente:
$ nix run github:fzakaria/anubis-fetch -- <url>
Ou adicione a entrada ao seu flake:
{
inputs.anubis-fetch.url = "github:fzakaria/anubis-fetch";
}
Adicione inputs.anubis-fetch.packages.${system}.default a home.packages ou environment.systemPackages.
anubis-fetch [flags] URL
| Flag | Efeito |
|---|---|
--text | Converte HTML em texto simples |
--timeout MS | Define o timeout por etapa em milissegundos; padrão 30000 |
--ua STRING | Define o User-Agent |
--browser | Usa o Chromium diretamente |
--no-browser | Sai com código 3 se o solucionador HTTP precisar do fallback de navegador |
--no-cache | Desativa a leitura e gravação de cookies salvos |
--help, -h | Imprime o uso e sai |
# HTML para stdout
anubis-fetch https://lore.kernel.org/
# Texto simples
anubis-fetch --text https://lore.kernel.org/
# Exige o caminho HTTP; verifica o status de saída 3
anubis-fetch --no-browser https://lore.kernel.org/
Os cookies são salvos por host em $XDG_CACHE_HOME/anubis-fetch/cookies/<host>.json, ou ~/.cache/anubis-fetch/cookies/<host>.json quando XDG_CACHE_HOME não está definido. Um cookie de autenticação válido pode permitir que requisições subsequentes pulem o desafio. Cookies obtidos através do Chromium também são salvos, junto com o User-Agent do Chromium. A Cloudflare só honra cf_clearance sob o User-Agent que o obteve, então requisições HTTP posteriores para esse host enviam o User-Agent salvo, a menos que --ua o substitua.
Use --no-cache para buscar sem cookies salvos, ou exclua o arquivo do host para descartá-los. Um cookie expirado ou rejeitado exige um novo desafio.
$ nix develop # Go, gopls, Chromium, treefmt
$ go test ./... # Testes unitários Go
$ nix build # CLI empacotada
$ nix flake check # Builds, testes e formatação
$ nix fmt # Formata Go e Nix