Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Web Bot Auth

最終更新 Markdown で表示Agent セットアップ

Web Bot Auth は、HTTP メッセージの暗号署名で、リクエストが自動ボットからのものであることを確認する認証方式です。Web Bot Auth は 検証済みボットとエージェント の検証方法として使われます。

IETF のドラフトに依拠します。クローラーが公開鍵を共有するための ディレクトリドラフト と、これらの鍵でクローラーの身元を HTTP リクエストに付ける方法を定める プロトコルドラフト です。

このドキュメントでは、Cloudflare での具体的な連携を説明します。

1. 有効な署名鍵を生成する

ボットのリクエストを認証するために使う署名鍵を生成します。

  1. リクエストの署名に使う、一意な Ed25519 秘密鍵を生成します。この例では OpenSSLgenpkey コマンドを使います。

    openssl genpkey -algorithm ed25519 -out private-key.pem
  2. 公開鍵を取り出します。

    openssl pkey -in private-key.pem -pubout -out public-key.pem
  3. 任意のツールで、公開鍵を JSON Web Key(JWK)に変換します。この例では jwker コマンドラインアプリケーションを使います。

    go install github.com/jphastings/jwker/cmd/jwker@latest
    jwker public-key.pem public-key.jwk

この手順で、秘密鍵と公開鍵を生成し、公開鍵を JWK に変換しています。

2. 鍵ディレクトリをホストする

ボットが Cloudflare へのリクエストを認証できるよう、鍵ディレクトリをホストします。 このディレクトリは draft-meunier-http-message-signatures-directory-03 の定義に従ってください。

  1. /.well-known/http-message-signatures-directory で鍵ディレクトリをホストします(これは必須です)。この鍵ディレクトリは、署名鍵から導出した公開鍵を含む JSON Web Key Set(JWKS)を返す必要があります。

  2. Web ページは HTTP ではなく HTTPS で配信します。

  3. Ed25519 公開鍵に対応する base64 URL エンコードの JWK サムプリントを計算 します。

  4. HTTP メッセージ署名の仕様に従い、鍵ディレクトリ内の鍵ごとに 1 つの署名を付けて HTTP レスポンスに署名します。これにより、ほかの者がディレクトリを複製して代わりに登録することを防げます。レスポンスには次のヘッダーが必要です。

    • Content-Type: このヘッダーの値は application/http-message-signatures-directory+json にしてください。
    • Signature: 選んだコンポーネントに対して Signature ヘッダー を構築します。
    • Signature-Input: 選んだコンポーネントに対して Signature-Input ヘッダー を構築します。ヘッダーは次の要件を満たす必要があります。
      必須コンポーネント / パラメーター 要件
      tag http-message-signatures-directory と等しくしてください。
      keyid ディレクトリ内の対応する鍵の JWK サムプリントです。
      created アプリケーションがメッセージを送った時点の Unix タイムスタンプと等しくしてください。
      expires Cloudflare がメッセージの検証をやめる時点の Unix タイムスタンプと等しくしてください。
      @authority リクエストが送った Host ヘッダーの値と等しくしてください。req コンポーネントパラメーター を設定します。

    次の例は、https://example.com に対する、必須ヘッダー付きの注釈付きリクエストとレスポンスです。ここでの Signature の値は説明用であり、実際に生成された署名ではありません。

    GET /.well-known/http-message-signatures-directory HTTP/1.1
    Host: example.com
    Accept: application/http-message-signatures-directory+json
    
    HTTP/1.1 200 OK
    Content-Type: application/http-message-signatures-directory+json
    Signature: sig1=:TD5arhV1ved6xtx63cUIFCMONT248cpDeVUAljLgkdozbjMNpJGr/WAx4PzHj+WeG0xMHQF1BOdFLDsfjdjvBA==:
    Signature-Input: sig1=("@authority";req);alg="ed25519";keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U";nonce="ZO3/XMEZjrvSnLtAP9M7jK0WGQf3J+pbmQRUpKDhF9/jsNCWqUh2sq+TH4WTX3/GpNoSZUa8eNWMKqxWp2/c2g==";tag="http-message-signatures-directory";created=1750105829;expires=1750105839
    Cache-Control: max-age=86400
    {
      "keys": [{
        "kty": "OKP",
        "crv": "Ed25519",
        "x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs", // Base64 URL-encoded public key, with no padding
      }]
    }

