Nginx 限制访问频率和传输速率配置方法

Anson 教程 105 次浏览 评论已关闭

Nginx 限制访问频率和传输速率有下面选项可用:

  • limit_conn:限制连接数。对于使用 HTTP/2 的 HTTPS 站点而言,用户请求多个或多次资源都通过一个 TCP 连接。 TCP 连接超时时间由用户浏览器(通常 30 秒)和网站服务器(Nginx 默认 75 秒)决定。
  • limit_req:限制请求数。用户请求的每个资源都计算请求数。需说明,如果仅对指定 URL 限制请求数,则受限 URL 页面引入的 CSS/JS/图片 等资源不受影响,因为这些资源的 URL 不同。
  • limit_rate:限制连接传输速度(下载和上传)。如果用户同时建立了多个连接,则相应增加占用服务器带宽,也就是限速是针对单个连接的。

用户访问流程:发送连接请求 -> 在已建立连接发送资源请求 -> 服务器返回请求资源。上面三个选项分别对应限制。

limit_conn 配置方法

以用例示范。先在 Nginx 配置文件 http 块内添加 limit_conn_zone 配置。

limit_conn_zone $binary_remote_addr zone=test_conn:10m;

其参数含义如下:

  • $binary_remote_addr 表示以用户 IP 作为限制连接数的判断依据
  • test_conn 是 zone 自定义名称,10m 是可用内存大小(在 64 位系统上,大约能储存 16 万个连接数状态信息。若内存用完且没有空闲状态信息可清除时,Nginx 会对后续新连接返回 503 错误)

接着添加 limit_conn 配置,可以放在 http, server, location 块内(通常在站点配置文件 server 块内使用,或者在指定 location 块内使用,例如仅对下载 URL 限制用户连接数)。

limit_conn test_conn 5;

上面配置限制每个 IP 同时最多 5 个连接数,超出将返回 503 错误,并记录日志到 error.log。

补充:limit_conn_zone 可以通过使用变量实现动态限制,例如设置 IP 白名单、不同 IP 差异限制,具体可参考这篇文章示例

limit_req 配置方法

以用例示范。先在 Nginx 配置文件 http 块内添加 limit_req_zone 配置。

limit_req_zone $binary_remote_addr zone=test_req:10m rate=10r/s;

其参数含义如下:

  • $binary_remote_addr 表示以用户 IP 作为限制请求数的判断依据
  • test_req 是 zone 自定义名称,10m 是可用内存大小(在 64 位系统上,大约能储存 8 万个请求数状态信息。若内存用完且没有空闲状态信息可清除时,Nginx 会对后续新请求返回 503 错误)
  • rate 指定允许的最大请求速率,10r/s 表示每个 IP 每秒最多接受 10 个请求(均速处理方式,即每 100 毫秒接受 1 个请求。如果前个请求发出接受完不到 100 毫秒又发第 2 个或更多请求,将会拒绝这些请求返回 503 错误,只接受超过 100 毫秒发出的请求),r/s 表示每秒多少请求,还可用 r/m 表示每分钟多少请求(例如 30r/m 表示每分钟最多接受 30 个请求,即每 2 秒接受 1 个请求)

接着添加 limit_req 配置,可以放在 http, server, location 块内(通常在站点配置文件 server 块内使用,或者在指定 location 块内使用,例如仅对注册/登录 URL 限制用户请求数)。

limit_req zone=test_req burst=20 nodelay;

上面添加了两个参数,burst=20 表示将那些原该拒绝的请求前 20 个放入列队,按 rate=10r/s 速率即每 100 毫秒接受 1 个请求。而 nodelay 表示 burst 请求不用排队处理,而是立即接受请求,但接受后 burst 名额不会立即全部释放,而是按每 100 毫秒释放 1 个名额的速度释放。另外一个 delay 参数(与 nodelay 是二选一关系),它可以指定 burst 请求中的前几个立即接受,剩余排队处理。

总结:在上面用例中,若没添加 burstnodelay 参数,对于同一个 IP 的请求,只会每 100 毫秒接受 1 个,每秒最多接受 10 个,其它低于 100 毫秒间隔发出的请求和超出每秒 10 个的请求将返回 503 错误,并记录日志到 error.log。

在添加 burstnodelay 参数后,除了每 100 毫秒接受 1 个请求外,允许突发接受 20 个请求(接着受限 burst 名额释放速度,降至每 100 毫秒接受 1 个请求)。假设用户 IP 不断大量发送请求,开始的 100 毫秒能突发接受 21 个请求,过后降至每 100 毫秒接受 2 个请求,其它请求返回 503 错误,并记录日志到 error.log。

补充:limit_req_zone 可以通过使用变量实现动态限制,例如设置 IP 白名单、不同 IP 差异限制,具体可参考这篇文章示例。另外这里还有一个经典用法示例

limit_rate 配置方法

以用例示范。添加 limit_rate 配置,可以放在 http, server, location 块内(通常在站点配置文件 server 块内使用,或者在指定 location 块内使用,例如仅对下载 URL 限制传输速度)。

limit_rate_after 800k;
limit_rate       100k;

上面 limit_rate_after 参数表示前 800k 数据传输不限速,超过后 limit_rate 参数生效,限速 100k。需留意,限速是单独作用于每个连接,如果用户同时建立了两个连接,则每个连接限速在 100k。

limit_rate 可以通过使用变量实现差异限速,例如对不同时间、不同用户、不同地区差异限速,具体可参考这篇文章示例

加强限制

配置上述 Nginx 限制后, 对于那些应用限制的连接/请求会被拒绝或限速。如果需要进一步限制,可以配合 Fail2ban 读取 Nginx 日志记录屏蔽用户 IP。