java 如何在tomcat访问日志中记录客户端IP和X-Forwarded-For IP
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48103673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to log Client IP and X-Forwarded-For IP in tomcat access log
提问by Kishore Tamire
How to log Client IP and X-Forwarded-For IP in tomcat access log.
如何在 tomcat 访问日志中记录客户端 IP 和 X-Forwarded-For IP。
I am using %{X-Forwarded-For}i and it logs the actual client address if I access through load balancer. But does not log the actual client address if I directly access the tomcat instance. Is there a way to display the actual client IP address in both the cases?
我正在使用 %{X-Forwarded-For}i 并且如果我通过负载平衡器访问它会记录实际的客户端地址。但是如果我直接访问 tomcat 实例,则不会记录实际的客户端地址。有没有办法在这两种情况下显示实际的客户端 IP 地址?
回答by mikep
From http://www.techstacks.com/howto/configure-access-logging-in-tomcat.html:
从http://www.techstacks.com/howto/configure-access-logging-in-tomcat.html:
If you are running a version of tomcat greater than version 6.0.21 or tomcat 7, you can take advantage of the new Remote IP Valve. For access logging, the nice thing about this valve is that it will swap the client IP with an IP address passed with the X-Forwarded-For header—automatically—if an IP address is passed in the X-Forwarded-For header. Loading it is pretty easy. Just add the org.apache.catalina.valves.RemoteIpValve to your server.xml before your AccessLogValve declaration. For example:
如果您运行的是高于 6.0.21 或 tomcat 7 的 tomcat 版本,您可以利用新的远程 IP Valve。对于访问日志记录,此阀的好处在于,如果在 X-Forwarded-For 标头中传递了 IP 地址,它将自动将客户端 IP 与通过 X-Forwarded-For 标头传递的 IP 地址交换。加载它非常容易。只需在您的 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>
If you are using a version of tomcat 6 older than 6.0.21 and you want to store the X-Forwarded-For IP address instead, then you could modify the pattern property of your AccessLogValve. You'll need to remove the "common" or "combined" pattern and replace it with one of the following patterns:
如果您使用的是早于 6.0.21 的 tomcat 6 版本,并且您想要存储 X-Forwarded-For IP 地址,那么您可以修改 AccessLogValve 的模式属性。您需要删除“common”或“combined”模式并将其替换为以下模式之一:
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
The main problem here, that RemoteIP Valve does take care of, is that you'll only get the X-Forwarded-For address in the logs. If you hit the app server directly, bypassing the device that is inserting the X-Forwarded-For header in the request, you won't get an IP address logged. You will still log a request—you just will not know where it came from.
此处的主要问题,即 RemoteIP Valve 确实处理的,是您只能在日志中获得 X-Forwarded-For 地址。如果您直接访问应用程序服务器,绕过在请求中插入 X-Forwarded-For 标头的设备,则不会记录 IP 地址。你仍然会记录一个请求——你只是不知道它来自哪里。
回答by Amino H.
I had this issue using an Apache reverse proxy in front of a Java application running on Tomcat/9.0.12
我在 Tomcat/9.0.12 上运行的 Java 应用程序前面使用 Apache 反向代理遇到了这个问题
I fixed it by adding this to Tomcat conf/server.xml , where to place the valve will depend on weather you want to apply this per Engine/Host/Context , i have added this 2 valves
我通过将其添加到 Tomcat conf/server.xml 来修复它,放置阀门的位置将取决于您想要按 Engine/Host/Context 应用它的天气,我添加了这 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" />
you don't need to define all remoteIpHeader and protocolHeader as these are the default values but I have added them just for clarity reason https://tomcat.apache.org/tomcat-9.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html
您不需要定义所有 remoteIpHeader 和 protocolHeader,因为这些是默认值,但为了清楚起见,我添加了它们https://tomcat.apache.org/tomcat-9.0-doc/api/org/apache/catalina/阀门/RemoteIpValve.html
%a will show the proxy ip(or load-balancer) and %{x-forwarded-for}i will show the user ip
%a 将显示代理 ip(或负载均衡器)和 %{x-forwarded-for}i 将显示用户 ip
回答by Mehmet Sunkur
<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" />
You can add these two Valve definition into context.xml. So you can see remote ip in both case. Through load balancer or direct.
您可以将这两个 Valve 定义添加到 context.xml 中。所以你可以在这两种情况下看到远程 ip。通过负载均衡器或直接。
org.apache.catalina.valves.RemoteIpValve detects "x-forwarded-for" header. If there is "x-forwarded-for" in header puts its value into "org.apache.tomcat.remoteAddr" request attribute. If there is no "x-forwarded-for" in header puts client ip addr into "org.apache.tomcat.remoteAddr" request attribute.
org.apache.catalina.valves.RemoteIpValve 检测“x-forwarded-for”标头。如果标头中有“x-forwarded-for”,则将其值放入“org.apache.tomcat.remoteAddr”请求属性中。如果标头中没有“x-forwarded-for”,则将客户端 ip 地址放入“org.apache.tomcat.remoteAddr”请求属性中。
AccessLogValve config just logs "org.apache.tomcat.remoteAddr" request attribute which holds correct remote ip.
AccessLogValve 配置只记录保存正确远程 IP 的“org.apache.tomcat.remoteAddr”请求属性。