
Im Rahmen unseres technischen Supports ist uns aufgefallen, dass der Tomcat-Server eines Kunden auf der Google Cloud Platform im Access Log nicht die korrekte Remote-IP-Adresse erfasst.
Der Grund: Der Server lief hinter Googles hervorragendem Load Balancer – und dieser hängt die Remote-IP des Clients an den HTTP-Header X-Forwarded-For an.

Wir haben einige Stunden gebraucht, um die passende Tomcat-Konfiguration zu finden. Damit Sie sich diese Zeit sparen, teilen wir unsere Lösung hier öffentlich:
Aus diesem Zustand:
remoteHostname: 130.211.2.139 // Interne Load-Balancer-Adressex-fwd-for= 192.115.200.197, 35.186.199.42sollte folgender werden:
remoteHostname: 192.115.200.197 // Echte Client-IPx-fwd-for= 192.115.200.197, 35.186.199.42Die Klasse "RemoteIpValve" ersetzt die scheinbare Remote-IP und den Hostnamen des Clients im Request durch die IP-Liste, die ein Proxy oder Load Balancer per Request-Header (z. B. "X-Forwarded-For") mitliefert.
Wie funktioniert das?
- RemoteIpValve iteriert über die kommagetrennte Liste von IPs und Hostnamen, die der vorgelagerte Load Balancer oder Proxy im HTTP-Header
$remoteIpHeader(Standardwertx-forwarded-for) übergibt. Die Werte werden von rechts nach links verarbeitet. - Für jede IP bzw. jeden Host der Liste gilt im Abgleich mit internalProxies:
- Trifft der Eintrag auf die Liste der internen Proxies zu, wird er verworfen.
- Andernfalls gilt dieser Eintrag als Remote-IP, und die Schleife endet.
Jetzt müssen wir nur noch die Regex für "internalProxies" so bauen, dass sie folgende IP-Bereiche abdeckt: 130.211.0.0/22 und 35.191.0.0/16.
Google veröffentlicht diese Bereiche hier:
https://cloud.google.com/load-balancing/docs/https/#firewall_rules
"130\.211\.\d{1,3}\.\d{1,3}|35\.191\.\d{1,3}\.\d{1,3}"Außerdem müssen wir die externe IP unseres Load Balancers ergänzen, da auch sie im X-Forwarded-For-Header landet.
In unserem Fall ist das: 35.186.199.42
Die resultierende Regex lautet:
"130\.211\.\d{1,3}\.\d{1,3}|35\.191\.\d{1,3}\.\d{1,3}|35\.186\.199\.42"Das Endergebnis sieht in etwa so aus:
<Valve className="org.apache.catalina.valves.RemoteIpValve"internalProxies="130\.211\.\d{1,3}\.\d{1,3}|35\.191\.\d{1,3}\.\d{1,3}|35\.186\.199\.42" /><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access_log" suffix=".txt" pattern="combined" requestAttributesEnabled="true" />Tragen Sie das einfach in Ihre server.xml ein und starten Sie den Tomcat-Dienst neu.
Viel Spaß beim Loggen :)