Nginx のレート制限 limit_req でホワイトリストを作る

スポンサーリンク

 Nginx ではリクエスト数の制限をかけられる ngx_http_limit_req_module という物を使うと DDoS やそれに近い挙動を示すクライアントからのアクセスを効率良く制限する事が出来る。
 しかしこのレート制限から特定 IP アドレスを除外するという所謂ホワイトリスト機能は無いようなので、複数のディレクティブを用いて実現させることに。

 記述は次のような感じで。

geo $white_ip {
    default 1;
    192.168.1.3 0;
}

map $white_ip $limit_object {
    0   "";
    1   $binary_remote_addr;
}

limit_req_zone $limit_object zone=LR:10m rate=3r/s;

server {
        ...
        ...
        ...
        location ~ \.php$ {
            limit_req zone=LR burst=7;
            limit_req_status 429;
            ...
            ...
        }
        ...
        ...
        ...
    }
}

 まず geo ディレクティブを用いて変数 $white_ip にデフォルトで 1 をセットするようにする。そして除外したい IP アドレスや CIDR を記述してマッチすれば $white_ip に 0 をセットするようにしておく。
 map ディレクティブでは geo ディレクティブにて $white_ip にセットされた変数が 1 であれば $binary_remote_addr をそのまま指定した変数 $limit_object にセットする。0 であれば “” がセットされる。

 つまりデフォルトでは limit_req_zone で評価されるバイナリ化された IP アドレスがそのまま別の変数 $limit_object を経て与えられ、レート制限のふるいにかけられる。geo ディレクティブにてホワイトリスト入りしている IP アドレスに関しては変数 $limit_object の中身が空になるのでレート制限を受けることが無くなり、イコールとしてホワイトリストが実現出来る事になる。

 ここ最近、お行儀の悪いアクセスがあった為に特に重くなる WordPress の PHP 実行箇所にレート制限を行ってみた。しかしこれが管理者画面で自分自身が制限を喰らってしまうと言う事態になってしまったので今回の追加対応と相成った。

  • 参考リンク
NGINX Rate Limiting
Protect your applications from excessive traffic, including DDoS attacks, by controlling the requests they receive with NGINX rate limiting.
スポンサーリンク