レート制限
一定時間あたりのリクエスト回数に上限を設け、総当たりや DoS、API の乱用を防ぐ仕組みです。トークンバケットなどのアルゴリズムで実装します。
- 1.レート制限は「単位時間あたり何回まで」を決めて超過分を拒否・遅延させる仕組みで、総当たり・DoS・スクレイピングなどの乱用を抑えます。
- 2.代表的なアルゴリズムはトークンバケット・リーキーバケット・固定/スライディングウィンドウ。バースト許容や精度で使い分けます。
- 3.超過時は 429 を返し、Retry-After や RateLimit ヘッダで「いつ再試行してよいか」をクライアントに伝えるのが作法です。
レート制限とは何か
レート制限(Rate Limiting)は、ある送信元からのリクエストを「単位時間あたり何回まで」と決め、その上限を超えた分を拒否したり遅らせたりする仕組みです。たとえば「1 IP につき 1 分間に 60 回まで」のように上限を定めます。
狙いは、正常な利用は妨げずに、異常な量のアクセスだけを抑えることです。1 回 1 回のリクエスト自体は正規の形をしていても、それが異常な頻度で来ること自体が攻撃や乱用のサインになります。レート制限は「中身」ではなく「頻度」に注目して防御する点が特徴です。
どの単位で数えるか(キーの取り方)が設計の肝になります。
- IP アドレス単位:手軽だが、共有 IP や NAT 配下では巻き込みが起き、攻撃側は IP を分散させて回避できる。
- アカウント / API キー単位:ログイン後の API で確実。誰の利用かが明確。
- エンドポイント単位:ログインや決済など、重い・危険な処理だけ厳しめにする。
何を防ぐのか
レート制限は単独の万能策ではありませんが、複数の脅威に同時に効きます。
| 脅威 | 内容 | レート制限の効き方 |
|---|---|---|
| 総当たり攻撃 | パスワードや token を片端から試す | 試行回数を絞り、現実的な時間で当たらなくする |
| DoS / 乱用 | 大量リクエストでサーバを過負荷に | 1 元あたりの量を抑え、資源の食い潰しを防ぐ |
| スクレイピング | 自動巡回でデータを大量取得 | 取得ペースを制限し、丸ごと吸い出しを抑止 |
| コスト増大 | 従量課金 API の踏み倒し・浪費 | 上限で青天井の課金を防ぐ |
特に総当たり攻撃との相性が良いことを押さえてください。攻撃者がパスワードを 1 秒間に何千回も試せるなら弱いパスワードはすぐ破られますが、「5 回失敗したら数分ロック」のように頻度を絞れば、試行は現実的な時間内に終わらなくなります。
攻撃元が多数の IP に分散する DDoS や、ボットネットを使った総当たりでは、「IP ごとの上限」は簡単に回避されます。1 IP あたり 10 回でも、1 万個の IP を使えば 10 万回試せるからです。アカウント単位の制限や、CDN・WAF による前段での緩和と組み合わせる必要があります。
主なアルゴリズム
「どう数えるか」にはいくつかの定番があります。バースト(瞬間的な集中)を許すか、精度、実装のしやすさでトレードオフがあります。
| アルゴリズム | 仕組み | 特徴 |
|---|---|---|
| 固定ウィンドウ | 1 分ごとなど区間で回数を数える | 単純。区間の境目で 2 倍のバーストが通る欠点 |
| スライディングウィンドウ | 直近 N 秒を常にずらして数える | 境目問題を緩和。精度が高い |
| トークンバケット | 一定速度で補充される token を 1 回ごとに消費 | バーストを許しつつ平均速度を保てる。定番 |
| リーキーバケット | 一定速度でしか処理しない(漏れるバケツ) | 出力を完全に平滑化。バーストを吸収 |
トークンバケットが広く使われます。バケツに一定の速さでトークンが補充され、リクエストごとに 1 個消費し、空なら拒否します。バケツに溜まっている分だけ短時間の集中(バースト)を許容しつつ、長期的には補充速度=平均レートに収束する、という現実的な挙動が得られます。
// トークンバケットの考え方(擬似コード)
function allow(bucket, ratePerSec, capacity) {
const now = Date.now() / 1000;
// 前回からの経過時間ぶんトークンを補充(上限は capacity)
bucket.tokens = Math.min(capacity, bucket.tokens + (now - bucket.ts) * ratePerSec);
bucket.ts = now;
if (bucket.tokens >= 1) {
bucket.tokens -= 1; // 1 個消費して通す
return true;
}
return false; // 空なら拒否(429 を返す)
}
固定ウィンドウは実装が最も簡単ですが、区間の境界が弱点です。たとえば「1 分 60 回」で 59 秒目に 60 回、次の分の 1 秒目にさらに 60 回送れば、わずか 2 秒で 120 回が通ってしまいます。これを嫌う場合はスライディングウィンドウを選びます。
クライアントへの伝え方
レート制限は「黙って落とす」のではなく、いつ再試行してよいかをクライアントに伝えるのが作法です。HTTP ではステータスコード 429 Too Many Requests を返します。
HTTP/1.1 429 Too Many Requests
Retry-After: 30
RateLimit-Limit: 60
RateLimit-Remaining: 0
RateLimit-Reset: 30
Retry-After:あと何秒(または何時)待てば再試行してよいか。RateLimit-*:上限・残り回数・リセットまでの秒数。クライアントが自主的にペースを落とすための情報。
行儀の良いクライアントは Retry-After を見て待ってから再送します。これがないと、クライアントは失敗をすぐ繰り返してかえって負荷を増やすため、ヘッダで明示することが安定運用につながります。
レート制限は、なるべくアプリの手前(API ゲートウェイ、リバースプロキシ、CDN / WAF)で実施するほど、重い処理に到達する前に弾けて効率的です。複数台のサーバで動くサービスでは、各サーバが別々にカウントすると上限がずれるため、Redis などの共有ストアでカウンタを一元管理するのが定番です。多くのフレームワークやゲートウェイ(Nginx、Kong、各種クラウドの API Gateway)が標準機能として備えています。
設計の注意点
最後に、運用でつまずきやすい点を整理します。
- 正規ユーザーを巻き込まない:上限が厳しすぎると、ページの一括読み込みや正当なバッチ処理まで落とします。実際のトラフィックを観測し、余裕を持った値から始めます。
- エンドポイントごとに変える:ログイン・パスワードリセット・決済など危険で重い処理は厳しく、静的な参照は緩く、とメリハリをつけます。
- スロットリングとの併用:拒否(429)だけでなく、わざと少し遅らせるスロットリングも有効です。総当たりは「速さ」が命なので、数秒の遅延でも大きく効きます。
- ログと監視:429 が急増したら、攻撃か、上限が厳しすぎるかのどちらかです。閾値の妥当性を継続的に見直します。
レート制限は、可用性を守る防御層の一つです。総当たりに対しては パスワードの安全な保存 や 多要素認証 と、過負荷に対しては DDoS 対策 と組み合わせ、攻撃面の全体像は OWASP Top 10 で押さえると、防御の位置づけが立体的に見えてきます。
セキュリティ Article
レート制限を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
レート制限
比較で見る軸
難易度: basic / カテゴリ: セキュリティ / タグ数: 3
導入後に効く点
代表的なアルゴリズムはトークンバケット・リーキーバケット・固定/スライディングウィンドウ。バースト許容や精度で使い分けます。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- basic
- カテゴリ
- セキュリティ
- タグ数
- 3
判断チェックリスト
- 自社の用途が「レート制限 / API」に近いか確認する。
- 強みである「レート制限は「単位時間あたり何回まで」を決めて超過分を拒否・遅延させる仕組みで、総当たり・DoS・スクレイピングなどの乱用を抑えます。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。