Nginx在反向代理后面时还原实际IP地址

时间:2020-01-09 10:42:47  来源:igfitidea点击:

我的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"