【IT 运维】Apache 使用 mod_remoteip 恢复 Cloudflare 后的真实访客 IP

前言

当你的网站使用 Cloudflare CDN 时,Apache 日志中记录的 IP 地址会变成 Cloudflare 代理节点的 IP,而不是访客的真实 IP。这会导致:

  • 网站统计(如 Google Analytics)失去精确度
  • 无法根据 IP 进行地域分析
  • 防火墙/WAF 规则无法准确拦截
  • 日志审计追踪困难

Cloudflare 早已弃用 mod_cloudflare 模块,官方推荐使用 Apache 内置的 mod_remoteip 来解决这个问题。

本文基于 Rocky Linux 8.10 + Apache 2.4.37 环境,完整记录配置过程。


环境说明

项目 信息
操作系统 Rocky Linux 8.10 (Green Obsidian)
Web 服务器 Apache 2.4.37
模块状态 mod_remoteip 已加载,未配置
目标 恢复 Cloudflare 后的真实访客 IP

第一步:检查 mod_remoteip 模块

bash 复制代码
# 检查模块是否已加载
httpd -M | grep remoteip

输出 remoteip_module (shared) 表示模块已启用。如果未加载,在 /etc/httpd/conf.modules.d/ 中添加:

apache 复制代码
LoadModule remoteip_module modules/mod_remoteip.so

第二步:创建 remoteip 配置文件

创建 /etc/httpd/conf.d/remoteip.conf

apache 复制代码
# Cloudflare mod_remoteip 配置
# 从 CF-Connecting-IP 请求头恢复真实访客 IP

RemoteIPHeader CF-Connecting-IP

# Cloudflare IPv4 地址段
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
RemoteIPTrustedProxy 103.22.200.0/22
RemoteIPTrustedProxy 103.31.4.0/22
RemoteIPTrustedProxy 141.101.64.0/18
RemoteIPTrustedProxy 108.162.192.0/18
RemoteIPTrustedProxy 190.93.240.0/20
RemoteIPTrustedProxy 188.114.96.0/20
RemoteIPTrustedProxy 197.234.240.0/22
RemoteIPTrustedProxy 198.41.128.0/17
RemoteIPTrustedProxy 162.158.0.0/15
RemoteIPTrustedProxy 104.16.0.0/12
RemoteIPTrustedProxy 172.64.0.0/13
RemoteIPTrustedProxy 131.0.72.0/22

# Cloudflare IPv6 地址段
RemoteIPTrustedProxy 2400:cb00::/32
RemoteIPTrustedProxy 2606:4700::/32
RemoteIPTrustedProxy 2803:f800::/32
RemoteIPTrustedProxy 2405:b500::/32
RemoteIPTrustedProxy 2405:8100::/32
RemoteIPTrustedProxy 2a06:98c0::/29
RemoteIPTrustedProxy 2c0f:f248::/32

关键指令说明

指令 作用
RemoteIPHeader 指定从哪个 HTTP 请求头获取真实 IP。Cloudflare 使用 CF-Connecting-IP
RemoteIPTrustedProxy 声明哪些代理 IP 是可信的,只有来自这些 IP 的请求才会被替换 IP

⚠️ 安全提示 :不要使用 RemoteIPTrustedProxy 0.0.0.0/0 等通配规则,攻击者可以伪造 CF-Connecting-IP 请求头来欺骗服务器。


第三步:修改日志格式(推荐)

%h 替换为 %a,这让日志语义更明确:

bash 复制代码
# 先备份
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak

# 修改
sed -i 's/^    LogFormat "%h /    LogFormat "%a /' /etc/httpd/conf/httpd.conf

修改前后对比:

diff 复制代码
- 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
占位符 含义
%h 远程主机名(默认情况下即对端 IP)
%a 经过 mod_remoteip 处理后的真实客户端 IP

💡 实际上 mod_remoteip 配置正确后,%h 也会显示真实 IP。但使用 %a 语义更清晰,是 Cloudflare 官方推荐的最佳实践。


第四步:测试并重启

bash 复制代码
# 1. 检查配置语法
apachectl configtest
# 输出: Syntax OK

# 2. 重启 Apache
systemctl restart httpd

# 3. 确认服务状态
systemctl status httpd

第五步:验证效果

方法一:curl 模拟测试

bash 复制代码
curl -s -H "CF-Connecting-IP: 1.2.3.4" http://localhost/ -o /dev/null
tail -1 /var/log/httpd/access_log

访问日志中应显示 1.2.3.4 而非 127.0.0.1

方法二:实际访问验证

从外部访问网站,检查日志中的 IP 是否为真实访客 IP(而非 Cloudflare 的 IP 段)。


常见问题

Q: 配置后仍然显示 Cloudflare IP?

  1. 确认 remoteip.conf 放在了 /etc/httpd/conf.d/ 目录下
  2. 检查 Cloudflare IP 段是否最新:https://www.cloudflare.com/ips/
  3. 确认请求确实经过了 Cloudflare(检查是否存在 CF-Connecting-IP 请求头)

Q: mod_remoteip 和 mod_cloudflare 有什么区别?

对比 mod_cloudflare mod_remoteip
维护状态 已弃用 活跃维护
来源 第三方模块 Apache 内置
安装方式 需手动编译 系统自带

Q: 需要定期更新 Cloudflare IP 段吗?

建议定期检查。Cloudflare 的 IP 段不常变动,但偶尔会有新增。可以考虑编写 cron 脚本自动拉取更新:

bash 复制代码
# 示例:每月自动更新 Cloudflare IP 段
curl -s https://www.cloudflare.com/ips-v4/ > /tmp/cf-ips.txt

总结

通过三步即可完成配置:

  1. 创建 remoteip.conf --- 信任 Cloudflare IP 段,使用 CF-Connecting-IP
  2. 修改 LogFormat --- %h%a(最佳实践)
  3. 重启 Apache --- 使配置生效

配置完成后,Apache 日志将正确记录访客的真实 IP,便于后续的日志分析和安全审计。


参考链接


相关推荐
万联WANFLOW20 小时前
SD-WAN 控制平面高可用怎么做?SDWAN 控制器挂了,全网会发生什么
运维·网络·分布式·架构
SkyWalking中文站1 天前
认识 Horizon UI · AI Assistant:用日常语言查询你的可观测性数据
运维·监控·自动化运维
艾莉丝努力练剑1 天前
OpenCode AI 编程:Ubuntu 24.04 环境安装与使用指南
linux·服务器·网络·人工智能·tcp/ip·ubuntu
崇山峻岭之间1 天前
Keil5输出hex转换为bin的设置
linux·运维·服务器
Hoxy.R1 天前
KingbaseES读写分离高可用集群扩容、备库重建与故障切换实战
运维·数据库
liulilittle1 天前
KCC 拥塞控制算法缺陷修复记录(26/07/05)
网络·tcp/ip·计算机网络·c·信息与通信·tcp·通信
考虑考虑1 天前
nginx配置ssl
运维·后端·nginx
着迷不白1 天前
Linux 磁盘管理完全指南:分区、文件系统、挂载与 LVM 实战
linux·运维·服务器
山川而川-R1 天前
LangChain
linux·运维·服务器
QH_ShareHub1 天前
Linux 根目录结构详解
linux·运维·服务器