web-dev-qa-db-ja.com

公開されているAPIへの複数のリクエストを防ぐために使用するアプローチ

訪問者がサブスクリプションを介してメールを送信できるAPIがあります。

/ api/subscribe

公開による大規模な負荷を防ぐには、このエンドポイントをどのように保護できますか?私はデータベースを使用する必要がありますか、それとも10分間などを解放するなんらかのキャッシュ、インメモリなどを使用せずにデータベースを使用できますか?

7
amels

私は WebApiThrottle の使用を終了しました。これは、選択したエンドポイントのリクエスト量を制限するために使用できます。

2
amels

Proof of Work を使用して、IPアドレスを覚える必要なくレート制限を実施できます。

プルーフオブワークでは、クライアントが安価に検証できる証明を生成するために、計算量の多い関数を実行する必要があります。最も一般的なPoWの1つは部分ハッシュ反転です。この場合、すべてのAPI送信に証明+要求のハッシュが添付されている必要があります。このハッシュには、特定の長さの事前定義されたプレフィックス(通常はゼロ)が必要です。クライアントにとって、証明を計算するには、数百または数千の潜在的な証明をテストして、必要な数のゼロを持つ証明に出くわす必要があります。目標は、通常のクライアントが送信される各メッセージに対して数秒または数分の計算能力を費やすことを要求することです。ただし、サーバーの場合、証明の検証に必要なハッシュ計算は1つだけです。この非対称性は、サーバーが無効な要求を拒否するよりも、クライアントが有効な要求を生成する方がはるかにコストがかかることを意味します。

リプレイ攻撃を防ぐために、リクエストにタイムスタンプまたはカウンターを含めることを要求できます。サーバーは、タイムスタンプが古すぎるか、すでに使用されているカウンター値が含まれているリクエストを拒否するためにチェックできます。

5
Lie Ryan

私はこれを行ったので、それがどのように最適に行われるかを知っています。アイデアは、IPアドレスのハッシュ値を計算するために SipHash などのハッシュ関数を使用することです。次に、ハッシュバケットごとに トークンバケット アルゴリズムを使用します。各ハッシュバケットで100個の初期トークンを使用し、1秒あたり10個のトークンを追加して最大100個のトークンを取得します。リクエストを受け取るたびに1つのトークンを削除します。トークンがない場合は、リクエストを拒否します。これにより、最大バーストサイズが100の場合、1秒あたり10リクエストが可能になります。

理論的には、2つのIPアドレスが同じバケットにハッシュする可能性がありますが、十分なハッシュバケットがある場合、この使用例では問題になりません。

バケットの更新については、バッチタイマーを使用して行うことができます。例えば。 131072バケットの場合、更新できます。タイマーごとに4096バケット、32タイマーが1秒以内に均等に期限切れになります。したがって、1/32秒で最初の4096バケットを更新し、2/32秒で次の4096バケットを更新します。タイマーを維持するためのデータ構造は、最適には priority queue のようになります。 a バイナリヒープ

この方法で実装された場合、誰かが多数の偽造されたソースIPアドレスでシステムをフラッディングすると、メモリがいっぱいになりません。

この方法で使用されるメモリは、整数配列を使用する場合、ハッシュバケットごとに8、16、または32ビットを使用します。整数サイズは要件からきています。 8ビットは255を超えるバーストサイズをサポートできません。同様に、16ビットは最大で65535のバーストサイズを許可します。バケットごとに8ビットまたは1バイト、131072バケットには128キロバイトのメモリが必要です。問題になるところはどこにもありません。優れたマシンには、少なくとも2 GBのメモリが搭載されています。これは、このシステムに必要な容量の15,000倍以上であることを意味します。

メモリの帯域幅も考慮する必要があります。各バケットが1秒に1回更新される場合、必要な帯域幅は128 KB /秒です。優れたコンピュータは、5 GB/s以上の読み取りと書き込みの帯域幅、またはこの私の提案が使用する40 000倍以上の帯域幅をサポートしています。

キャッシュをRAMに保存してください。データベースやディスクファイルを使用しないでください。システムがクラッシュした場合でも、すべてのバケットを初期値に初期化するだけです。

4
juhist

公開とは、API自体が認証を必要としないことを意味しますか?あなたはそもそもそれを公開するという選択を再考するかもしれません。リソースを消費し、さらに問題を引き起こす可能性があるもの(送信する電子メールが多すぎるだろうは、スパムフィルターとそれらを受信する人々の両方で問題を引き起こす電子メール)は公開しないでください。ただし、禁止できる(または、各要求を支払うことができる)登録ユーザーに制限する必要があります。

何らかの理由で認証を要求できない場合、残念ながらできることは多くありません。 DOSおよびDDOS攻撃を検索できます;たくさんのリソースがありますが、賢明な人が正当な目的でのみAPIを使用することを確実に保証するものはありません

IPごとのブロッキングについては、これが最も基本的で、効果が最も低く、DOSおよびDDOSに対する最も問題のある保護です。主な問題は次のとおりです。

  • 同じIPアドレスを複数の人が使用できるという事実。私が働いている会社では、おそらく数千人が同じパブリックIPアドレス(または狭い範囲のIPアドレス)を共有しています。

    これにより、Stack Exchangeを含む一部のWebサイトでいくつかの問題が発生し、IPアドレスからのリクエストが多すぎると何度か主張され、ブロックされました。まあ、確かに、同時に作業している何百人もの開発者が大量のリクエストを生成しています

    以前の会社では、CAPTCHAを入力する必要があり、時々私たちをブロックしたのはGoogle検索でした。ここでも、同時に何百人もの人が毎分多くのGoogle検索を行っている可能性があります。

  • DDOS攻撃が複数のIPアドレスから明確に実行されるという事実。それぞれが異なるIPアドレスから数百または数千のリクエストを受け取り、すべてが同時にサーバーに到着する場合があります。また、これらのアドレス(サーバーに害を及ぼす意図やスキルがなく、ウェブサイトの存在すら知らない人に属している可能性があるアドレス)をブロックしようとした場合でも、攻撃者は比較的簡単に他のマシンに切り替えることができます。

2