在使用Nginx代理网络请求时,设置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
,但是在我的server端(Tomcat,Spring)收到的网络请求中却得不到这个x-forwarded-for的信息,原因是我的代理机器的IP地址与Tomcat RemoteIpValve中配置的默认内部代理地址internalProxies能匹配,于是x-forwarded-for信息被忽略并删除了。
(在server.xml中删除RemoteIpValve的默认配置,或者配置internalProxies为其他地址(如server的地址),就可以在x-forwarded-for中得到代理传输过来的信息。)
X-Forwarded-For
x-forwarded-for在HTTP Header中,用来记录代理链的IP信息(不包括最后一次的代理)。
RemoteIpValve
Tomcat中的RemoteIpValve的设计意图是根据InternalProxies和TrustedProxies的配置,来过滤代理信息链X-Forwarded-For中的信息,获取代理机器之前的IP地址,并改写RemoteAddress的值。如果没有RemoteIpValve的处理,且有代理转发的情况下,则RemoteAddress永远为代理机器的IP地址,而不是代理机器之前发送数据包机器的IP地址(根据网络情况,可能为实际的用户IP地址)
具体逻辑如下图所示。
初始RemoteAddress为代理机器的IP地址,首先判断是否与InternalProxies匹配,如果不匹配,则RemoterIpValve不会做处理;如果匹配,则根据InternalProxies和TrustedProxies的配置来决定是否改写X-Forwarded-For和RemoteAddress以及X-Forwarded-By。
默认情况下,
private Pattern internalProxies = Pattern.compile( "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}");
internalProxies默认情况下是有配置值的(貌似是常见的局域网IP地址),trustedProxies默认为null。而我的内网代理机器和我本机的IP地址都与InternalProxies匹配,则X-Forwarded-For中代理链的信息被删除。