博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nginx在CDN加速之后,获取用户真实IP做并发访问限制的方法
阅读量:4157 次
发布时间:2019-05-26

本文共 4118 字,大约阅读时间需要 13 分钟。

 

一、普通配置

什么叫普通配置?

普通配置就是针对【用户浏览器】→【网站服务器】这种常规模式的。那么,如果我要对单IP做访问限制,绝大多数教程都是这样写的:

## 你想开 几千个连接 刷死我? 超过 50 个连接,直接返回 503 错误给你,根本不处理你的请求了limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:10m ;limit_conn  TotalConnLimitZone  50;limit_conn_log_level notice; ## 用户的 IP 地址 $binary_remote_addr 作为 Key,每个 IP 地址每秒处理 10 个请求## 你想用程序每秒几百次的刷我,没戏,再快了就不处理了,直接返回 503 错误给你limit_req_zone $binary_remote_addr zone=ConnLimitZone:10m  rate=10r/s;limit_req_log_level notice; ## 具体服务器配置server {listen   80;location ~ \.php$ {                ## 最多 5 个排队, 由于每秒处理 10 个请求 + 5个排队,你一秒最多发送 15 个请求过来,再多就直接返回 503 错误给你了limit_req zone=ConnLimitZone burst=5 nodelay;fastcgi_pass   127.0.0.1:9000;fastcgi_index  index.php;include fastcgi_params;} 

②、echo用法举例:

其实就和shell的echo差不多,能否输出自定义信息。

比如,在nginx里面配置如下:

访问http://yourdomain.com/hello 就会在浏览器里面输出hello, world! 了(如果域名开了CDN可能会报404)。

又比如,测试本文提到的真实用户的IP,只要在本文第二步配置基础上,加上如下规则并reload即可:

