我使用如下所示的 .htaccess 文件将对目录的访问限制为某些 IP 地址:
AuthType Basic
AuthName "Protected"
<RequireAny>
Require ip 1.2.3.4
</RequireAny>
这在正常服务器设置中工作正常,但是当使用 Cloudflare 作为 WAF 代理时,它会停止工作,因为服务器接收通过 Cloudflare IP 代理的所有请求。
作为一种解决方法,可以使用“X-Forwarded-For” header 来识别客户端的“真实”IP 地址,因为 Cloudflare 会将其与其所有请求一起传递:
AuthType Basic
AuthName "Protected"
SetEnvIf X-Forwarded-For 1.2.3.4$ allowed
<RequireAny>
Require env allowed
</RequireAny>
这是一种安全的方法,还是有更好/更安全的方法来限制使用 Cloudflare 时 Apache 中客户端 IP 的访问?
最佳答案
根据IETF RFC 2616, Section 4.2 , header 可以保存逗号分隔的值列表,这是 X-Forwarded-For
的情况,如 Cloudflare uses it 。
If an X-Forwarded-For header was already present in the request to Cloudflare, Cloudflare appends the IP address of the HTTP proxy to the header:
Example: X-Forwarded-For: 203.0.113.1,198.51.100.101,198.51.100.102
In the examples above, 203.0.113.1 is the original visitor IP address and 198.51.100.101 and 198.51.100.102 are proxy server IP addresses provided to Cloudflare via the X-Forwarded-For header.
习惯上将最左边的 IP 视为真实 IP,但情况并非总是如此。
如果你这样做,你应该检查与你的 IP 匹配的正则表达式
SetEnvIf X-Forwarded-For ^1\.2\.3\.4 allowed
(最左边的IP,转义点)
更好的方法(恕我直言)
Cloudflare 还会发送 header cf-connecting-ip
(这意味着是发送到您的计算机之前到达 cloudflare 的最后一个 IP),我宁愿使用该 header 。
Is this a safe approach or is there a better/more secure way to limit access by client IP in Apache when Cloudflare is being used?
有一个问题。在这种情况下,您告诉 Apache:
“我们在中间有 cloudflare,所以让我们看看这个自定义 header ,而不是用 native 方式告诉访问者的 IP”。
该自定义 header 可以伪造。绝对地。因此,你还应该说:
“当且仅当请求来自 Cloudflare IP 时,此自定义 header 才应被视为可靠”。
Cloudflare does explicitly list their IP ranges
最后,您应该使用mod_remoteip而不是手动构建 SetEnvIf 规则。
基本上:
# /etc/apache2/conf-enabled/remoteip.conf
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
...
RemoteIPTrustedProxy 2606:4700::/32
RemoteIPTrustedProxy 2803:f800::/32
或者,将 IP 列表放入单独的文件中:
# /etc/apache2/conf-enabled/remoteip.conf
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxyList conf/trusted-proxies.lst
和
# conf/trusted-proxies.lst
173.245.48.0/20
103.21.244.0/22
...
...
2803:f800::/32
2606:4700::/32
如果请求中没有出现上述 header ,Apache 将退回 REMOTE_ADDR。来自不受信任 IP 的请求也是如此。如果 header 存在并且来自 Cloudflare,您只需执行以下操作:
Require ip 1.2.3.4
这种方法会在您需要使用 IP 的地方(日志、身份验证等)替换 IP,并在边缘情况下优雅地回退到原始 REMOTE_ADDR。
关于linux - 使用 Cloudflare 时依靠 "X-Forwarded-For"限制 Apache 中的 IP 访问是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58314261/