使用站点IP访问/admin/login路径时出现403禁止访问,但IP已加入白名单且域名访问正常的问题排查
看起来问题出在请求经过的路径和Apache VirtualHost匹配/访问控制的逻辑上,我来帮你拆解几个最可能的原因和解决办法:
1. 直接访问Web服务器IP时,请求没经过Load Balancer,导致X-Forwarded-For头缺失
你提到站点用了负载均衡器,而你的<Location "/admin/login">配置是依赖X-Forwarded-For头来识别VPN IP的。但如果你的监控请求是直接打Web服务器的IP,而不是走负载均衡器的IP,那这个请求里根本不会带X-Forwarded-For头——这个头是负载均衡器在转发请求时才会添加的。
这种情况下,SetEnvIf X-Forwarded-For ^123\.123\.123\.123 AllowIP这个条件就不会触发,自然Allow from env=AllowIP也不生效,最后Deny from all就会把你拦下来,返回403。而用域名访问时,请求是走负载均衡器的,所以头存在,就能正常访问。
解决办法:
修改<Location "/admin/login">的配置,同时兼容直接访问的场景——添加对客户端真实IP(Remote_Addr)的判断:
<Location "/admin/login"> Deny from all # 同时匹配X-Forwarded-For(走LB的情况)和Remote_Addr(直接访问Web服务器的情况) SetEnvIf Remote_Addr ^123\.123\.123\.123 AllowIP SetEnvIf X-Forwarded-For ^123\.123\.123\.123 AllowIP Allow from env=AllowIP Satisfy all </Location>
这样不管请求是走LB还是直接访问Web服务器,只要你的VPN IP是123.123.123.123,就能通过权限校验。
2. 用IP访问时,Apache匹配到了错误的VirtualHost
Apache是根据请求的Host头来匹配VirtualHost的。你的配置里ServerName是mysite.com,ServerAlias是www.testsite.org,都没包含站点IP111.111.111.111。如果你的Apache配置里还有其他VirtualHost(比如默认的、没有指定ServerName的),那当你用IP访问时,Apache会匹配到第一个定义的VirtualHost或者默认VirtualHost,而那个VirtualHost里可能没有/admin/login的白名单配置,所以返回403。
而你访问/search正常,可能是因为默认VirtualHost的DocumentRoot和你这个配置的一样,或者刚好也开放了这个路径,但/admin/login在默认配置里是被禁止的。
解决办法:
给你的VirtualHost添加IP作为ServerAlias,确保IP访问能匹配到正确的配置块:
<VirtualHost *:80> ServerName mysite.com ServerAlias www.testsite.org 111.111.111.111 # 加上站点IP DocumentRoot /var/www/html/server/public # 其他配置不变... </VirtualHost>
然后重启Apache生效。
3. 辅助排查:查看日志确认细节
可以通过Apache的日志进一步验证上面的猜测:
- 查看
error.log(你的路径是/var/log/httpd/testsite.log),找/admin/login相关的记录,会显示是“client denied by server configuration”,同时可以确认请求的客户端IP是什么。 - 查看
access.log,看请求的Host字段是不是111.111.111.111,以及X-Forwarded-For头是否存在(如果你的日志格式包含这个字段的话)。
备注:内容来源于stack exchange,提问作者r.cam

