如何在 nginx 中限制速率,但包括/排除某些 IP 地址?

如何在 nginx 中限制速率,但包括/排除某些 IP 地址?

我可以使用limit_req速率限制来限制对我的服务器的所有请求。

但是我想删除某些 IP 地址(即白名单)的速率限制,并对某些其他 IP 地址使用不同的速率限制(即我希望某些 IP 的速率低至 1r/s)。

我尝试使用条件(例如if ( $remote_addr = "1.2.3.4" ) {}),但它似乎只适用于重写规则,而不适用于速率限制规则。

答案1

最好避免使用“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_modulengx_http_limit_conn_module

答案2

您可以安全地使用命名位置,例如 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 / {
         ...
      }
   }

在“location @slowdown { }”中填写与“location / { }”相同的信息,例如,如果您使用 nginx 作为反向代理,则填写 proxy_pass。

相关内容