【悲報】Harada's DiaryがDDos攻撃を受ける

· 3 min read
【悲報】Harada's DiaryがDDos攻撃を受ける

3/2 追記

最大リクエスト数(burst)の設定値が厳しすぎて、
データを受け取り切る前にぶった切られる事が判明したので、制限を緩めました。

location / {
      limit_req  zone=one burst=100 nodelay;
      ...
}

先日の深夜にこの WordPress サイトが DoS 攻撃を受け、
一時的にアクセス不可になった模様。あっ…(察し)

59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"

~ (省略) ~

59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
59.106.50.252 - - [21/Feb/2017:01:10:44 +0900] "GET / HTTP/1.0" 499 0 "-" "ApacheBench/2.0.40-dev" "-"
122.218.250.122 - - [21/Feb/2017:01:12:34 +0900] "GET / HTTP/1.1" 504 176 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" "-"

ApacheBench でアクセスして来たようですが、この威力です。(直後のアクセスが 504 エラーを返している)
WEB アクセスを国内のみに制限しているのに、まさかアタックを受けるとは思わんかったので
なにかしら対策をしてみようと思います。


nginxでのDoS攻撃対策

主な対策は以下となります。

  • Nginx のモジュール ngx_http_limit_req_module を使用して、単位時間あたりにリクエストできる数に制限をかける

Nginx の limit_req の設定内容

とりあえずこんな感じで設定します。

# vi /etc/nginx/nginx.conf

http {
      ...
      limit_req_zone       $binary_remote_addr  zone=one:10m rate=1r/s;
      ...
}

limit_req_zone

上記設定では、limit_req_zone で同一 IP からの
アクセスが 秒間1回 以上あったら制限をかけるゾーンを定義しています。

続けて、location ディレクティブなどに limit_req を設定します。

server {
    location / {
        limit_req  zone=one burst=10 nodelay;
        ...
    }
}

limit_req zone

limit_req zone = name [ burst = number(default 0)] [ nodelay ]

  • ゾーン (zone) とバースト時の最大リクエスト数 (burst) を指定
  • 過剰リクエスト数(今回であれば 10)が burst の数値以内であれば、レスポンスを遅延させる
  • nodelay を設定すると、レスポンスを遅延させなくなる
  • 過剰リクエスト数が burst の数値を超過した場合、リクエストはコード 503 Service Temporarily Unavailable を返す

したがって、秒間10リクエストを超える、つまり制限を超えると即座に 503 エラーを返す ようになります。


動作確認

今回の DoS で使用された ApacheBench で検証します。
リクエスト回数 100、同時リクエスト数 100 とします。

※間違っても本番に打たないでね……

# ab -n 100 -c 100 http://hdserver.mydns.jp/

結果:

Time taken for tests:   7.881 seconds
Complete requests:      100
Failed requests:        83

100 リクエスト中 83 アクセスが失敗しています。

エラーログ:

2017/02/25 19:51:19 [error] 6958#6958: *155 limiting requests, excess: 10.025 by zone "one", client: 121.116.163.198, server: , request: "GET / HTTP/1.0", host: "150.95.141.227"

エラーログを見ると、秒間アクセスが制限を超えた旨のログが出ています。
アクセスログにも 503 でエラーを返しているのがわかります。

121.116.163.198 - - [25/Feb/2017:19:51:24 +0900] "GET / HTTP/1.0" 503 206 "-" "ApacheBench/2.3" "-"

対策前は攻撃を受けただけで Load が 50 近く跳ね上がっていましたが、
対策後はせいぜい 1~2 程度の負荷で済みました。

しっかり対策しないとこういうことが起こるんだなぁと、身をもって実感した出来事でした。