多くのホスティングプランは DDoS 対策をうたっています。それは通常、大量の不要なパケットの洪水(レイヤー 3 と 4)をサーバーに届く前にフィルタリングすることを指します。1,000 台の「本物の」ブラウザーが最も遅いページを同時に読み込むような攻撃は防げません。こうしたアプリケーション層(レイヤー 7)の攻撃は通常の訪問者と見分けがつかず、自分で対処する必要があります。背景はDDoS 対策とはをご覧ください。
違いを理解する
- ボリューム型の洪水攻撃: ネットワーク回線を埋め尽くします。ホストまたは上流側でフィルタリングされます。
- プロトコル攻撃: 接続テーブルを使い果たします。大半はネットワーク側で処理されます。
- レイヤー 7 攻撃: 正当に見える HTTP リクエストで、CPU、データベース、ワーカーを使い果たします。これらはアプリケーションに届きます。
ステップ 1: Nginx でレート制限する
1つのアドレスからのリクエスト速度に上限を設けます。http ブロックでゾーンを定義し、サイトに適用します。
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=connip:10m;
server {
location / {
limit_req zone=perip burst=20 nodelay;
limit_conn connip 20;
}
location = /login {
limit_req zone=perip burst=3 nodelay;
}
}
ログインと検索は負荷が高いため、はるかに厳しい制限を設定してください。
ステップ 2: できるものはキャッシュする
キャッシュされたページは、ほとんどコストをかけずに配信できます。匿名ユーザーのトラフィックに対して、30 から 60 秒程度でも FastCGI またはプロキシのキャッシュを有効にしてください。同一リクエストの洪水が、ごく少数の実リクエストに変わります。
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=site:50m inactive=10m;
fastcgi_cache site;
fastcgi_cache_valid 200 60s;
fastcgi_cache_use_stale updating error timeout;
ステップ 3: 適切なタイムアウトを設定する
低速接続攻撃はワーカーを占有し続けます。制限値を短くしてください。
client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 15s;
keepalive_timeout 15s;
client_max_body_size 5m;
ステップ 4: fail2ban で繰り返し攻撃する相手を遮断する
レートリミッターに引っかかったアドレスを遮断します。Nginx は拒否したリクエストをエラーログに記録するので、フィルターでそれらを検出できます。
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 60
bantime = 1h
ステップ 5: 深刻になったら前段にプロキシを置く
ボット対策のチャレンジを備えたリバースプロキシや CDN は、VPS 単体では受け止められない攻撃を吸収できます。オリジン IP を秘密にするで説明しているとおりオリジンも保護するのを忘れないでください。そうしないと、攻撃者はプロキシを迂回してしまいます。
起きる前に備える
- 最も遅いページを把握し、修正するかキャッシュしてください。
- 急増にすぐ気づけるよう、監視を続けてください。
- 計画を用意しておきます。より厳しい制限、メンテナンスページ、より大きなサーバーなどです。
UFW と fail2ban のガイドの基本事項も、このガイドと併せて実施してください。