
Come curl, ma supera i muri anti-bot di Anubis e Cloudflare.
$ nix run github:fzakaria/anubis-fetch -- --text https://lore.kernel.org/
Una CLI Go per recuperare URL protetti dalle sfide proof-of-work di Anubis. Risolve le sfide legacy SHA-256 e WASM in-process, con Chromium headless come fallback.
Siti come lore.kernel.org e kernel.org usano Anubis per richiedere una proof of work prima di servire una pagina. Un semplice client HTTP può ricevere la pagina della sfida invece del contenuto richiesto. anubis-fetch risolve la sfida, invia la risposta e scrive la pagina risultante su stdout.
req per impersonare il fingerprint TLS e HTTP/2 di Chrome. Questo può aiutare con i controlli bot passivi, incluso quello di Cloudflare.
Per i metodi fast e slow di Anubis, lo strumento calcola un nonce e invia
la risposta direttamente. Per i metodi WASM sha256, argon2id e hashx,
scarica il modulo del sito e lo esegue in Go con
wazero.chromedp, esegue il codice della sfida
servito dal sito.Il fallback del browser gestisce i metodi preact e metarefresh di Anubis, e le pagine di sfida di Cloudflare (risposte con cf-mitigated: challenge).
Lo strumento effettua il fallback anche quando la difficoltà legacy SHA-256 supera il suo limite, l'esecuzione WASM fallisce o va in timeout, o Anubis rifiuta una soluzione.
Usa --browser per iniziare con Chromium, o --no-browser per richiedere il percorso HTTP. Tutti e tre i metodi WASM funzionano con --no-browser.
Il solver nativo evita di avviare un processo browser per ogni fetch. Chromium è comunque incluso nel pacchetto Nix per le sfide che richiedono il fallback.
Tempi di fetch approssimativi per il percorso SHA-256 originale:
| Percorso | Tempo reale | Richiede Chromium |
|---|---|---|
| Solver SHA-256 in-process | ~0.6s | No |
| Fallback browser | ~2.0s | Sì |
Tempi di fetch WASM contro un server Anubis locale a difficoltà 2:
| Metodo WASM | Tempo reale mediano | Richiede Chromium |
|---|---|---|
| SHA-256 | ~0.025s | No |
| Argon2id | ~0.55s-2.33s | No |
| HashX | ~0.041s | No |
Per i metodi fast e slow, Anubis incorpora la sfida nella pagina:
{"rules":{"algorithm":"fast","difficulty":4},
"challenge":{"id":"...","method":"fast","randomData":"6214bd88...","difficulty":4}}
Il solver cerca un nonce tale che hex(sha256(randomData || nonce))
inizi con difficulty caratteri zero. Il nonce è codificato come stringa
decimale. La risposta viene inviata ad Anubis:
GET /.within.website/x/cmd/anubis/api/pass-challenge?id=...&response=<hash>&nonce=<n>&redir=<url>&elapsedTime=<ms>
Una risposta riuscita imposta un cookie di autenticazione e reindirizza alla pagina richiesta. La difficoltà 4 richiede in media circa 65.536 hash.
Per sha256, argon2id e hashx, Anubis serve un modulo WebAssembly
che implementa la proof of work. anubis-fetch scarica il modulo,
decodifica i dati esadecimali della sfida in byte e passa i dati e
la difficoltà al modulo. Il modulo cerca un nonce e restituisce
il nonce e l'hash da inviare allo stesso endpoint sopra.
Il modulo viene eseguito all'interno del processo Go usando wazero, quindi questi metodi funzionano
con --no-browser. L'esecuzione ha limiti di memoria e tempo. Il modulo
definisce le regole di difficoltà; i numeri di difficoltà WASM non sono direttamente
comparabili con il metodo legacy SHA-256.
Esegui direttamente:
$ nix run github:fzakaria/anubis-fetch -- <url>
Oppure aggiungi l'input al tuo flake:
{
inputs.anubis-fetch.url = "github:fzakaria/anubis-fetch";
}
Aggiungi inputs.anubis-fetch.packages.${system}.default a
home.packages o environment.systemPackages.
anubis-fetch [flags] URL
| Flag | Effetto |
|---|---|
--text | Converte l'HTML in testo semplice |
--timeout MS | Imposta il timeout per passo in millisecondi; predefinito 30000 |
--ua STRING | Imposta lo User-Agent |
--browser | Usa Chromium direttamente |
--no-browser | Esce con 3 se il solver HTTP necessita del fallback browser |
--no-cache | Disabilita la lettura e scrittura dei cookie salvati |
--help, -h | Stampa l'utilizzo ed esce |
# HTML su stdout
anubis-fetch https://lore.kernel.org/
# Testo semplice
anubis-fetch --text https://lore.kernel.org/
# Richiede il percorso HTTP; verifica lo stato di uscita 3
anubis-fetch --no-browser https://lore.kernel.org/
I cookie vengono salvati per host in
$XDG_CACHE_HOME/anubis-fetch/cookies/<host>.json, o
~/.cache/anubis-fetch/cookies/<host>.json quando XDG_CACHE_HOME non è impostato.
Un cookie di autenticazione valido può permettere alle richieste successive di saltare la sfida.
Anche i cookie ottenuti tramite Chromium vengono salvati, insieme allo
User-Agent di Chromium. Cloudflare onora cf_clearance solo sotto lo User-Agent che
lo ha ottenuto, quindi le successive richieste HTTP a quell'host inviano lo User-Agent salvato
a meno che --ua non lo sovrascriva.
Usa --no-cache per recuperare senza cookie salvati, o elimina il file dell'host
per scartarli. Un cookie scaduto o rifiutato richiede una nuova sfida.
$ nix develop # Go, gopls, Chromium, treefmt
$ go test ./... # Test unitari Go
$ nix build # CLI pacchettizzata
$ nix flake check # Build, test e formattazione
$ nix fmt # Formatta Go e Nix