過度のアクセスに備える(その1)!!Nginxのlimit_connの設定と検証

過度のアクセスを防ぐNginxのモジュール、ngx_http_limit_conn_moduleを紹介します。このモジュールを使うと、同一IPからの同時接続がある一定数越えたときにステータスコード503を返すことができるようになります。

なお、当記事で試したNginxのバージョンは1.6.3です。

ngx_http_limit_conn_moduleの設定

ngx_http_limit_conn_moduleの設定は非常に簡単です。まずは、httpディレクティブにlimit_conn_zoneなどを追加します。

http {
    ...
    limit_conn_zone $binary_remote_addr zone=limit_per_ip:10m;
    limit_conn_log_level error;
    limit_conn_status 503;
    ...
}

limit_conn_zoneで指定しているパラメータ$binary_remote_addrで、同一IPからの接続数を制御するためのゾーンを定義しています。

あとは、実際に制限をかけたいlocationなどのディレクティブに、limit_connを設定するだけです。そのときに、先ほど定義したlimit_per_ipで定義したlimit_per_ipを指定します。

location / {
    limit_conn limit_per_ip 30;
    ...
}

上記設定では、location「/」に対して、同一のIPからの同時接続数を30に制限しています。

ngx_http_limit_conn_moduleの動作確認

limit_connの設定が効いているかをabコマンドで確かめてみます。なお、判別しやすいように、同時接続数を越えた場合に返すステータスコードを599としています。

limit_conn_status 599;

「limit_conn limit_per_ip 10」の場合

まずは、同時接続のエラーが発生することを確認します。以下のように、許容できる同時接続数を10と設定しておきます。

location / {
    limit_conn limit_per_ip 10;
}

abコマンド実行

abコマンドでリクエストを投げると、エラーが返ってきていることがわかります。

$ ab -n 1000 -c 100 https://test.remotestance.com/
...
Complete requests:      1000
Failed requests:        685
Non-2xx responses:      685
...

access.logやerror.logにも、同時接続数が原因で正しく599エラーが発生したことが記録されます。

access.logの確認

# grep -c " 599 " /var/log/nginx/access.log
685

error.logの確認

2015/05/31 xx:xx:xx [error] 5504#0: *997 limiting connections by zone "limit_per_ip", client: xxx.xxx.xxx.xxx, server: remotestance.com, request: "GET / HTTP/1.0", host: "test.remotestance.com"

「limit_conn limit_per_ip 65535」の場合

次に、同時接続のエラーが発生しないケースを確認します。limit_connの設定を65535としてみます。

location / {
    # limit_conn limit_per_ip 10;
    limit_conn limit_per_ip 65535;
}

abコマンド実行

この状態でabコマンドでリクエストを投げると、エラーが返ってきていないことがわかります。

$ ab -n 1000 -c 100 https://test.remotestance.com/
...
Complete requests:      1000
Failed requests:        0
...

access.logの確認

access.logに、ステータスコード599のレスポンスが記録されていないことが確認できます。

# grep -c " 599 " /var/log/nginx/access.log
0

error.logの確認

error.logに、同時接続数要因のエラーが記録されていないことが確認できます。

-rw-r--r-- 1 root root 0  5月 31 xx:xx error.log

この記事が役に立った場合、シェアしていただけると励みになります!!