トークンバケット型のレート制限は直列リクエストでは発火しない — 上限確認は並列で投げる
セキュリティ
運用
検証
知識
運用
レート制限が効いていることを確かめようと、リクエストを直列で連打しても上限を超える件数を投げてさえ拒否が出ないことがある。バースト付きのトークンバケット方式では、消費している間にもトークンが一定速度で戻るため、直列のリクエスト間隔(往復のレイテンシ)では消費が補充に追いつかない。
見積もり方
平均レートを R(毎秒)、バーストを B、測定にかかる秒数を T とすると、拒否させるにはおおむね B + R×T 件を超える必要がある。往復に100ミリ秒かかる直列リクエストだと T が伸び、R×T の項が膨らんでいくらでも届かない。並列度を上げて T を圧縮するのが正しい。
判断基準
- レート制限の確認は並列クライアントで投げる。直列で全件正常応答だったことを「制限が効いていない」の根拠にしない
- 逆に、直列で連打して全部通ったことを「実用上問題ない」の根拠にしない。実際の攻撃は並列で来る
- 除外対象(ヘルスチェック等)の確認も同じ並列条件で行う。除外が効いているのか、単に発火閑値に届いていないだけなのかを分けるため
- 送信元の判定に CDN ・プロキシ由来のヘッダーを使っている場合、測定は実際にその経路を通して行う。オリジン直叩きではキーが変わり、別のバケットを見ることになる
報告の仕方
「制限が効く」ではなく、並列度・総リクエスト数・拒否件数をひと組で記録する。後から値を調整したときに、同じ条件で再現できる。