Nginx 不受 CDN 服务影响获取访客真实 IP

cera cera

获取和记录站点访客的真实 IP 对于站点日志的分析和安全策略的指定很有帮助,Nginx 默认的日志记录获取到的 IP 地址如果站点启用了 CDN 服务,那么这里的 IP 地址都是 CDN 服务器节点的 IP 地址了,并不是用户访客的 IP 地址(如图 1),这时候分析 Nginx 日志看到的数据就不是很真实了,影响判断呀!今天就给大家分享一个 Nginx 不受 CDN 服务影响获取访客真实 IP 的方法。

 

这个方法是完全基于 Nginx 的,主要表现在 Nginx 的日志记录里的,WordPress、Typecho 博客平台下获取访客真实 IP 可以参考『总是忘了 CDN 后评论用户的真实 IP 地址获取问题』一文的方法,这段代码是通用的好像,只要是 PHP 就可以使用的。

 

图 1

从图 1 里可以看到 Nginx 日志里记录的183.131.214.25、59.56.78.45 等等这些 IP 地址基本上都是 CDN 服务的节点 IP,这样的统计结果很明显混乱不堪毫无分析价值了都。好在以前折腾“Nginx 限制单个 IP 的并发连接数/速度”的时候知道通过 map 指令绕过 CDN 获取访客真实 IP(可参考哦『Nginx 限制单个 IP 的并发连接数改进适配开启 CDN 站点』一文),由此让 Nginx 日志记录访客真实 IP 不受 CDN 服务影响的方法也就出来了,只需要在你的 Nginx 的配置文件 nginx.conf 里添加如下配置代码获取访客真实 IP 并赋值到一个变量:

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

然后在指定 Nginx 日志格式的 log_format 里替换$remote_addr 为上面的$clientRealIP 的变量即可,修改后如下:

  1. #日志中记录真实 IP 地址,替换$remote_addr 为上面的$clientRealIP.
  2. log_format  main  ‘$clientRealIP – $remote_user [$time_local“$request” ‘
  3.                              ‘$status $body_bytes_sent $brotli_ratio “$http_referer” ‘
  4.                             ‘“$http_user_agent”‘;

最后为了让这个 Nginx 日志格式配置生效,在站点日志配置文件里采用这个日志格式生成日志即可,配置代码如下:

  1. access_log  /home/wwwlogs/www.xxxxxxxx.com.log main;

注意 access_log 这段最后的 main 哦,这里要跟上面的日志格式对应的才能生效哦,记得要修改 XXXXX 为你的站点域名或者站点日志文件名称哦。

重启一下 Nginx 生效配置,这时候查看 Nginx 日志文件是不是访客 IP 都是真实 IP 了,不再是 CDN 节点 IP 了。要验证日志实时输出才可以看到确切效果,如下截图:

 

可以看到,日志记录的访客 IP 已经都是访客 IP 了,不再是千篇一律的 CDN 节点 IP 了,大功告成!以后分析日志原始数据就准确了,再也不会发生屏蔽某个 IP 后造成误伤 CDN 节点的事儿了,同时对于那些恶意扫描、注入的请求的 IP 也可以有的放矢来应对了。

 

这个方法最大的优点就是几乎不会增加任何性能负载,也不依赖任何第三方模块,完全是采用 Nginx 内置命令来解决的,已经用这个方法多次获取到恶意请求、恶意注入、恶意攻击者的真实 IP 采取了相应的防御策略,总之效果还是非常不错的,使用本地日志分析软件的时候统计结果也更加的精准了许多

cera cloudiplc tengxunyun

相关推荐