
curlと似ていますが、AnubisやCloudflareのボット対策を回避します。
$ nix run github:fzakaria/anubis-fetch -- --text https://lore.kernel.org/
Anubisのプルーフ・オブ・ワークチャレンジの背後にあるURLを取得するためのGo CLIです。レガシーなSHA-256およびWASMチャレンジをインプロセスで解決し、フォールバックとしてヘッドレスChromiumを使用します。
lore.kernel.orgやkernel.orgなどのサイトは、ページを提供する前にプルーフ・オブ・ワークを要求するためにAnubisを使用しています。通常のHTTPクライアントは、要求されたコンテンツの代わりにチャレンジページを受け取る可能性があります。anubis-fetchはチャレンジを解決し、回答を送信し、結果のページをstdoutに書き込みます。
reqを使用してChromeのTLSおよびHTTP/2フィンガープリントを偽装します。これはCloudflareのものを含むパッシブなボットチェックに役立ちます。Anubisのfastおよびslowメソッドでは、ツールはnonceを計算し、回答を直接送信します。WASMメソッドのsha256、argon2id、hashxでは、サイトのモジュールをダウンロードし、wazeroを使用してGoで実行します。chromedpによって駆動され、サイトが提供するチャレンジコードを実行します。ブラウザフォールバックは、Anubisのpreactおよびmetarefreshメソッド、およびCloudflareチャレンジページ(cf-mitigated: challengeを含むレスポンス)を処理します。このツールは、レガシーSHA-256の難易度が制限を超えた場合、WASMの実行が失敗またはタイムアウトした場合、またはAnubisが解答を拒否した場合にもフォールバックします。--browserを使用してChromiumで開始するか、--no-browserを使用してHTTPパスを必須にします。3つのWASMメソッドはすべて--no-browserで動作します。
ネイティブソルバーは、フェッチごとにブラウザプロセスを起動することを避けます。Chromiumはフォールバックが必要なチャレンジのためにNixパッケージに依然として含まれています。
元のSHA-256パスのおおよそのフェッチ時間:
| パス | 実時間 | Chromiumが必要 |
|---|---|---|
| インプロセスSHA-256ソルバー | 約0.6秒 | いいえ |
| ブラウザフォールバック | 約2.0秒 | はい |
難易度2のローカルAnubisサーバーに対するWASMフェッチ時間:
| WASMメソッド | 中央値実時間 | Chromiumが必要 |
|---|---|---|
| SHA-256 | 約0.025秒 | いいえ |
| Argon2id | 約0.55秒〜2.33秒 | いいえ |
| HashX | 約0.041秒 | いいえ |
fastおよびslowメソッドでは、Anubisはチャレンジをページに埋め込みます:
{"rules":{"algorithm":"fast","difficulty":4},
"challenge":{"id":"...","method":"fast","randomData":"6214bd88...","difficulty":4}}
ソルバーは、hex(sha256(randomData || nonce))がdifficulty個のゼロ文字で始まるようなnonceを探します。nonceは10進数文字列としてエンコードされます。回答はAnubisに送信されます:
GET /.within.website/x/cmd/anubis/api/pass-challenge?id=...&response=<hash>&nonce=<n>&redir=<url>&elapsedTime=<ms>
成功したレスポンスは認証Cookieを設定し、要求されたページにリダイレクトします。難易度4では、平均して約65,536回のハッシュ計算が必要です。
sha256、argon2id、hashxでは、Anubisはプルーフ・オブ・ワークを実装するWebAssemblyモジュールを提供します。anubis-fetchはモジュールをダウンロードし、チャレンジの16進データをバイトにデコードし、データと難易度をモジュールに渡します。モジュールはnonceを検索し、上記と同じエンドポイントに送信するためのnonceとハッシュを返します。
モジュールはwazeroを使用してGoプロセス内で実行されるため、これらのメソッドは--no-browserで動作します。実行にはメモリと時間の制限があります。難易度ルールはモジュールが定義します。WASMの難易度数値は、レガシーSHA-256メソッドと直接比較することはできません。
直接実行:
$ nix run github:fzakaria/anubis-fetch -- <url>
または、flakeに入力を追加します:
{
inputs.anubis-fetch.url = "github:fzakaria/anubis-fetch";
}
inputs.anubis-fetch.packages.${system}.defaultをhome.packagesまたはenvironment.systemPackagesに追加します。
anubis-fetch [flags] URL
| フラグ | 効果 |
|---|---|
--text | HTMLをプレーンテキストに変換 |
--timeout MS | ステップごとのタイムアウトをミリ秒で設定;デフォルトは30000 |
--ua STRING | User-Agentを設定 |
--browser | Chromiumを直接使用 |
--no-browser | HTTPソルバーがブラウザフォールバックを必要とする場合に終了コード3で終了 |
--no-cache | 保存されたCookieの読み書きを無効化 |
--help, -h | 使用方法を表示して終了 |
# HTMLをstdoutへ
anubis-fetch https://lore.kernel.org/
# プレーンテキスト
anubis-fetch --text https://lore.kernel.org/
# HTTPパスを必須にする;終了ステータス3を確認
anubis-fetch --no-browser https://lore.kernel.org/
Cookieはホストごとに$XDG_CACHE_HOME/anubis-fetch/cookies/<host>.json、またはXDG_CACHE_HOMEが未設定の場合は~/.cache/anubis-fetch/cookies/<host>.jsonに保存されます。有効な認証Cookieがあれば、以降のリクエストでチャレンジをスキップできます。Chromiumを通じて取得されたCookieも、ChromiumのUser-Agentとともに保存されます。Cloudflareはcf_clearanceを、それを取得したUser-Agentの下でのみ尊重するため、そのホストへの以降のHTTPリクエストは、--uaで上書きしない限り、保存されたUser-Agentを送信します。
--no-cacheを使用して保存されたCookieなしでフェッチするか、ホストのファイルを削除してCookieを破棄します。期限切れまたは拒否されたCookieは、新しいチャレンジを必要とします。
$ nix develop # Go, gopls, Chromium, treefmt
$ go test ./... # Go unit tests
$ nix build # Packaged CLI
$ nix flake check # Builds, tests, and formatting
$ nix fmt # Format Go and Nix