ディレクトリの検証には、Cloudflare が開発した http-signature-directory CLI ツール を使えます。

3. ボットと鍵ディレクトリを登録する

検証済みボットの一覧にボットを追加するには、ボットと鍵ディレクトリを登録します。

  1. Cloudflare ダッシュボード にログインし、アカウントとドメインを選びます。
  2. Manage Account > Configurations を開きます。
  3. Bot Submission Form タブを開きます。
  4. Verification MethodRequest Signature を選びます。
  5. Validation Instructions に、鍵ディレクトリの URL を入力します。ボットが送る User-Agent の値(と一致パターン)も追加で指定できます。
  6. Submit を選びます。

Cloudflare は、鍵ディレクトリ内の有効な Ed25519 鍵をすべて受け入れます。鍵がすでに Cloudflare の登録データベースにある場合は、新しい鍵の提供、または既存鍵のローテーションについて調整します。

検証が成功すると、検証済みリクエストを送れるようになります。

4.(検証後)リクエストに署名する

ボットの検証が成功したら、リクエストに署名できます。署名プロトコルは draft-meunier-web-bot-auth-architecture-02 で定義されています。

4.1. 署名するコンポーネントを選ぶ

署名するコンポーネントの集合を選びます。

コンポーネントは HTTP ヘッダー、または HTTP Message Signatures 仕様の 派生コンポーネント のいずれかです。Cloudflare は次を推奨します。

  • 少なくとも @authority 派生コンポーネントを選んでください。リクエスト先のドメインを表します。たとえば https://example.com へのリクエストでは、@authorityexample.com と解釈されます。
  • ASCII 値だけを含むコンポーネントを使ってください。HTTP Message Signatures 仕様は非 ASCII 文字を認めておらず、ボットのリクエスト検証が失敗します。

4.2. JWK サムプリントを計算する

Cloudflare に登録した公開鍵から、base64 URL エンコードの JWK サムプリントを計算 します。

4.3. 必須ヘッダーを構築する

Web Bot Auth に必要な 3 つのヘッダーを構築します。

Signature-Input ヘッダー

選んだコンポーネントに対して Signature-Input ヘッダー を構築します。ヘッダーは次の要件を満たす必要があります。

必須コンポーネントパラメーター 要件
tag web-bot-auth と等しくしてください。
keyid 手順 2 で計算したサムプリントと等しくしてください。
created アプリケーションがメッセージを送った時点の Unix タイムスタンプと等しくしてください。
expires Cloudflare がメッセージの検証をやめる時点の Unix タイムスタンプと等しくしてください。短い expires はリプレイ攻撃の可能性を下げます。適切な短寿命の間隔を選ぶことを Cloudflare は推奨します。

Signature ヘッダー

選んだコンポーネントに対して Signature ヘッダー を構築します。

Signature-Agent ヘッダー

鍵ディレクトリを指す Signature-Agent ヘッダー を構築します。Cloudflare は draft-meunier-http-message-signatures-directory-03Signature-Agent 形式を実装しており、ヘッダー値は "https://signature-agent.test" のような構造化文字列です。

次の場合、Cloudflare はメッセージの検証に失敗します。

  • メッセージに https:// ではない Signature-Agent ヘッダーがある。
  • メッセージに有効な URI があるが、二重引用符で囲まれていない。Signature-Agent は構造化フィールドのためです。
  • メッセージが後続ドラフトの辞書形式(sig2="https://signature-agent.test" など)を使っている。
  • メッセージに有効な Signature-Agent ヘッダーがあるが、Signature-Input のコンポーネント一覧に含まれていない。

4.4. ボットのリクエストにヘッダーを付ける

この 3 つのヘッダーをボットのリクエストに付けます。

