如何在 tomcat 访问日志中记录客户端 IP 和 X 转发的 IP



如何在tomcat访问日志中记录客户端IP和X转发IP的IP地址。

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

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

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

<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>

如果您使用的是早于 6.0.21 的 tomcat 6 版本,并且想要存储 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 地址。 您仍然会记录请求 - 只是您不知道它来自哪里。

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

我通过将其添加到 Tomcat conf/服务器来修复它.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

<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 定义添加到上下文.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 config 只记录 "org.apache.tomcat.remoteAddr" 请求属性,该属性包含正确的远程 IP。

若要扩展此处已提供的答案,还可以从负载均衡器中排除日志记录检查。

当请求通过RemoteIpValve时,如果请求有一个X-Forwarded-For头(或你为remoteIpHeader配置的任何内容),则会在请求中添加一个名为org.apache.catalina.AccessLog.RemoteAddr的属性。然后,您可以在AccessLogValve中使用此选项,仅当此属性存在时才进行记录。

此示例适用于 tomcat9。

<Valve className="org.apache.catalina.valves.RemoteIpValve" />
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="access"
suffix=".log"
pattern="combined"
renameOnRotate="true"
requestAttributesEnabled="true"
maxDays="90"
conditionIf="org.apache.catalina.AccessLog.RemoteAddr"
/>

最新更新