问题描述
如果将X-Forward-For标头中的多个IP与使用代字号运算符的ACL相比较,在Varnish中会发生什么?
虚拟示例:
该请求具有以下HTTP标头:
functools.cache
清漆配置如下:
X-Forward-For: 160.12.34.56,10.10.10.10
执行了哪个代码块?
此外,IP的顺序在X-Forward-For标头中是否重要?
如果有2个X-Forward-For标头,每个标头具有两个IP之一,是否会更改?
解决方法
它将起作用吗?
您问题的简短答案是否,它将无法正常工作。
std.ip()
希望收到一个 IP地址,而不是一个集合。转换将失败,并返回后备值(该函数的第二个参数)。
这是一个说明此情况的快速测试脚本:
vcl 4.0;
import std;
backend default none;
sub vcl_recv {
set req.http.x-f = "1.2.3.4,5.6.7.8";
return(synth(200,std.ip(req.http.x-f,"0.0.0.0")));
}
此示例将返回0.0.0.0
。
X-Forwarded-For是否需要多个IP地址?
问您的X-Forwarded-For
标头是否需要多个IP地址确实很有意义。
其目的是向原始服务器指示原始客户端的IP地址是什么。
在您的情况下,Web服务器前面有多个代理,因此自然的反应是将IP地址链接在X-Forwarded-For
标头中。
一个更好的解决方案是弄清楚原始客户端的IP地址是什么,然后在X-Forwarded-For
中设置该值。
完成此任务的最佳方法是利用Varnish支持的PROXY protocol。
利用代理协议
PROXY 协议具有传输HTTP协议的功能,但是还可以跟踪原始客户端的连接参数。
Varnish支持此功能,并允许您设置一个额外的侦听端口,以侦听 PROXY 请求。
以下是如何在 PROXY 支持下启动varnishd
的示例:
varnishd -a :80 -a :8443,PROXY -f /etc/varnish/default.vcl -s malloc,256m
如您所见,端口80
仍可用于常规 HTTP ,但端口8443
已分配用于 PROXY 支持。
如果Varnish前面的代理服务器支持 PROXY ,则Varnish将从原始客户端获取该值,并自动使用该值设置X-Forwarded-For
。
通过这种方式,您始终可以知道客户端是谁,并且可以安全地执行 ACL检查。
此外,还有一个PROXY module for Varnish,可以为您提供有关发生在Varnish前面的 TLS终止的信息。