背景

日常应用中,会有使用到RemoteIP,以及X-Forwarded-For头的场景,典型的IP黑白名单校验!
在实际业务中,遇到XFF头无法取到,但是实际RemoteAddr又能正常获取到客户端的情形!

分析

  • 具体表现

    • tomcat access日志可以正常输出XFF头,说明该请求头是正常传入的;
    • 应用调用httpRequest.getHeader(“X-Forwarded-For”),返回内容为空;
  • 疑点

    • tomcat对header做了处理;
    • spring对header做了处理;

tomcat分析

  • 1,查看server.xml,有如下配置:
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>
  • 2,查看tomcat文档:
    https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/catalina/valves/RemoteIpValve.html pic 其中提到会对remoteIpHeader中,命中了internal proxies的IP,进行swallow! 根据配置此处remoteIpHeader,就是X-Forwarded-For!

  • 3, 进一步查看源码:
    pic

    • 1,此处先对remoteip进行查找(==remoteIpHeader中首个非internal,非trusted的IP==),并更新至remoteAddr;
    • 2,将剩余的remoteIpHeader中的IP进行重新构建,并更新至remoteIpHeader。 至此可以明确,一旦增加了RemoteIpValve配置,则同时会对RemoteAddr,X-Forwarded-For头产生影响。同时,对其他的header和属性也会有影响,具体影响的内容可以参考官方文档

spring分析

pic 尚未遇到该问题,暂且做记录。

综述

IP的传递本身是一个比较基础的功能项,业务感知度不高,但是Nginx,Tomcat,Spring中都会有专门的模块进行分析处理。
需要前期进行规范统一,否则容易导致IP的误取,误判!
而实际业务使用过程中,很多是不知道底层具体实现,而采取了巧合编程,一旦出现问题,则会一头雾水!在此简略说明之。