NGINX-logo-rgb-large.png

I. 限制思路

Cloudflare 加持下的 Nginx,对单个IP限制并发数:获取用户真实IP,并对其限制并发数

II. Nginx 的运作方式

一些与不套CDN的区别:Cloudflare 下的 Nginx 运作方式,Cloudflare 转发用户请求至源站服务器,源站返回结果并传输内容到Cloudflare,Cloudflare 转发内容至客户端。如果设置了缓存,未来的相通请求不会经过源站服务器,而是直接从Cloudflare缓存中直接调用;以上。

需要厘清的一点就是,Nginx 识别到的请求IP来自 Cloudflare 全球各个加速节点的IP

III. 识别并记录用户真实IP

Cloudflare 下 Nginx 获取用户真实IP 地址,这里提供了相关思路思路(专门为了拉黑CC的无尽IP写的);

在nginx.conf的[http]模块里添加如下代码

获取用户真实IP,并赋值给变量$clientRealIP
map $http_x_forwarded_for  $clientRealIp {
        ""      $remote_addr;
        ~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
}

通过 map 指令,我们为 nginx 创建了一个变量 $clientRealIp ,这个就是 原始用户的真实 IP 地址,不论用户是直接访问,还是通过一串 CDN 之后的访问,我们都能取得正确的原始IP地址。

在nginx.conf的[http]模块里添加如下代码

#用户的 IP 地址 $clientRealIP 作为 Key,每个 IP 地址每秒处理 10 个请求
#你想用程序每秒几百次的刷我,没戏,再快了就不处理了,直接返回 503 错误给你
limit_req_zone $clientRealIP zone=ConnLimitZone:10m  rate=10r/s;
limit_req_log_level notice;

最后在Nginx的站点配置文件里[server]模块里加上下面一段代码

limit_req zone=ConnLimitZone burst=5 nodelay;

这样限制单个真实访客IP并发连接数以及速度限制就生效了,实现的效果是:“ 最多 5 个排队, 由于每秒处理 10 个请求 + 5个排队,你一秒最多发送 15 个请求过来,再多就直接返回 503 错误给你了”

一些问题

我用的是 lnmp.org 的脚本安装的 lnmp ; 所以按以上设定配置了 子站 配置文件,即 vhost文件夹下的子站配置文件; 我将 limit_req zone=ConnLimitZone burst=5 nodelay; 配置在了 [http] 模块下,也是生效的;相应的,我加上了一个我想要的状态码,403;可以说是很好的保障。

我的配置文件参考

#获取用户真实IP,并赋值给变量$clientRealIP
map $http_x_forwarded_for  $clientRealIp {
        ""      $remote_addr;
        ~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
}

#用户的 IP 地址 $clientRealIP 作为 Key,每个 IP 地址每秒处理 10 个请求
#你想用程序每秒几百次的刷我,没戏,再快了就不处理了,直接返回 403 错误给你
limit_req_zone $clientRealIP zone=ConnLimitZone:10m  rate=10r/s;
limit_req_log_level notice;
limit_req zone=ConnLimitZone burst=5 nodelay;
limit_req_status 403; ## 返回状态403!

server
    {
        listen 443 ssl http2;
        #listen [::]:80;
server_name limbopro.com ;
...

IV. 附注

文章参考:Nginx 限制单个IP的并发连接数改进适配开启 CDN 站点

最后修改:2021 年 04 月 04 日 08 : 30 PM