How to log Client IP and X-Forwarded-For IP in tomcat access log

31,348

Solution 1

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

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

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.

Solution 2

I had this issue using an Apache reverse proxy in front of a Java application running on Tomcat/9.0.12

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

<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

%a will show the proxy ip(or load-balancer) and %{x-forwarded-for}i will show the user ip

Solution 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" />

You can add these two Valve definition into context.xml. So you can see remote ip in both case. Through load balancer or direct.

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.

AccessLogValve config just logs "org.apache.tomcat.remoteAddr" request attribute which holds correct remote ip.

Share:
31,348
Kishore Tamire
Author by

Kishore Tamire

Updated on July 09, 2022

Comments

  • Kishore Tamire
    Kishore Tamire almost 2 years

    How to log Client IP and X-Forwarded-For IP in tomcat access log.

    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?

  • Kishore Tamire
    Kishore Tamire over 6 years
    This works when going through the load balancer, but it is not logging the IP address when accessing the tomcat instnace directly skipping the load balancer URL. Is there a way to log IP address in both the cases?
  • Mehmet Sunkur
    Mehmet Sunkur over 6 years
    Both of them supports Valve definitions. If you need to that for all apps that works on tomcat you need to do it in server.xml.
  • Yu Jiaao
    Yu Jiaao over 4 years
    Does case sensitive for x-forwarded-for?
  • sandeepd
    sandeepd almost 4 years
    You will also need to set requestAttributesEnabled attribute to true in AccessLogValue.
  • asgs
    asgs almost 2 years
    @YuJiaao http headers are not case sensitive