web-dev-qa-db-ja.com

nginxでレート制限する方法、ただし特定のIPアドレスを含める/除外する方法は?

_limit_req_を使用して、サーバーへのすべてのリクエストをレート制限できます。

ただし、特定のIPアドレス(つまり、ホワイトリスト)のレート制限を削除し、特定の他のIPアドレス(つまり、1r/sまで低くしたい特定のIP)には異なるレート制限を使用したいと思います。

条件文(例:if ( $remote_addr = "1.2.3.4" ) {})を使用してみましたが、これは書き換えルールでのみ機能し、レート制限ルールでは機能しないようです。

29
Jason Cohen

「if」ディレクティブの使用は避けた方がよいでしょう。 limit_req_zone(およびlimit_conn_zone)のキーが空の場合、制限は適用されません。これをmapおよびgeoモジュールと組み合わせて使用​​して、スロットル制限が適用されないIPのホワイトリストを作成できます。

この例は、単一のIPからの同時リクエストとリクエストレートの両方に制限を設定する方法を示しています。

http {
    geo $whitelist {
       default 0;
       # CIDR in the list below are not limited
       1.2.3.0/24 1;
       9.10.11.12/32 1;
       127.0.0.1/32 1;
    }

    map $whitelist $limit {
        0     $binary_remote_addr;
        1     "";
    }

    # The directives below limit concurrent connections from a 
    # non-whitelisted IP address to five

    limit_conn_zone      $limit    zone=connlimit:10m;

    limit_conn           connlimit 5;
    limit_conn_log_level warn;   # logging level when threshold exceeded
    limit_conn_status    503;    # the error code to return

    # The code below limits the number requests from a non-whitelisted IP
    # to one every two seconds with up to 3 requests per IP delayed 
    # until the average time between responses reaches the threshold. 
    # Further requests over and above this limit will result 
    # in an immediate 503 error.

    limit_req_zone       $limit   zone=one:10m  rate=30r/m;

    limit_req            zone=one burst=3;
    limit_req_log_level  warn;
    limit_req_status     503;

ゾーンディレクティブはhttpレベルで配置する必要がありますが、他のディレクティブはさらに下に配置できます。サーバーまたはロケーションレベルでスコープを制限するか、制限をさらに調整します。

詳細については、Nginxのドキュメント ngx_http_limit_req_module および ngx_http_limit_conn_module を参照してください

34

If()ブロックで "@location"などの名前付きの場所を安全に使用できます。

参照: http://wiki.nginx.org/IfIsEvil

このようなものはうまくいくはずです:

http {

   limit_req_zone $binary_remote_addr zone=delay:10m rate=1r/m;

   server {
      ...

      error_page 410 = @slowdown;

      if( $remote_addr != "1.2.3.4" ) {
         return 410;
      }

      location @slowdown {
         limit_req zone=delay burst 5;
         ...
      }

      location / {
         ...
      }
   }

Nginxをリバースプロキシとして使用している場合は、proxy_passなど、「location @slowdown {}」に「location/{}」と同じ情報を入力します。

5
Robert Suh