你的网站日志里全是 Cloudflare IP?一文教你 Nginx 和 Apache 如何获取用户真实 IP
前言:日志里的“陌生访客”
如果你和我一样,喜欢分析网站的访问日志来了解访客来源,或者部署了像 Fail2ban 这样的安全工具,那么当你启用了 Cloudflare 的 CDN 加速(橙色云朵)后,你可能会发现一个“诡异”的现象:网站访问日志里所有的访客 IP,都变成了 Cloudflare 的官方 IP 地址段,例如 172.68.x.x 或 104.21.x.x 等。
这意味着你失去了追踪真实访客来源的能力,更严重的是,安全工具可能会因为误判而封禁整个 Cloudflare 节点,导致成千上万的正常用户无法访问你的网站。
这究竟是为什么?又该如何解决呢?别担心,这篇教程将为你彻底揭秘背后的原理,并提供 Nginx 和 Apache 两种主流 Web 服务器的“一站式”解决方案。
问题的根源:反向代理与“传话人”
当你开启 Cloudflare 的 CDN 代理后,你的网站访问流程发生了变化:
用户 -> Cloudflare 全球节点 -> 你的源站服务器
在这个流程中,Cloudflare 扮演了一个“中间人”或“传话人”的角色。它接收了用户的请求,然后用自己的名义来向你的服务器请求内容,最后再把内容返回给用户。
因此,你的服务器(Nginx/Apache)直接看到的连接,就是由 Cloudflare 服务器发起的。日志里记录下它的 IP,也就顺理成章了。
解决方案:信任“传话人”递来的“小纸条”
幸运的是,Cloudflare 在向你的服务器“传话”时,非常贴心地附上了一张“小纸条”(即 HTTP Header),上面清晰地写着真实访客的信息。
我们需要做的,就是教会我们的 Web 服务器去读取这张“小纸条”,并信任上面的内容。
Cloudflare 主要通过以下 HTTP Header 来传递真实 IP:
CF-Connecting-IP: 用户的真实 IP 地址。X-Forwarded-For: 包含了用户 IP 和所有中间代理 IP 的链条。
我们的目标,就是让 Nginx 或 Apache 将 CF-Connecting-IP 里的地址,作为真实的客户端 IP 来处理。
Nginx 解决方案
对于 Nginx,我们需要使用 ngx_http_realip_module 模块,这个模块在绝大多数编译版本中都是默认开启的。
操作步骤:
-
找到 Nginx 主配置文件 通常位于
/etc/nginx/nginx.conf。如果你使用宝塔面板,可以在软件商店 -> Nginx -> 设置 -> 配置修改中找到它。 -
在
http配置块中添加代码 找到http { ... }这个配置段,在它的内部(比如server_tokens off;的下一行)添加以下内容:# ===================================================# Cloudflare Real IP Configuration# ===================================================# 优先从 CF-Connecting-IP Header 获取真实 IPreal_ip_header CF-Connecting-IP;# (可选,作为备用)如果上面的 Header 不存在,则从 X-Forwarded-For 中获取# real_ip_header X-Forwarded-For;# 设置所有 Cloudflare 的 IP 地址段为可信代理# 只有来自这些 IP 的请求,我们才信任它提供的 real_ip_headerset_real_ip_from 173.245.48.0/20;set_real_ip_from 103.21.244.0/22;set_real_ip_from 103.22.200.0/22;set_real_ip_from 103.31.4.0/22;set_real_ip_from 141.101.64.0/18;set_real_ip_from 108.162.192.0/18;set_real_ip_from 190.93.240.0/20;set_real_ip_from 188.114.96.0/20;set_real_ip_from 197.234.240.0/22;set_real_ip_from 198.41.128.0/17;set_real_ip_from 162.158.0.0/15;set_real_ip_from 104.16.0.0/13;set_real_ip_from 104.24.0.0/14;set_real_ip_from 172.64.0.0/13;set_real_ip_from 131.0.72.0/22;set_real_ip_from 2400:cb00::/32;set_real_ip_from 2606:4700::/32;set_real_ip_from 2803:f800::/32;set_real_ip_from 2405:b500::/32;set_real_ip_from 2405:8100::/32;set_real_ip_from 2a06:98c0::/29;set_real_ip_from 2c0f:f248::/32;# ===================================================提示: Cloudflare 的 IP 段可能会更新,你可以随时在 Cloudflare 官网 - IP Ranges 页面获取最新的列表。
-
保存并重载 Nginx 配置
Terminal window # 检查配置语法是否正确sudo nginx -t# 重载配置sudo systemctl reload nginx如果你使用宝塔面板,直接保存并重启 Nginx 即可。
配置完成后,你的 Nginx 访问日志和后端应用(如 PHP 的 $_SERVER['REMOTE_ADDR'])获取到的就都是用户的真实 IP 了!
Apache 解决方案
对于 Apache,我们需要启用一个名为 mod_remoteip 的模块。
操作步骤:
-
启用
remoteip_module在大多数现代的 Linux 发行版中,这个模块已经安装好了,只需要启用它。Terminal window # 对于 Debian/Ubuntusudo a2enmod remoteipsudo systemctl restart apache2# 对于 CentOS/RHEL,通常是默认编译的,检查 httpd.conf 中的 LoadModule 指令 -
创建或修改配置文件 在 Apache 的主配置文件(
httpd.conf或apache2.conf)或者在conf-available目录下创建一个新的配置文件,例如remoteip.conf。Terminal window # 创建新配置文件sudo nano /etc/apache2/conf-available/remoteip.conf -
添加配置内容 将以下内容粘贴到文件中:
# ===================================================# Cloudflare Real IP Configuration for Apache# ===================================================# 告诉 remoteip 模块,真实 IP 存在于 'CF-Connecting-IP' Header 中RemoteIPHeader CF-Connecting-IP# 添加所有 Cloudflare 的 IP 段为可信代理RemoteIPTrustedProxy 173.245.48.0/20RemoteIPTrustedProxy 103.21.244.0/22RemoteIPTrustedProxy 103.22.200.0/22# ... 将 Nginx 部分的所有 IP 段,都以 'RemoteIPTrustedProxy' 开头写在这里 ...RemoteIPTrustedProxy 2c0f:f248::/32# ===================================================注意: 你需要把 Nginx 方案中
set_real_ip_from列表里的所有 IP 段,都转换成RemoteIPTrustedProxy的格式。 -
启用配置并重启 Apache
Terminal window # 启用新的配置文件sudo a2enconf remoteip# 重启 Apache 使配置生效sudo systemctl restart apache2 -
修改日志格式(可选但推荐) 为了让访问日志也显示真实 IP,你需要修改
LogFormat指令,将%h(远程主机) 替换为%a(客户端 IP)。 例如,将:LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined修改为:LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
总结
通过以上简单的配置,我们就能轻松“穿透”Cloudflare 的代理,让我们的服务器重新记录下每一个访客的真实足迹。这不仅能让我们的数据分析更精准,更能让我们的安全策略(如 Fail2ban)发挥出应有的作用。
如果你也在使用 Cloudflare,强烈建议你花几分钟时间检查并应用此配置。希望这篇教程对你有所帮助!