リクエストの例は次のとおりです。

Signature-Agent: "https://signature-agent.test"
Signature-Input: sig2=("@authority" "signature-agent")
 ;created=1735689600
 ;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"
 ;alg="ed25519"
 ;expires=1735693200
 ;nonce="e8N7S2MFd/qrd6T2R3tdfAuuANngKI7LFtKYI/vowzk4lAZYadIX6wW25MwG7DCT9RUKAJ0qVkU0mEeLElW1qg=="
 ;tag="web-bot-auth"
Signature: sig2=:jdq0SqOwHdyHr9+r5jw3iYZH6aNGKijYp/EstF4RQTQdi5N5YYKrD+mCT1HA1nZDsi6nJKuHxUi/5Syp3rLWBA==:

推移的信頼と Forwarded ヘッダー

サイトに到達するエージェントは、それを作った企業自身が運用していないことが多いです。1 つのプラットフォームが多数のエンドユーザーに代わって自動化を実行できるため、運用者とエンドユーザーは同一ではありません。Cloudflare はこの連鎖(サイト所有者 → ボット運用者 → エンドユーザー)を 推移的信頼(transitive trust) と呼びます。

この連鎖を通じて運用者の身元を運ぶため、Cloudflare は RFC 7239 で定義された Forwarded ヘッダーを試験しています。IP アドレスに対する X-Forwarded-For と同様です。運用者を許可する設定は、その運用者が直接到達する場合でも、Cloudflare が信頼する中継を経由する場合でも有効です。

運用者は for パラメーターで識別します。

Forwarded: for="openai"

ヘッダーには、運用者がアクセスするコンテンツに対して約束する content-use の値も載せられます。

Forwarded: for="openai";use="reference"

制限

Cloudflare の Web Bot Auth 実装は、IETF RFC 9421 で定義されたすべてのコンポーネントとパラメーターには対応していません。リクエストの Signature-Input ヘッダーに次のいずれかを含めると、検証は失敗します。

  • @query-params: 個別パラメーターに署名する代わりに、@query コンポーネントでクエリ全体に署名することを推奨します。
  • @status: リクエストパスに含めることはできません。

IETF RFC 9421 で定義された次のコンポーネントパラメーターには対応しておらず、含めると Cloudflare はメッセージの検証に失敗します。

  • sf(HTTP ヘッダーフィールド向け)
  • bs(HTTP ヘッダーフィールド向け)
  • key(HTTP ヘッダーフィールド向け)
  • req(HTTP ヘッダーフィールドまたは派生コンポーネント向け)
  • name@query-param 向け。これには @query-param の対応が必要です)

トラブルシューティング

メッセージの検証に失敗する

メッセージの検証に失敗する場合、原因には次があります。

  • Signature-Agent ヘッダー があり、値が二重引用符で囲まれていることを確認します。
  • Signature-Agent ヘッダー が辞書ではなく構造化文字列であることを確認します。
  • Signature-Input ヘッダー のコンポーネント一覧に signature-agent を含めていることを確認します。
  • expires タイムスタンプが短すぎて、Cloudflare のサーバーに届くまでに期限切れになっていないことを確認します。1 分で十分なことが多いです。
  • 非 ASCII 値を含むコンポーネントや、非対応の一覧にあるコンポーネントに署名していないことを確認します。

Cloudflare の検証なしでゾーンに HTTP Message Signatures / Web Bot Auth を使う

自分のオリジン処理のために HTTP Message Signatures(Web Bot Auth)を使い、Cloudflare の検証が介入したり cf.bot_management.verified_bot フィールドを設定したりしてほしくない場合は、そのゾーンで Cloudflare の検証機能を無効にできます。

Web Bot Auth の検証を無効にするには、Cloudflare サポート に連絡してください。

この機能を無効にすると、Cloudflare は受信署名を検証しません。検証済みボットは、トラフィックが正当かどうかを判断するため、逆引き DNS 検証などほかの方法にフォールバックします。

関連リソース

次のリソースも参照できます。

役に立ちましたか?