【问题标题】:How to log Client IP and X-Forwarded-For IP in tomcat access log如何在tomcat访问日志中记录客户端IP和X-Forwarded-For IP
【发布时间】:2018-06-14 16:19:00
【问题描述】:

如何在 tomcat 访问日志中记录客户端 IP 和 X-Forwarded-For IP。

我正在使用 %{X-Forwarded-For}i,如果我通过负载均衡器访问,它会记录实际的客户端地址。但如果我直接访问 tomcat 实例,则不会记录实际的客户端地址。有没有办法在这两种情况下显示实际的客户端 IP 地址?

【问题讨论】:

    标签: java tomcat http-headers ip load-balancing


    【解决方案1】:

    来自http://www.techstacks.com/howto/configure-access-logging-in-tomcat.html

    如果您运行的 tomcat 版本高于 6.0.21 或 tomcat 7,则可以利用新的远程 IP 阀。对于访问日志记录,这个 Valve 的好处是它会自动交换客户端 IP 与通过 X-Forwarded-For 标头传递的 IP 地址,如果 IP 地址在 X-Forwarded-For 标头中传递。加载它非常容易。只需在 AccessLogValve 声明之前将 org.apache.catalina.valves.RemoteIpValve 添加到 server.xml 中。例如:

     <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
    
      <!-- Remote IP Valve -->
        <Valve className="org.apache.catalina.valves.RemoteIpValve" />
    
      <!-- Access log processes all example.
        Documentation at: /docs/config/valve.html -->
    
      <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 
        prefix="localhost_access_log." suffix=".txt"
        pattern="combined" resolveHosts="false"/>
      -->
    </Host>
    

    如果您使用的 tomcat 6 版本早于 6.0.21,并且您想存储 X-Forwarded-For IP 地址,那么您可以修改 AccessLogValve 的模式属性。您需要删除“通用”或“组合”模式并将其替换为以下模式之一:

    Common Log Format: %{X-Forwarded-For}i %l %u %t "%r" %s %b
    Combined Log Format: %{X-Forwarded-For}i %l %u %t %r %s %b %{User-Agent}i %{Referer}i
    

    RemoteIP Valve 解决的主要问题是,您只能在日志中获得 X-Forwarded-For 地址。如果您直接访问应用服务器,绕过在请求中插入 X-Forwarded-For 标头的设备,您将不会记录 IP 地址。你仍然会记录一个请求——你只是不知道它来自哪里。

    【讨论】:

    • 这在通过负载均衡器时有效,但在直接跳过负载均衡器 URL 访问 tomcat 实例时不会记录 IP 地址。有没有办法在这两种情况下记录 IP 地址?
    • 您还需要在 AccessLogValue 中将requestAttributesEnabled 属性设置为true
    【解决方案2】:

    我在 Tomcat/9.0.12 上运行的 Java 应用程序前面使用 Apache 反向代理时遇到了这个问题

    我通过将它添加到 Tomcat conf/server.xml 来修复它,放置阀门的位置将取决于您希望在每个引擎/主机/上下文中应用它的天气,我已经添加了这 2 个阀门

    <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" protocolHeader="x-forwarded-proto" />
    
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="tomcat_access_log" suffix=".log" pattern="%t %{X-AUSERNAME}o %{User-Agent}i %a %m %r %b %s %D %I %{x-forwarded-for}i" />
    

    您不需要定义所有 remoteIpHeader 和 protocolHeader 因为它们是默认值,但我添加它们只是为了清楚起见https://tomcat.apache.org/tomcat-9.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html

    %a 将显示代理 ip(或负载均衡器),%{x-forwarded-for}i 将显示用户 ip

    【讨论】:

    • x-forwarded-for 是否区分大小写?
    【解决方案3】:
    <Valve className="org.apache.catalina.valves.RemoteIpValve"
           remoteIpHeader="x-forwarded-for" />
    
    <Valve className="org.apache.catalina.valves.AccessLogValve"
        requestAttributesEnabled="true"
         pattern="Remote Ip is: %{org.apache.tomcat.remoteAddr}r" />
    

    您可以将这两个 Valve 定义添加到 context.xml 中。所以你可以在这两种情况下看到远程 ip。通过负载均衡器或直接。

    org.apache.catalina.valves.RemoteIpValve 检测到“x-forwarded-for”标头。如果标头中有“x-forwarded-for”,则将其值放入“org.apache.tomcat.remoteAddr”请求属性中。如果标头中没有“x-forwarded-for”,则将客户端 ip addr 放入“org.apache.tomcat.remoteAddr”请求属性中。

    AccessLogValve 配置只记录包含正确远程 IP 的“org.apache.tomcat.remoteAddr”请求属性。

    【讨论】:

    • 两者都支持 Valve 定义。如果您需要对所有适用于 tomcat 的应用程序执行此操作,则需要在 server.xml 中执行此操作。
    猜你喜欢
    • 2021-01-23
    • 2014-04-23
    • 2021-06-08
    • 2016-02-17
    • 1970-01-01
    • 2019-01-01
    • 2013-10-22
    • 2021-05-25
    相关资源
    最近更新 更多