Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Echte Client-IPs in Tomcat-Logs mit Google Load Balancer protokollieren

By Eran ChetzroniJan 24, 20192 min read

Diese Seite ist auch in English, Español, Français, Italiano, 日本語 und Português verfügbar.

1 2zp9g30kerhlin0nkhtc7q

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.

1 2zp9g30kerhlin0nkhtc7q

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-Adresse
x-fwd-for= 192.115.200.197, 35.186.199.42

sollte folgender werden:

remoteHostname: 192.115.200.197 // Echte Client-IP
x-fwd-for= 192.115.200.197, 35.186.199.42

Die 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 (Standardwert x-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 :)