1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CloudflareAdvent Calendar 2022

Day 6

Cloudflare で gRPC を通す (3. レートリミット)

Last updated at Posted at 2023-02-04

はじめに

Cloudflare で gRPC を通すテスト、第3回です。

  1. プロキシ + Full TLS 化
  2. ファイアウォール
  3. レートリミット <<====
  4. ロードバランシング

レートリミット

gRPC リクエストにレートリミットを適用しオリジンへの到達を抑制しようと思います。

Advanced Rate Limiting を利用します。
紹介 Blog

以前の Rate Limiting は IP アドレス・レンジ毎にレートリミットを行いましたが、現行の Advanced Rate LimitingCloudflare 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 アプリケーション全体へのリクエストは下記のとおりです。
Screenshot 2023-02-04 at 15.13.49.png

IP アドレスは 1 つ。
Screenshot 2023-02-04 at 15.14.36.png

うーん、どうやって gRPC クライアントをクラス分けしましょう?

JA3 フィンガープリントがクライアント分類に使えそうです。
Screenshot 2023-02-04 at 15.15.00.png

2 つの値があり、1 つが 40 リクエスト/分を投げています。
こちらを 20 以下に制限することにします。

テーブルを見ると、区別できそうなポイントは User-Agent あるいは JA3 フィンガープリントになりそうですが、User-Agent のほうは偽造しやすいと思うので、TLS リクエストを元にする JA3 フィンガープリントをクラス化の条件にします。
Screenshot 2023-02-04 at 15.16.10.png

方針

下記の方針で設定することとします。

gRPC Client IP 現在のリクエスト数(分) レートリミット適用後の期待
Windows x.x.x.x 40 20 (超過をブロック)
Ubuntu 同上 14 14 (ブロックなし)

設定

1. レート制限するリクエストを絞る

gRPC アプリケーションへの Japan からのリクエストのみをレート制限の対象にします。
Screenshot 2023-01-29 at 22.13.46.png

2. カウント条件、カウント値のグループ化、レート制限条件、アクションを決める

Screenshot 2023-02-04 at 16.41.25.png

"以下を実行..."
条件にハマったら、どのアクションを取るか。
今回はブロック。
コード 429 、Body を JSON で指定。

"理由..."
アクションを継続する期間。
今回はブロックを 10 秒継続。

理由... 意味がわかりませんね。原文は For... なので、 "...の間” ということですね…

”レートが次の値を超えた場合...”
レートの定義。
今回は 10 秒間に 5 リクエストを超えた場合に発動。

"同じ値の..."
クラス化。
今回は "IP アドレス"と "JA3 フィンガープリント"でクラス化し、カウンタ値をまとめる。

"カウンタ"
いつカウントするか。
指定しない場合は受信ルールにマッチする場合にカウンタ値が増える。
今回は"カスタムカウント"でレスポンスステータスコードが 200 のときに増加するよう指定。

”キャッシュ ステータス”
キャッシュされたアセットに適用するかどうか。
今回のレスポンスはキャッシュ対象としていないので、関係なし。

効果確認

ファイアウォールイベント

ファイアウォールイベントを確認します。

1 つのクライアント IP に許可ブロックのイベント両方が表示されています。
また、”サービス毎のイベント”を見ると、レート制限ルールが発動していることもわかります。

Screenshot 2023-02-04 at 16.59.18.png

"アクティビティログ"でもブロックイベントが出ています。IP アドレスは同じです。
Screenshot 2023-02-04 at 16.59.42.png

リクエスト

"リクエストサマリー"を確認します。
全体のリクエスト総数はレート制限の適用前と変わらないようです。
JA3 フィンガープリント別でみると、各クライアントが挙動を変えず同じペースでリクエストをしていることがわかります。
Screenshot 2023-02-04 at 17.02.47.png

クライアントごとのブロック状況を確認するために、ドリルダウンしていきます。

エッジステータスコードの視点に切り替えます。
200 OK の他に429 Too Many Requests がカウントされており、全体のリクエストの 3~4 割程度がブロックされていることがわかります。

Screenshot 2023-02-04 at 17.03.15.png

JA3 フィンガープリントのフィルタを追加します。

Windows クライアント

期待通り、ブロックが動き、20 リクエスト程度に成功リクエストが抑えられています。

Screenshot 2023-02-04 at 17.03.43.png

Ubuntu クライアント

そもそも 20 リクエストを超えておらず、ブロックもされていません。

Screenshot 2023-02-04 at 17.04.28.png

目的達成です。

まとめ

以上、gRPC にレート制限を適用し、オリジンサーバへのリクエストを適正化することができました。

次回はロードバランシングで gRPC アプリケーションの可用性、効率性を高めようと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?