This is a follow up from my earlier question on capturing the X-Forwarded-For IP address in across multiple proxies. Now, I'm looking to capture the Client's IP in the application's (Shibboleth's IdP) logs.

The follow is:

Client > Load Balancer > Apache httpd server > Tomcat server (running Shibboleth's IdP)

The variable with the Client's IP at the Load Balancer is ClientIP which I can capture in the web server's logs using LogFormat "%{ClientIP}i ... " and similarly in Tomcat's access logs using these inserver.xml`:

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
protocolHeaderHttpsValue="https" />

<Valve className="org.apache.catalina.valves.AccessLogValve" 
pattern="%{ClientIP}i %h %l %u %t %r %>s %b %{Referer}i %{User-Agent}i" resolveHosts="false"/>

Now, I'm looking to capture this IP in Shibboleth's IdP audit logs. This discussion talks about using mod_rpaf for Apache but doesn't get into the details. I'm hoping to do without installing additional modules.

Looks like I'm missing a couple of (small?) pieces here. Any ideas? Many thanks!


After digging at LogBack's documentation on logging client IPs and the corresponding code for the MDCInsertingServletFilter servlet, turns out you must use the X-Forwarder-For header.

We replaced ClientIP with X-Forwarder-For in the load balancer, updated httpd.conf's LogFormat to log X-Forwarder-For, then updated Shibboleth's logging.xml file as follows for the audit logs:

<appender name="IDP_AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">

  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">

We made similar changes to the idp-process as well, and did not have to update Tomcat's logging.

Hope this helps others.

Edit 1: Tomcat Logging

Turns out, after a while, the X-Forwarded-For IP address stopped appearing in Shib's IdP logs. We ended up adding the RemoteIpValve in tomcat and restarting. Looks like it is needed after all:

  <Valve className="org.apache.catalina.valves.RemoteIpValve"
   trustedProxies="--IPs here--"
   protocolHeaderHttpsValue="https" />
  • 1
    I'm not sure %X{req.xForwardedFor} is needed. When you use the Tomcat RemoteIpValve, it will set request.remoteAddr to the value of the X-Forwarded-For header, then it unsets the X-Forwarded-For header. So in logging.xml you would use %mdc{clientIP} (which shouldn't be needed because %msg includes the client IP). For more info: tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/valves/… (scroll down to the samples) – bmaupin Sep 23 '15 at 17:44
  • @bmaupin thanks for weighing in. It has been a while since we got this working, but I faintly recall the only (or the first perhaps?) combination to log the actual IP was MDC filter + Tomcat valve + X-Forwarded-For. I don't recall any combination of clientIP working. The app has since moved to another platform, still this might be worth a second look. – KM. Sep 24 '15 at 13:57
  • 1
    Ah, yes if you're using the MDC filter that might change things. On my end all I needed was 1. X-Forwarded-For in the load balancer 2. RemoteIpValve in the Tomcat server.xml, then the client IP showed up fine in the Shibboleth logs. – bmaupin Sep 24 '15 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.