【入門編】APIレート制限とDoS攻撃対策の実装 – アプリケーションセキュリティ & 安全な開発防御ガイド

「APIの門番」を強化しよう:DoS攻撃からサービスを守るための「レート制限」入門

こんにちは!セキュリティの世界へようこそ。
皆さんは普段、自分の家をどうやって守っていますか?頑丈な鍵をかけるのはもちろん、怪しい訪問者が来たらインターホン越しに追い返したり、あるいは「今日はもう遅いからまた明日来てね」と丁重にお断りしたりしますよね。

Webサービスにおいて、APIは「家への入り口」です。しかし、インターネット上には、強引にドアをこじ開けようとしたり、一度に何千人分もの注文を同時に送りつけて「店をパンクさせよう」とする迷惑な泥棒(攻撃者)がうろついています。

今回は、そんな攻撃からあなたのサービスを守るための「APIレート制限」について、一緒に紐解いていきましょう!

—

なぜ「制限」が必要なのか?(DoS攻撃の正体)

サービスを提供していると、稀にDoS(Denial of Service:サービス拒否)攻撃というものに遭遇します。これは、攻撃者が短時間に膨大な数のリクエストを送りつけ、サーバーを過労死させる攻撃のことです。

たとえるなら、「1人のお客さんが、1分間に1万回『いらっしゃいませ!』と叫び続け、店員が他の接客をできなくする嫌がらせ」のようなものです。

これを防ぐのが「レート制限(Rate Limiting)」です。これは、店員のルールとして「1分間に注文できるのは1人3回まで!」という制限を設ける仕組みのことですね。

—

現場で使われる「トークンバケット」アルゴリズム

レート制限を実装する際、よく使われるのが「トークンバケット」という考え方です。少し難しそうに聞こえますが、イメージは簡単です。

1. あなたの店の入り口に、「入店チケット(トークン)」が入ったバケツが置いてあります。
2. お客さん(リクエスト)が来たら、バケツからチケットを1枚取って入店します。
3. バケツの中身が空っぽになったら? そう、「今はチケットがないから、また後で来てね!」とお断りするわけです。
4. バケツには一定時間ごとに新しいチケットが自動で補充されます。

これなら、一気に大勢が押し寄せても、チケットがない人は「429 Too Many Requests(リクエストが多すぎます)」というエラーを受け取り、システム全体がダウンするのを防ぐことができます。

—

実装のヒント:Nginxで「門番」を雇おう

サーバーの入り口である「APIゲートウェイ」や「Nginx」などのミドルウェアで、この制限をかけるのが最も効率的です。以下は、Nginxで簡単に実装する例です。

1秒間に1リクエストまで許可し、バケツのサイズを5(一時的なスパイクを許容)にする設定
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=1r/s;

server {
location /api/ {
# 設定した制限を適用
limit_req zone=api_limit burst=5 nodelay;

# 制限を超えたら「429」を返す
limit_req_status 429;

proxy_pass http://backend_server;
}
}

  • zone=api_limit:10m: どのIPアドレスが何回アクセスしたかを記録するメモ帳(メモリ)を10MB確保します。
  • rate=1r/s: 「1秒間に1回まで」という厳しいルールです。
  • burst=5: 「急に5回くらいなら許してあげる」という、少しだけ優しいバッファです。
  • limit_req_status 429: 制限に引っかかった人に対して、「今は忙しいので後でね」という429エラーをしっかり返します。

—

「429 Too Many Requests」とどう向き合う?

制限に引っかかったユーザーに対して、ただ「エラーです!」と突き放すのは少し不親切ですよね。APIを設計する際は、レスポンスヘッダーに少しだけ情報を添えてあげましょう。

  • Retry-After ヘッダー: 「あと何秒待てば再度アクセスできるか」を数字で伝えます。
  • 例:Retry-After: 30 (あと30秒待ってね)

これだけで、行儀の良いクライアント(正当なアプリなど)は、自動的に待機してから再送してくれるようになります。これが、セキュリティを保ちつつユーザー体験も守るという、プロのエンジニアの心遣いです。

—

一歩ずつ、強固なサービスへ

セキュリティ対策というと「ガチガチに固める」イメージがあるかもしれませんが、実際は「誰を優先し、誰をいなすか」という交通整理に近いものです。

まずは、自分のAPIに「1人何回まで」というルールを設けることから始めてみてください。攻撃者は「抵抗が少ない場所」を好みます。少しの工夫で、あなたのサービスは攻撃者にとって「面倒で、割に合わないターゲット」に変わるはずです。

「難しそうだな」と思ったら、まずは開発環境でレート制限をかけて、自分で429エラーを発生させてみてください。自分の手で門番をコントロールできたとき、きっとセキュリティの面白さが少しだけ分かってくるはずですよ。

それでは、また次の記事でお会いしましょう!安全な開発ライフを。

コメント

タイトルとURLをコピーしました