我们在 Solaris 10 环境中运行 Apache 2.2.22。
我们有一个特定的 URL,我们希望通过 IP 限制对该 URL 的访问。我们最近实施了 CDN,现在情况变得更加复杂,因为请求所显示的 IP 实际上是 CDN 服务器,而不是最终用户。在我们需要撤回 CDN 的情况下,我们希望处理 CDN 转发请求或最终客户端直接发送请求的情况。
CDN 在 HTTP 标头中发送最终用户 IP 地址(对于此场景,该标头称为“User-IP”)。以下是我们已实施的配置:
SetEnvIf User-IP (\d+\.\d+\.\d+\.\d+) REAL_USER_IP=$1
SetEnvIf REAL_USER_IP "(10\.1\.2\.3|192\.168\..+)" access_allowed=1
<Location /uri/>
Order deny,allow
Allow from 10.1.2.3 192.168.
allow from env=access_allowed
Deny from all
</Location>
一段时间内,这种方式似乎可以正常工作,但是在某些时候,Web 服务器开始向最终用户提供 403 错误 - 因此出于某种原因,它限制了访问。奇怪的是,Web 服务器的反弹似乎可以解决问题,但只能持续一段时间 - 然后行为又会恢复。
可能还值得一提的是,此 URL 通过 mod_jk 委托给 JBoss 服务器。但是,拒绝访问已确认发生在 Apache 层,并且该问题似乎仅在服务器运行一段时间后才会发生。
答案1
以下是解决我们的问题的最终配置:
SetEnvIf User-IP (\d+\.\d+\.\d+\.\d+) REAL_USER_IP=$1
SetEnvIf Remote_Addr "(10\.1\.2\.3|192\.168\..+)" access_allowed=1
SetEnvIf REAL_USER_IP "(10\.1\.2\.3|192\.168\..+)" access_allowed=1
<Location /uri/>
Order deny,allow
Allow from env=access_allowed
Deny from all
</Location>
看起来问题出在源 IP 的明确允许上,因为 REAL_USER_IP 可能有效,但其中包含 IP 的明确允许失败了。
我们现在基本上链接 SetEnvIf 语句以确保如果 Remote_Addr 或 REAL_USER_IP 与我们的 IP 匹配则设置环境变量“access_allowed” - 并且仅允许在环境变量上。