WordPress 使用 Nginx 限制每个 IP 地址访问 URL 的频率

编辑于:2022年01月04日

在保护 API 接口、阻止暴力破解和预防 CC 攻击等方面,我们希望限制单个 IP 访问 URL 的频率,比如每秒只能请求一次,或每分钟访问一次等,Nginxlimit_req_zone 可以实现限制请求速率的需求。虫子菌将以宝塔面板 + WordPress 网站为例,详细解读 limit_req_zone 的参数配置。

1. limit_req_zone

http {
    #...
    #设置名为 cccitu 的内存区域,10 MB大小,单个 IP 限制每分钟访问 1 次
    limit_req_zone $binary_remote_addr zone=cccitu:10m rate=1r/m;

    server {
        #...
        #对 https://www.cccitu.com/5065.html 进行访问频率限制
        location =/5065.html {
            #如果同 IP 一分钟内发起 10 并发请求,第 1 个请求立即处理,缓存 5 个请求后每分钟处理一个,剩下的 4 个直接返回 503 错误
            limit_req zone=cccitu burst=5 nodelay;
        }
    }
}

如上所示,limit_req_zone 的启用只有非常简单的两行代码,将它们写在 Nginx 的配置文件中即可生效。

imit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; 只能放在 http {} 内;limit_req zone=one burst=5 nodelay; 则可以根据需要放在 http {} (对服务器内所有的网站生效)、server {} (对具体的一个网站生效)或 location {} (对具体的一个网址生效)

2. 实例部署

虫子菌以使用宝塔面板部署的 WordPress 的网站为例,假设要限制对 https://www.cccitu.com/5065.html 的请求速率,每个 IP 地址,每分钟只能访问此网址 1 次。部署过程分为两部分:第一部分在 http {} 内开启 limit_req_zone 功能,第二部分在 location {} 内对具体 URL 做频率限制。

2.1 第一部分 http {}

2.1.1 代码部署:

WordPress 使用 Nginx 限制每个 IP 地址访问 URL 的频率

#zone= 和 rate= 的内容,可以根据需要自行设置
limit_req_zone $binary_remote_addr zone=cccitu:10m rate=1r/s;

将如上代码添加到 Nginx 配置文件的 http {} 内。

2.1.2 参数解读:

  • zone=cccitu:10m
  • 将 IP 地址保存在名为 cccitu 内存区域,该区域储存空间为 10 MB。区域名称可以随便设置,但要注意后面用的时候名称要一致;1m 空间大约能保存 1.6 万条 IP 地址,10m 完全够用了,空间满了新数据会覆盖旧数据。

  • rate=1r/m
  • 限制访问请求频率为每分钟 1 次,可根据需要自行设置,1r/s 是 1 秒 1 次,30r/m 是 1 分钟 30 次(换算为 2 秒 1 次),需要注意时间单位只能选择 s (秒)或 m (分),最低频率限制是每分钟 1 次访问请求。

    2.2 第二部分 location {}

    2.2.1 代码部署:

    WordPress 使用 Nginx 限制每个 IP 地址访问 URL 的频率

    location = /5065.html {
            #以下需根据实际情况修改
            #教程:https://www.cccitu.com/5065.html
            limit_req zone=cccitu burst=5 nodelay;
            try_files $uri $uri/ /index.php?$args;
            fastcgi_pass unix:/tmp/php-cgi-73.sock;
            
            #以下固定内容,无需修改
            fastcgi_index index.php;
            include fastcgi_params;         
            fastcgi_param  SCRIPT_FILENAME $document_root/$fastcgi_script_name; 
        }
    

    将如上代码添加到 Nginx 的配置文件针对 www.cccitu.com 站点的 server {} 内。

    2.2.2 参数解读:

  • location = /5065.html
  • = /5065.html 只对网址 www.cccitu.com/5065.html 生效,= / 只对 www.cccitu.com 生效,只保留 location 后面什么也不写则是对该网站的所有网址生效。

  • limit_req zone=cccitu burst=5 nodelay;
  • zone=cccitu 是存放 IP 地址的内存区域名称,要与第一部分在 http {} 中设置的名称保持,前面叫 cccitu,这里也要写 cccitu。这一行其实有 3 种写法,在此例子中我们将限制频率为 1 分钟 1 次(rate=1r/s),如果瞬间并发了 10 次请求,这 3 种写法的效果分别如下 :

    #立即处理第 1 个请求,其余 9 个直接返回 503 错误
    limit_req zone=cccitu; 
    
    #立即处理第 1 个请求,第 2-6 个请求缓存后排队 1 分钟处理 1 个,第 7-10 个请求返回 503 错误
    limit_req zone=cccitu burst=5; 
    
    #立即处理第 1-5 个请求,第 7-10 请求返回 503 错误
    limit_req zone=cccitu burst=5 nodelay; 
    
  • try_files $uri $uri/ /index.php?$args;
  • WordPress 使用 Nginx 限制每个 IP 地址访问 URL 的频率

    是 WordPress 的伪静态(宝塔面板——网站——设置——伪静态)如果你没设置伪静态或者没用 WordPress,可以删掉不写。

  • fastcgi_pass unix:/tmp/php-cgi.sock;
  • WordPress 使用 Nginx 限制每个 IP 地址访问 URL 的频率

    PHP 连接配置,有 192.168.1.25:9001unix:/tmp/php8.sock 两种写法,并且不同版本的 PHP 所写内容也不同,具体怎么写,请与所使用 PHP 的 FPM 配置文件一致(宝塔面板——软件商店——所安装PHP——FPM 配置文件)

    其它没提及的内容,是默认固定配置,不用专门修改。

    2.3 额外补充:

    location = /5065.html {
            #教程:https://www.cccitu.com/5065.html
            limit_req zone=cccitu burst=5 nodelay;
            try_files $uri $uri/ /index.php?$args; 
        }
    

    对于宝塔面板 + WordPress,如果针对的 URL 文章/标签/分类,不是 网站首页、wp-login.php、admin-ajax.php 等,那么,http {} 保持不变,location {} 有更简单的写法,如上所示。

    相关推荐

    WordPress 选择什么固定链接形式比较好?

    WordPress 选择什么固定链接形式比较好?

    WordPress 的设置中有个固定链接选项,可以选择文章、页面、分类和标签等页面链接的形式。从实际出发与各位同学们聊聊,虫子菌为什么采用/p/%postname%.html和cat、tag作为分类和标签的前缀的形式。 文章和页面的自 ...

    暂无评论