コンテンツにスキップ

ベストプラクティス

以下のセクションでは、一般的なユースケースに対する典型的なレート制限の設定について説明します。提供された例のルールを組み合わせて、自分のシナリオに合わせて調整できます。

レート制限の主なユースケースは以下の通りです。

詳細なアクセス制御の強制

ユーザーエージェントによる制限

一般的なユースケースは、個々のユーザーエージェントによって行われるリクエストのレートを制限することです。以下の例のルールでは、モバイルアプリが10分間に最大100リクエストを行うことを許可します。また、デスクトップブラウザのレートを制限するための別のルールを作成することもできます。

設定
一致基準ユーザーエージェントが MobileApp に等しい
http.user_agent eq "MobileApp"
カウント特性IP
レート(リクエスト / 期間)100リクエスト / 10分
アクション管理されたチャレンジ

特定のIPアドレスまたはASNを許可

リソースへのアクセスを制御する別のユースケースは、レート制限ルールからIPアドレスまたは自律システム番号(ASN)を除外または含めることです。

以下の例のルールでは、同じIPアドレスからの/statusへのGETリクエストについて、最大10リクエスト/分を許可します。ただし、訪問者のIPアドレスがpartner_ips IPリストに含まれていない場合に限ります。

設定
一致基準URIパスが/statusに等しく、リクエストメソッドがGETに等しく、IPソースアドレスがリストpartner_ipsに含まれていない
http.request.uri.path eq "/status" and http.request.method eq "GET" and not ip.src in $partner_ips
カウント特性IP
レート(リクエスト / 期間)10リクエスト / 1分
アクション管理されたチャレンジ

リファラーによる制限

一部のアプリケーションは、他のソース(たとえば、第三者ページへのリンクを含む広告によって使用される)から発生したリクエストを受け取ります。個々のリファラーページによって生成されるリクエストの数を制限して、クォータを管理したり、間接的なDDoS攻撃を回避したりすることを検討するかもしれません。

