はじめに
Cloudflare で gRPC を通すテスト、第3回です。
- プロキシ + Full TLS 化
- ファイアウォール
- レートリミット <<====
- ロードバランシング
レートリミット
gRPC リクエストにレートリミットを適用しオリジンへの到達を抑制しようと思います。
Advanced Rate Limiting を利用します。
紹介 Blog
以前の Rate Limiting は IP アドレス・レンジ毎にレートリミットを行いましたが、現行の Advanced Rate Limiting は Cloudflare Rules language を利用してより柔軟なコントロールを提供します。
第2回で紹介したようにアプリケーションに対するリクエストをいろいろな条件でクラスに分類し、クラスごとにポリシーを当てることが可能になります。
着信リクエストを Wireshark のディスプレイフィルタをベースに、フィルタします。例えばこんな感じ。
(http.request.uri.path eq "/store" or http.request.uri.path eq "/prices") and (http.host eq "mystore1.com" or http.host eq "mystore2.com") and not cf.client.bot
この形で定義する if
は、WAF/レート制限などのセキュリティ、 Cache などパフォーマンス、デフォルト動作の変更やリクエスト書き換えなど、Cloudflare 各機能の then
で利用できるので、全体で統一感のある設定が可能になります。これだけで別記事になるネタですね。
テストシナリオ
1つの IP アドレスの下で Ubuntu と Windows 2 つの gRPC クライアントを稼働させています。どちらのクライアントも公平に、平均 20 リクエスト/分 以下に抑制しようと思います。
現状確認
gRPC アプリケーション全体へのリクエストは下記のとおりです。
うーん、どうやって gRPC クライアントをクラス分け
しましょう?
JA3 フィンガープリントがクライアント分類に使えそうです。
2 つの値があり、1 つが 40 リクエスト/分を投げています。
こちらを 20 以下に制限することにします。
テーブルを見ると、区別できそうなポイントは User-Agent あるいは JA3 フィンガープリントになりそうですが、User-Agent のほうは偽造しやすいと思うので、TLS リクエストを元にする JA3 フィンガープリントをクラス化の条件にします。
方針
下記の方針で設定することとします。
gRPC Client | IP | 現在のリクエスト数(分) | レートリミット適用後の期待 |
---|---|---|---|
Windows | x.x.x.x | 40 | 20 (超過をブロック) |
Ubuntu | 同上 | 14 | 14 (ブロックなし) |
設定
1. レート制限するリクエストを絞る
gRPC アプリケーションへの Japan からのリクエストのみをレート制限の対象にします。
2. カウント条件、カウント値のグループ化、レート制限条件、アクションを決める
"以下を実行..."
条件にハマったら、どのアクションを取るか。
今回はブロック。
コード 429 、Body を JSON で指定。
"理由..."
アクションを継続する期間。
今回はブロックを 10 秒継続。
理由...
意味がわかりませんね。原文は For...
なので、 "...の間”
ということですね…
”レートが次の値を超えた場合...”
レートの定義。
今回は 10 秒間に 5 リクエストを超えた場合に発動。
"同じ値の..."
クラス化。
今回は "IP アドレス"と "JA3 フィンガープリント"でクラス化し、カウンタ値をまとめる。
"カウンタ"
いつカウントするか。
指定しない場合は受信ルールにマッチする場合にカウンタ値が増える。
今回は"カスタムカウント"でレスポンスステータスコードが 200 のときに増加するよう指定。
”キャッシュ ステータス”
キャッシュされたアセットに適用するかどうか。
今回のレスポンスはキャッシュ対象としていないので、関係なし。
効果確認
ファイアウォールイベント
ファイアウォールイベントを確認します。
1 つのクライアント IP に許可
とブロック
のイベント両方が表示されています。
また、”サービス毎のイベント”を見ると、レート制限ルール
が発動していることもわかります。
"アクティビティログ"でもブロックイベントが出ています。IP アドレスは同じです。
リクエスト
"リクエストサマリー"を確認します。
全体のリクエスト総数はレート制限の適用前と変わらないようです。
JA3 フィンガープリント
別でみると、各クライアントが挙動を変えず同じペースでリクエストをしていることがわかります。
クライアントごとのブロック状況を確認するために、ドリルダウンしていきます。
エッジステータスコード
の視点に切り替えます。
200 OK
の他に429 Too Many Requests
がカウントされており、全体のリクエストの 3~4 割程度がブロックされていることがわかります。
JA3 フィンガープリントのフィルタを追加します。
Windows クライアント
期待通り、ブロックが動き、20 リクエスト程度に成功リクエストが抑えられています。
Ubuntu クライアント
そもそも 20 リクエストを超えておらず、ブロックもされていません。
目的達成です。
まとめ
以上、gRPC にレート制限を適用し、オリジンサーバへのリクエストを適正化することができました。
次回はロードバランシングで gRPC アプリケーションの可用性、効率性を高めようと思います。