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エラーを返すようになります。
動作確認
今回のDDosで使用したapache bencheで検証します。リクエスト回数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程度の負荷で済みました。
しっかり対策しないとこういうことが起こるんだなぁと、身をもって実感した出来事でした。