Nginx在反向代理后面时还原实际IP地址
我的Nginx Web服务器在反向代理服务器后面。
在反向代理服务器(例如AWS Cloudfront,Fastly,Cloudflare CDN/WAF)后面时,如何恢复客户端/访问者的原始IP地址和真实IP地址?
当我们的Web服务器位于反向代理后面时,我们将看到反向代理IP登录到日志文件中。
但是我们需要用户的真实IP地址。
让我们看看如何在反向代理服务器后面的nginx中获得真实用户的IP地址,以及如何使用ngx_http_realip_module恢复实际IP地址
Nginx使用ngx_http_realip_module恢复真实IP地址
首先让我们看看Nginx是否使用以下命令编译并加载了ngx_http_realip_module:
nginx -V 2>&1 | egrep --color -o 'http_realip_module' nginx -V 2>&1 | egrep --color -o 'realip_module'
输出示例表明我的Nginx使用必需的模块进行了编译:
--with-http_realip_module
步骤1通过在Nginx中设置标头名称来还原访问者IP
编辑您的nginx配置文件,例如nginx.conf或者虚拟域配置。
例如:
sudo vi /etc/nginx/vhosts.d/theitroad.local.conf
在http,服务器或者位置上下文中进行以下设置:
real_ip_header X-Forwarded-For;
Cloudflare用户尝试以下操作:
real_ip_header CF-Connecting-IP;
一些反向代理将名为X-Real-IP的标头传递给后端,因此我们可以按以下方式使用它:
real_ip_header X-Real-IP;
步骤2在反向代理后面的Nginx中获取用户真实IP
我们需要定义已知可发送正确替换地址的可信IP地址。
通常,我们添加上游服务器的IP地址。
语法为:
set_real_ip_from ipv4_addresss; set_real_ip_from ipv6_address; set_real_ip_from sub/net; set_real_ip_from CIDR;
在这种情况下,我受信任的上游代理是192.168.1.254
set_real_ip_from 192.168.1.254;
以下是一些示例:
set_real_ip_from 2606:4700:10::6816:ad6;
信任Linode nodebalancer IP:
set_real_ip_from 192.168.155.0/24;
步骤3重启Nginx服务器
使用systemctl命令
sudo systemctl restart nginx ## 或者 sudo systemctl reload nginx
对于基于Unix的系统,请尝试:
sudo nginx -s reload
步骤4 Cloudflare帮助程序脚本处理Nginx的Forwarded标头
反向代理服务提供商(例如Cloudfront,Fastly,Cloudflare等)具有大量的IPv4和IPv6地址/无类域间路由(CIDR)。
通常,他们会发布所有IPv4/IPv6的列表,我们可以根据需要将其脚本化。
让我们看看如何使用Cloudflare自动化它。
更新nginx配置文件如下
让我们编辑vdoamin文件:
sudo vi /etc/nginx/vhosts.d/theitroad.local.conf
在服务器上下文中追加以下内容:
include "/etc/nginx/vhosts.d/cloudflare.conf";
保存并关闭文件。
创建一个Shell脚本以获取所有Cloudflare IP地址
sudo vi /root/bin/restoring-original-visitor-ips.sh
追加以下bash代码:
#!/usr/bin/env bash # Purpose: Get user real ip in nginx behind Cloudflare reverse proxy # Author: {https://www.theitroad.local} under GNU GPL v2.x+ # Call using Cron https://www.theitroad.local/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/ # ------------------------------------------------------------------ set -e # IP List IPv4="https://www.cloudflare.com/ips-v4" IPv6="https://www.cloudflare.com/ips-v6" # Nginx config file conf="/etc/nginx/vhosts.d/cloudflare.conf" # Path to nginx binary nginx_cmd="/usr/sbin/nginx" file="/tmp/ips.$$" # Get list wget -q "${IPv4}" -O -> "${file}" wget -q "${IPv6}" -O ->> "${file}" # Start building config file echo 'real_ip_header CF-Connecting-IP;' > "${conf}" while read i do echo "set_real_ip_from ${i};" >> "${conf}" done < "${file}" # Check for syntax error and reload the nginx ${nginx_cmd} -qt && ${nginx_cmd} -s reload # Clean up rm -f "${file}"
每天或者每周设置Linux/Unix cron作业
首先,使用chmod命令设置权限:
chmod +x /root/bin/restoring-original-visitor-ips.sh
接下来,使用ln命令创建软链接,以便更新日常文件:
sudo ln -v -s /root/bin/restoring-original-visitor-ips.sh /etc/cron.d/
输出示例:
'/etc/cron.d/restoring-original-visitor-ips.sh' -> '/root/bin/restoring-original-visitor-ips.sh'
老实说,每周的cron工作已经足够了:
sudo ln -v -s /root/bin/restoring-original-visitor-ips.sh /etc/cron.weekly/
测试一下
我们不会等待cron工作。
因此,让我们手动运行脚本:
sudo /etc/cron.d/restoring-original-visitor-ips.sh
步骤5验证
检查您的nginx日志文件,并确保使用tail命令/cat命令/grep命令记录的真实IP地址:
tail -f /var/log/nginx/theitroad.local_access.log
真实IP地址:
139.1.2.3 - - [07/May/2020:12:16:24 +0000] "GET / HTTP/1.1" 200 3032 "https://www.google.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" 142.2.3.4 - - [07/May/2020:12:16:25 +0000] "GET /style.css HTTP/1.1" 200 399 "https://www.theitroad.local/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" 1.2.3.4 - - [07/May/2020:12:16:25 +0000] "GET /images/logo.png HTTP/1.1" 200 34001 "https://www.theitroad.local/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"