NGINX提供了各种模块,允许用户控制其网站、Web 应用程序以及其他 Web 资源的流量。限制流量或访问的关键原因之一是防止某些类型的滥用或攻击,例如DoS(拒绝服务)攻击。

在NGINX中有三种主要的限制使用或流量的方法:

  • 限制连接(请求)的数量。
  • 限制请求的速率。
  • 限制带宽。

在我们三部分系列的第一部分中,我们将讨论如何限制NGINX中的连接数以保护您的网站/应用程序。

  • 如何限制 NGINX 中的连接(请求)数量 - 第 1 部分
  • 如何限制 NGINX 中的连接(请求)速率 - 第 2 部分
  • 如何在 NGINX 中限制带宽使用 - 第 3 部分

请记住,只有当服务器正在处理请求并且整个请求标头已被读取时, NGINX才会考虑限制连接。因此,并非所有客户端连接都被计算在内。

限制 NGINX 中的连接数

首先,您需要使用limit_conn_zone指令定义一个共享内存区域,用于存储各种键的连接指标。如前所述,密钥可以是文本、变量(例如客户端的远程 IP 地址)或两者的组合。

这个在 HTTP 上下文中有效的指令有两个参数:键和区域(格式为 zone_name:size)。

limit_conn_zone $binary_remote_addr zone=limitconnbyaddr:20m;

要设置返回给被拒绝请求的响应状态代码,请使用将HTTP 状态代码作为参数的limit_conn_status指令。它在 HTTP、服务器和位置上下文中有效。

limit_conn_status 429

要限制连接,请使用limint_conn指令设置要使用的内存区域和允许的最大连接数,如以下配置片段所示。该指令在 HTTP、服务器和位置上下文中有效。

limit_conn   limitconnbyaddr  50;

完整的配置:

upstream api_service {
    server 127.0.0.1:9051;
    server 10.1.1.77:9052;
}
limit_conn_zone $binary_remote_addr zone=limitconnbyaddr:20m;
limit_conn_status 429;

server {
    listen 80;
    server_name testapp.tecmint.com;
    root /var/www/html/testapp.tecmint.com/build;
    index index.html;

    limit_conn   limitconnbyaddr  50;

    #include snippets/error_pages.conf;
    proxy_read_timeout 600;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    location / {
        try_files $uri $uri/ /index.html =404 =403 =500;
    }
    location /api {
        proxy_pass http://api_service;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
   }
}

 


保存文件并关闭它。

然后通过运行以下命令检查NGINX配置是否正常:

$ sudo nginx -t

接下来,重新加载NGINX服务以影响最近的更改:

$ sudo systemctl reload nginx

检查 Nginx 连接限制

当客户端超过允许的最大连接数时,NGINX会向客户端返回“ 429 Too many requests ”错误,并在错误日志文件中注册如下条目:

2022/03/15 00:14:00 [error] 597443#0: *127 limiting connections by zone "limitconnbyaddr", client: x.x.x.x, server: testapp.tecmimt.com, request: "GET /static/css/main.63fdefff.chunk.css.map HTTP/1.1", host: "testapp.tecmimt.com"

 

限制 Nginx 与应用程序的连接数

您还可以通过使用$server_name变量来限制给定服务器的连接数:

upstream api_service {
    server 127.0.0.1:9051;
    server 10.1.1.77:9052;
}
limit_conn_zone $server_name zone=limitbyservers:10m;
limit_conn_status 429;

server {
    listen 80;
    server_name testapp.tecmint.com;
    root /var/www/html/testapp.tecmint.com/build;
    index index.html;

     limit_conn  limitbyservers  2000;

    #include snippets/error_pages.conf;
    proxy_read_timeout 600;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    location / {
        try_files $uri $uri/ /index.html =404 =403 =500;
    }
    location /api {
        proxy_pass http://api_service;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
   }
}

此配置使NGINX能够将与为应用程序testapp.tecmint.com提供支持的虚拟服务器的连接总数限制为2000个连接。

注意: 基于客户端 IP 限制连接有一个缺点。您最终可能会限制不止一个用户的连接,特别是如果访问您的应用程序的许多用户都在同一个网络上并且在NAT后面运行——他们的所有连接都来自同一个 IP 地址。