server {listen   80;        server_name  yourdomain.com;        ## 以下是新增规则:        ## 当用户访问 /realip 的时候,我们输出 $clientRealIp 变量,看看这个变量        ## 值是不是真的 用户源IP 地址        location /realip {                echo $clientRealIp;        }}

这样一个最简单的服务器安全限制访问就完成了,这个基本上你 Google 一搜索能搜索到  90% 的网站都是这个例子,而且还强调用“$binary_remote_addr”可以节省内存之类的云云。

二、CDN之后

目前国内已经争相出现了百度云加速、加速乐、360网站卫士以及安全宝等免费CDN。让我们这些小网站也能免费享受以前高大上的CDN加速服务。

于是,网站的访问模式就变为:

用户浏览器 → CDN节点 → 网站源服务器

甚至是更复杂的模式:

用户浏览器 → CDN节点(CDN入口、CC\DDoS攻击流量清洗等) → 阿里云盾 → 源服务器

可以看到,我们的网站中间经历了好几层的透明加速和安全过滤, 这种情况下,我们就不能用上面的“普通配置”。因为普通配置中基于【源IP的限制】的结果就是,我们把【CDN节点】或者【阿里云盾】给限制了,因为这里“源IP”地址不再是真实用户的IP,而是中间CDN节点的IP地址。

我们需要限制的是最前面的真实用户,而不是中间为我们做加速的加速服务器。

其实,当一个 CDN 或者透明代理服务器把用户的请求转到后面服务器的时候,这个 CDN 服务器会在 Http 的头中加入一个记录

X-Forwarded-For :  用户IP, 代理服务器IP

如果中间经历了不止一个代理服务器,这个记录会是这样

X-Forwarded-For :  用户IP, 代理服务器1-IP, 代理服务器2-IP, 代理服务器3-IP, ….

可以看到经过好多层代理之后, 用户的真实IP 在第一个位置, 后面会跟一串中间代理服务器的IP地址,从这里取到用户真实的IP地址,针对这个 IP 地址做限制就可以了。

那么针对CDN模式下的访问限制配置就应该这样写:

map $http_x_forwarded_for  $clientRealIp {"" $remote_addr;~^(?P
[0-9\.]+),?.*$ $firstAddr;} ## 针对原始用户 IP 地址做限制limit_conn_zone $clientRealIp zone=TotalConnLimitZone:20m ;limit_conn TotalConnLimitZone 50;limit_conn_log_level notice; ## 针对原始用户 IP 地址做限制limit_req_zone $clientRealIp zone=ConnLimitZone:20m rate=10r/s;#limit_req zone=ConnLimitZone burst=10 nodelay; #如果开启此条规则,burst=10的限制将会在nginx全局生效limit_req_log_level notice; ## 具体Server:如下在监听php部分新增限制规则即可server {listen 80;location ~ \.php$ { ## 最多 5 个排队, 由于每秒处理 10 个请求 + 5个排队,你一秒最多发送 15 个请求过来,再多就直接返回 503 错误给你了limit_req zone=ConnLimitZone burst=5 nodelay; fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;include fastcgi_params;} }

三、echo模块

作者原文提到了的一个echo模块,特意玩了下感觉挺有意思的,下面贴一下简单集成步骤。

①、给集成echo模块:

#下载echo模块并解压:wget https://github.com/openresty/echo-nginx-module/archive/v0.57.tar.gztar zxvf v0.57.tar.gz #下载nginx并解压wget http://nginx.org/download/nginx-1.6.0.tar.gztar -xzvf nginx-1.6.0.tar.gzcd nginx-1.6.0/ #查看在用nginx的编译参数(如果是全新安装则省略)/usr/local/nginx/sbin/nginx -Vnginx version: nginx/1.6.0built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) #以下这行即为旧的编译参数:configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_gzip_static_module#在旧的编译参数基础上新增【--add-module=/echo模块的解压路径】参数,开始编译./configure --prefix=/usr/local/nginx/nginx  --add-module=/usr/local/src/echo-nginx-module-0.57 #make编译make -j2 #平滑升级nginx (如果是全新安装请执行:make install)mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.oldcp -f objs/nginx /usr/local/nginx/sbin/make upgrade

②、echo用法举例:

其实就和shell的echo差不多,能否输出自定义信息。

比如,在nginx里面配置如下:

location/hello{
  echo"hello, world!";
}

访问http://yourdomain.com/hello 就会在浏览器里面输出hello, world! 了(如果域名开了CDN可能会报404)。

又比如,测试本文提到的真实用户的IP,只要在本文第二步配置基础上,加上如下规则并reload即可:

server{
listen  80;
        server_name  yourdomain.com;
        ## 以下是新增规则:
        ## 当用户访问 /realip 的时候,我们输出 $clientRealIp 变量,看看这个变量
        ## 值是不是真的 用户源IP 地址
        location/realip{
                echo$clientRealIp;
        }
}

生效后,访问http://yourdomain.com/realip 就能显示你所用电脑(宽带)的真实IP了(可在ip138查验准确性):

Ps:感兴趣又喜欢学习的童鞋可以看下相关wiki文档:

本文介绍到这就差不多结束了,也是在神作的基础上精简整理并测试的,如果看完还有些许疑问,请前往查看神作原文,也许还是大神写的比较好理解(是否是原创我就不深究了,感觉也是转来转去,都没留链接,悲哀的互联网)!

本文整理自【棒主妇开源】,原文地址:《》。

转载地址:http://zrzxi.baihongyu.com/

你可能感兴趣的文章
小米颓势已现,生死劫命悬手机
查看>>
三大隐忧 三星未来路在何方?
查看>>
linux下各种进制转化最简单的的命令行
查看>>
结构体和联合体
查看>>
ACM(Association for Computing Machinery )组织的详细介绍
查看>>
unix高级编程之-命令行参数(实践一)
查看>>
无线网络加密方式对比 .
查看>>
linux中cat命令使用详解
查看>>
Static 作用详述
查看>>
透析ICMP协议(三): 牛刀初试之一 应用篇ping(ICMP.dll)
查看>>
透析ICMP协议(四): 牛刀初试之二 应用篇ping(RAW Socket)
查看>>
再次写给我们这些浮躁的程序员
查看>>
Linux下重要日志文件及查看方式(1)
查看>>
Linux下重要日志文件及查看方式(2)
查看>>
C中的static函数
查看>>
Ubuntu系统root用户密码找回方法
查看>>
Linux驱动程序中比较重要的宏
查看>>
芯片驱动问题定位思路总结之一单板重启的问题
查看>>
S3C2440看门狗定时器
查看>>
LDD3源码分析之llseek分析
查看>>