設定
一致基準URIパスが/statusに等しく、リクエストメソッドがGETに等しい
http.request.uri.path eq "/status" and http.request.method eq "GET"
カウント特性ヘッダー(Referer1
レート(リクエスト / 期間)100リクエスト / 10分
アクションブロック

この例のルールは、高度なレート制限を必要とします。

宛先ホストによる制限

SaaSアプリケーションやCloudflare SSL for SaaSを使用している顧客は、同じゾーン内に数千のホストを持つ場合があり、各ホストごとに個別のルールを作成することは実用的ではありません。これを克服するために、ホストをカウント特性として使用するレート制限ルールを作成できます。

以下の例のルールは、各ホストの/loginエンドポイントへのリクエストのレートを追跡します。

設定
一致基準URIパスが/loginに等しく、リクエストメソッドがGETに等しい
http.request.uri.path eq "/login" and http.request.method eq "GET"
カウント特性IPとホスト
レート(リクエスト / 期間)10リクエスト / 10分
アクションブロック

この例のルールは、高度なレート制限を必要とします。

認証情報の詰め込み攻撃からの保護

レート制限の典型的なユースケースは、ログインエンドポイントを保護することです。以下の例には、リクエストを多く行うクライアントを管理するための、ペナルティが増加する3つの異なるレート制限ルールが含まれています。

ルール #1

設定
一致基準ホスト名がexample.comに等しく、URIパスが/loginに等しく、リクエストメソッドがPOSTに等しい
http.host eq "example.com" and http.request.uri.path eq "/login" and http.request.method eq "POST"
カウント特性IP
カウント基準URIパスが/loginに等しく、メソッドがPOSTに等しく、レスポンスコードが(401, 403)のいずれかである
カウント式http.request.uri.path eq "/login" and http.request.method eq "POST" and http.response.code in {401 403}
レート(リクエスト / 期間)4リクエスト / 1分
アクション管理されたチャレンジ

ルール #2

設定
一致基準ホスト名がexample.comに等しく、URIパスが/loginに等しく、リクエストメソッドがPOSTに等しい
http.host eq "example.com" and http.request.uri.path eq "/login" and http.request.method eq "POST"
カウント特性IP
カウント基準URIパスが/loginに等しく、リクエストメソッドがPOSTに等しく、レスポンスステータスコードが(401, 403)のいずれかである
カウント式http.request.uri.path eq "/login" and http.request.method eq "POST" and http.response.code in {401 403}
レート(リクエスト / 期間)10リクエスト / 10分
アクション管理されたチャレンジ

ルール #3

設定
一致基準ホストがexample.comに等しい
http.host eq "example.com"
カウント特性IP
カウント基準URIパスが/loginに等しく、リクエストメソッドがPOSTに等しく、レスポンスステータスコードが(401, 403)のいずれかである
カウント式http.request.uri.path eq "/login" and http.request.method eq "POST" and http.response.code in {401 403}
レート(リクエスト / 期間)20リクエスト / 1時間
アクション1日間ブロック

ルール #1では、1分間に最大4リクエストを許可し、その後に管理されたチャレンジがトリガーされます。この設定により、正当な顧客はパスワードを思い出すためのいくつかの試行が可能です。自動化されたアクターが複数のリクエストを行った場合、そのクライアントは未解決の管理されたチャレンジによってブロックされる可能性が高いです。一方で、人間がルール #1のレート制限に達したときにチャレンジを取得して通過した場合、ルール #2が次の保護レベルを提供し、次の10分間に最大10リクエストを許可します。この2番目の閾値を超えたクライアントには、ルール #3(最も厳しい)が適用され、1日間ブロックされます。

これらの3つのルールは、ルールの式(緩和式とも呼ばれる)とは別のカウント式を持っています。別のカウント式を設定すると、一致基準はアクションがトリガーされたときにのみ使用されます。カウント式には、HTTPレスポンスステータスコードやHTTPレスポンスヘッダーに基づく条件を含めることができるため、レート制限をバックエンドロジックと統合できます。

カウント式とルール/緩和式の2つの異なる式を持つことも決定できます。これにより、次のことを定義できます。

  1. レートを計算するために使用されるリクエスト。
  2. 実際にアクションが適用されるリクエスト。

たとえば、ルール #3は、/loginへのPOSTリクエストで401または403のHTTPステータスコードが返されたものを考慮してレートを計算します。ただし、レート制限が超過した場合、Cloudflareは同じIPから生成されたexample.comホストへのすべてのリクエストをブロックします。カウント式の詳細については、Cloudflareがリクエストレートを決定する方法を参照してください。

操作数の制限

レート制限を使用して、クライアントが実行する操作の数を制限できます。この保護を提供する正確なルールは、アプリケーションによって異なります。以下の例は、クエリ文字列パラメータやJSONボディを介したコンテンツスクレイピングに対処しています。

コンテンツスクレイピングの防止(クエリ文字列経由)

この例では、クライアントが異なるクエリ文字列パラメータを使用してeコマースウェブサイトで操作(価格の確認やカートへの追加など)を行います。たとえば、クライアントが送信する典型的なリクエストは次のようになります。

GET https://store.com/merchant?action=lookup_price&product_id=215
Cookie: session_id=12345

セキュリティチームは、Cloudflare Bot Managementを回避したボットがストアの全カタログをスクレイピングするのを防ぐために、クライアントが価格を確認できる回数に制限を設けることを検討するかもしれません。

ルール #1

設定
一致基準URIパスが/merchantに等しく、URIクエリ文字列にaction=lookup_priceが含まれている
http.request.uri.path eq "/merchant" and http.request.uri.query contains "action=lookup_price"
カウント特性IP
レート(リクエスト / 期間)10リクエスト / 2分
アクション管理されたチャレンジ

ルール #2

設定
一致基準URIパスが/merchantに等しく、URIクエリ文字列にaction=lookup_priceが含まれている
http.request.uri.path eq "/merchant" and http.request.uri.query contains "action=lookup_price"
カウント特性IP
レート(リクエスト / 期間)20リクエスト / 5分
アクションブロック

これらの2つのレート制限ルールは、選択したアクション(この例では価格の照会)を実行するリクエストに一致し、カウント特性としてIPを使用します。前の/loginの例と同様に、これらの2つのルールは、持続的(しかし正当な)訪問者の場合の誤検知を減らすのに役立ちます。

特定のproduct_idの照会をクエリ文字列パラメータを介して制限するには、その特定のクエリパラメータをカウント特性として追加し、クライアントに関係なくすべてのリクエストに基づいてレートを計算します。以下の例のルールは、各product_idの照会数を10秒間に50リクエストに制限します。

設定
一致基準URIパスが/merchantに等しい
http.request.uri.path eq "/merchant"
カウント特性クエリ(product_id
レート(リクエスト/期間)50リクエスト / 10秒
アクションブロック

この例のルールは、高度なレート制限を必要とします。

予約やブッキングを扱うアプリケーションを保護するために、同様のパターンのレート制限ルールを適用できます。

コンテンツスクレイピングを防ぐ(ボディ経由)

リクエストボディをJSON形式で操作とそのパラメータを処理するアプリケーションを考えてみましょう。たとえば、lookup_price操作は次のようになります。

POST https://api.store.com/merchant
Cookie: session_id=12345
ボディ:
{
"action": "lookup_price",
"product_id": 215
}

このシナリオでは、個々のセッションからのアクション数を制限するルールを書くことができます。

設定
一致基準URIパスが/merchantに等しく、JSON文字列actionlookup_priceに等しい
http.request.uri.path eq "/merchant" and lookup_json_string(http.request.body.raw, "action") eq "lookup_price"
カウント特性クッキー(session_id
レート(リクエスト/期間)10リクエスト / 2分
アクション管理されたチャレンジ

この例のルールは、高度なレート制限とペイロード検査を必要とします。

クライアントに関係なく、各product_idの照会数を制限するために、次のようなルールを展開することもできます。

設定
一致基準URIパスが/merchantに等しく、JSONフィールドactionlookup_priceに等しい
http.request.uri.path eq "/merchant" and lookup_json_string(http.request.body.raw, "action") eq "lookup_price"
カウント特性JSONフィールド(product_id
レート(リクエスト/期間)50リクエスト / 10秒
アクションブロック

この例のルールは、高度なレート制限とペイロード検査を必要とします。

ボットからのリクエストを制限する

ボットからのトラフィックを特定する一般的なアプローチは、オリジンサーバーからの大量の403または404レスポンスステータスコードをトリガーするリクエストをレート制限することです。これは通常、スクレイピングアプリケーションからの自動化された活動を示します。

この状況では、次のようなルールを構成できます。

設定
一致基準ホスト名がexample.comに等しい
http.host eq "example.com"
カウント特性IP
カウンターを増加させる条件レスポンスステータスコードが(401, 403)のいずれかである
カウント式http.response.code in {401 403}
レート(リクエスト/期間)5リクエスト / 3分
アクション管理されたチャレンジ

自動化されたソースによって実行されるアクションのレートを制御するには、レート制限ルールをCloudflare Bot Managementと組み合わせて使用することを検討してください。ボット管理を使用すると、ボットスコアを一致基準の一部として使用して、ルールを自動化されたトラフィックまたは自動化される可能性のあるトラフィックにのみ適用できます。たとえば、自動化される可能性のあるトラフィックには最大スコア(または閾値)30、自動化されたトラフィックには10を使用できます。

アプリケーションがクッキーを使用してセッションを追跡している場合、クッキーを使用してレート制限コンテキストを設定できます(つまり、カウント特性として使用します)。レート制限特性をクッキーに設定することで、ルールは異なるIPアドレスからのリクエストをグループ化しますが、同じセッションに属するため、分散攻撃を行うボットネットワークを扱う際の一般的なシナリオです。

ルール #1

設定
一致基準ボットスコアが30未満で、URIクエリ文字列にaction=deleteが含まれている
cf.bot_management.score lt 30 and http.request.uri.query contains "action=delete"
カウント特性クッキー(session_id
レート(リクエスト/期間)10リクエスト / 1分
アクション管理されたチャレンジ

ルール #2

設定
一致基準ボットスコアが10未満で、URIクエリ文字列にaction=deleteが含まれている
cf.bot_management.score lt 10 and http.request.uri.query contains "action=delete"
カウント特性クッキー(session_id
レート(リクエスト/期間)20リクエスト / 5分
アクションブロック

これらの例のルールは、高度なレート制限とボット管理を必要とします。

アプリケーションがセッションクッキーを使用していない場合、JA3フィンガープリントを使用して個々のクライアントを特定できます。JA3フィンガープリントは、ボット管理を利用する顧客に提供されるユニークな識別子で、Cloudflareが同じクライアントからのリクエストを特定できるようにします。すべてのクライアントには、ボットであろうとなかろうと、関連付けられたフィンガープリントがあります。

設定
一致基準URIパスが/merchantに等しく、ボットスコアが10未満である
http.request.uri.path eq "/merchant" and cf.bot_management.score lt 10
カウント特性JA3フィンガープリント
レート(リクエスト/期間)10リクエスト / 1分
アクション管理されたチャレンジ

この例のルールは、高度なレート制限とボット管理を必要とします。

REST APIの保護

APIは、APIリクエストが計算または提供するのに高コストであるため、アプリケーションバックエンドに大きな負担をかける可能性があります。これらのリクエストは、データ処理や大規模なデータ照会などの複雑な操作を必要とする場合があり、悪用されると最終的にオリジンサーバーをダウンさせる可能性があります。

ボリュメトリック攻撃を防ぐ

高度なレート制限は、DDoS攻撃、大量割り当て、データ流出などの多くのタイプのボリュメトリック攻撃を軽減できます。

一般的な懸念は、POSTアクションを制限することです。認証されたトラフィックの場合、APIディスカバリーを使用して、エンドポイントごとの適切なリクエストレートを特定し、次のようなレート制限ルールを作成できます。

設定
一致基準URIパスが/endpoint1に等しく、リクエストメソッドがPOSTに等しい
http.request.uri.path eq "/endpoint1" and http.request.method eq "POST"
カウント特性ヘッダー(x-api-key
レート(リクエスト/期間)APIディスカバリーによって提案されたもの、または過去のトラフィックを分析して評価されたもの。
アクションブロック

この例のルールは、高度なレート制限を必要とします。APIディスカバリーには追加のライセンスが必要です。

カウント特性は、ヘッダー、キー、トークン、クッキー、クエリパラメータ、またはJSONボディフィールドのいずれかである可能性があります。いくつかのAPIでは、JSONボディの一部としてセッションIDやユーザーIDを含めることがあります。以下のセクションを参照して、追加情報を得てください。

リソースを保護する

GETリクエストもアプリケーションに過剰な負担をかけたり、帯域幅などの高コストリソースに影響を与えたりする可能性があります。たとえば、クライアントが特定のURLにアクセスすることでファイルをダウンロードできる大量の保存ファイル(画像など)を持つアプリケーションを考えてみましょう。

GET https://api.store.com/files/<FILE_ID>
Header: x-api-key=9375

悪用を避けるためにダウンロード数を制限したいと思うかもしれませんが、データストレージのサイズを考慮して、各ファイルに対して個別のルールを書くことは望ましくありません。この場合、次のようなルールを書くことができます。

設定
一致基準ホスト名がapi.example.comに等しく、リクエストメソッドがGETに等しい
http.host eq "api.example.com" and http.request.method eq "GET"
カウント特性パス
レート(リクエスト/期間)APIディスカバリーによって提案されたもの、または過去のトラフィックを分析して評価されたもの。
アクションブロック

この例のルールは、高度なレート制限を必要とします。

このルールは、https://api.store.com/files/*の下の各ファイルに対して10分間に10回のダウンロードを制限します。パスをルール特性として使用することで、異なる<FILE_ID>を持つ新しいアップロードファイルがあるたびに新しいルールを書く必要がなくなります。このルールでは、レートはリクエストごとに計算され、ソースIPやセッション識別子に関係なく適用されます。

特定のクライアント(x-api-keyで識別される)による特定のファイルの最大ダウンロード数を設定するために、パスとx-api-keyヘッダー(またはキーやトークンがない場合はIP)を組み合わせることもできます。

設定
一致基準ホスト名が api.store.com と等しく、リクエストメソッドが GET と等しい
http.host eq "api.example.com" and http.request.method eq "GET"
カウント特性パスとヘッダー (x-api-key)
レート (リクエスト / 期間)APIディスカバリーによって提案されたもの、または過去のトラフィックを分析して評価されたもの。
アクションブロック

この例のルールは、高度なレート制限を必要とします。

GraphQL APIの保護

GraphQLに基づいて構築されたアプリケーションが直面する最大の課題の1つは、単一のパスがサーバーへのすべてのクエリを管理し、すべてのリクエストが通常 POST 操作であることです。

リクエストの目的は通常、ボディに埋め込まれており、クライアントが取得または変更したいデータに関する情報が含まれています(サーバー側のデータ変更に関するGraphQLの用語に従う)、およびアクションを実行するために必要な追加データが含まれています。

以下の例は、映画のレビューを受け付けるアプリケーションに基づいています。GraphQLリクエストは次のようになります:

POST https://moviereviews.example.com/graphql
Cookie: session_id=12345
ボディ:
{
"data": {
"createReview": {
"stars": 5,
"commentary": "これは素晴らしい映画です!"
}
}
}

操作の数を制限する

アクションのレートを制限するために、次のルールを使用できます:

設定
一致基準URIパスが /graphql と等しく、ボディに createReview が含まれている
http.request.uri.path eq "/graphql" and http.request.body.raw contains "createReview"
カウント特性クッキー (session_id)
レート (リクエスト / 期間)5リクエスト / 1時間
アクションブロック

この例のルールは、高度なレート制限とペイロード検査を必要とします。

サーバーの過負荷を防ぐ

GraphQLリクエストを処理するために必要な複雑さは大きく異なる場合があります。APIが単一のエンドポイントを使用しているため、リクエストが処理される前に各リクエストの複雑さを把握することは困難です。

リソースの枯渇からオリジンサーバーを保護するためには、リクエストの数を制限するのではなく、特定のクライアントが一定期間内に処理するために必要な複雑さの量を制限する必要があります。Cloudflareのレート制限を使用すると、時間の経過に伴う複雑さを追跡するルールを作成し、複雑さの予算または制限に達した後に後続のリクエストをブロックできます。

このタイプのレート制限では、サーバーは提供されたリクエストごとにリクエストの複雑さに基づいてスコアを付ける必要があります。さらに、サーバーはこのスコアをHTTPヘッダーとしてレスポンスに追加する必要があります。次に、レート制限メカニズムはこの情報を使用して、その特定のクライアントの予算を更新します。

例えば、次のルールは、1時間あたりの総複雑さ予算を1,000に定義します:

設定
一致基準URIパスが /graphql を含む
http.request.uri.path eq "/graphql"
カウント特性クッキー (session_id)
スコアレート (スコア / 期間)1,000 / 1時間
スコアの場所レスポンスヘッダー (score)
アクションブロック

この例のルールは、高度なレート制限とペイロード検査を必要とします。

オリジンサーバーがリクエストを処理すると、score HTTPヘッダーをレスポンスに追加し、オリジンがそれを処理するためにどれだけの作業を行ったかを示す値を持ちます — 例えば、400。次の1時間で、同じクライアントは追加の予算 600 までリクエストを行うことができます。この予算を超えると、タイムアウトが切れるまで後続のリクエストはブロックされます。

Footnotes

  1. HTTPヘッダー名は「referrer」の誤字を使用しています。