根本原因是%{remote_addr}在反向代理下仍是代理内网ip,需启用mod_remoteip模块并配置remoteipheader与remoteiptrustedproxy,使%{remote_addr}还原为真实客户端ip后,rewritecond才能正确匹配。
这个问题本质不是 rewritecond 本身失效,而是它默认读取的 %{remote_addr} 不是真实客户端 ip——在反向代理或负载均衡环境下,它显示的是上一级代理(比如 nginx、haproxy 或 apache 自身)的内网地址,而非用户真实 ip。所以 rewritecond 看着“写对了”,但匹配对象错了。
确保 mod_remoteip 已启用并正确配置
这是最根本的解决前提。RewriteCond 要匹配真实 IP,必须让 %{REMOTE_ADDR} 变成真实值,而不是靠后端或重写规则去“猜”头信息。
- 确认模块已加载:
httpd -M | grep remoteip,若无输出需启用:LoadModule remoteip_module modules/mod_remoteip.so - 指定真实 IP 来源头(通常为
X-Forwarded-For):RemoteIPHeader X-Forwarded-For - 严格列出所有可信代理出口 IP 或网段(不是 VIP,不是监听地址):
RemoteIPTrustedProxy 192.168.5.10、RemoteIPTrustedProxy 10.0.20.0/24等——漏一个,链就断,REMOTE_ADDR会退回到该代理 IP
RewriteCond 中直接使用 %{REMOTE_ADDR} 即可
配置生效后,%{REMOTE_ADDR} 就已是真实客户端 IP(字符串形式),RewriteCond 可直接匹配,无需再解析头字段:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 封禁某真实 IP:
RewriteCond %{REMOTE_ADDR} ^203\.0\.113\.77$ - 放行特定网段:
RewriteCond %{REMOTE_ADDR} !^192\.168\.10\. - 注意:正则中点号要转义,避免误匹配
验证与常见陷阱
配置后务必验证,否则 RewriteCond 看似运行,实则匹配错对象:
- 用
curl -H "X-Forwarded-For: 203.0.113.88" http://yoursite.com/test发请求,再查 Apache access_log —— 若日志中%a显示的是203.0.113.88(不是代理 IP),说明mod_remoteip生效 - 检查
RemoteIPTrustedProxy是否覆盖了所有中间代理的真实出口 IP;CDN 如 Cloudflare 需单独加其 ASN IP 段,不能只写你自己的 Nginx 地址 - 不要在 RewriteCond 中手动读取
%{HTTP:X-Forwarded-For}——这绕过mod_remoteip的可信校验,头可被伪造,不安全
补充:日志中也要看到真实 IP 才算闭环
即使 RewriteCond 匹配正确,如果日志还记着代理 IP,排查和审计仍困难。需同步调整日志格式:
- 把 LogFormat 中的
%h换成%a:LogFormat "%a %l %u %t \"%r\" %>s %b" common -
%a对应的就是经mod_remoteip修正后的REMOTE_ADDR,和 RewriteCond 读取的是同一个值










