Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 813
Kishore Tamire Avatar asked Jan 04 '18 21:01

Kishore Tamire


People also ask

Does Tomcat have access logs?

Tomcat will use the first AccessLog implementation found to log those requests that are rejected before they are passed to a container. The output file will be placed in the directory given by the directory attribute. The name of the file is composed by concatenation of the configured prefix , timestamp and suffix .


2 Answers

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.

like image 193
mikep Avatar answered Sep 28 '22 01:09

mikep


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

like image 21
Amino H. Avatar answered Sep 28 '22 00:09

Amino H.