Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Registrare gli IP remoti reali nei log di Tomcat con Google Load Balancer

By Eran ChetzroniJan 24, 20192 min read

Questa pagina è disponibile anche in English, Deutsch, Español, Français, 日本語 e Português.

1 2zp9g30kerhlin0nkhtc7q

Durante le nostre attività di supporto tecnico, ci siamo accorti che il server Tomcat di un cliente su Google Cloud Platform non riportava l'indirizzo IP remoto corretto nell'access log.

Il motivo, naturalmente, era che si trovava dietro il fantastico load balancer di Google, che aggiunge l'indirizzo IP remoto del client all'header HTTP X-Forwarded-For.

1 2zp9g30kerhlin0nkhtc7q

Ci sono volute diverse ore per individuare la configurazione corretta di Tomcat, perciò abbiamo deciso di pubblicarla, sperando di farvi risparmiare tutto il tempo che ci abbiamo dedicato noi:

Volevamo trasformare questo:

remoteHostname: 130.211.2.139 // Internal load balancer address
x-fwd-for= 192.115.200.197, 35.186.199.42

In questo:

remoteHostname: 192.115.200.197 // Real client IP
x-fwd-for= 192.115.200.197, 35.186.199.42

La classe "RemoteIpValve" sostituisce l'indirizzo IP remoto e l'hostname apparenti del client con la lista di indirizzi IP fornita da un proxy o da un load balancer tramite un header della richiesta (ad esempio "X-Forwarded-For").

Come funziona?

  • RemoteIpValve scorre la lista, separata da virgole, di IP e hostname trasmessa dal load balancer o dal proxy a monte nell'header HTTP della richiesta denominato $remoteIpHeader (valore di default x-forwarded-for). I valori vengono elaborati da destra a sinistra.
  • Per ogni ip/host della lista in internalProxies:
  • se corrisponde alla lista degli internal proxies, l'ip/host viene scartato/rimosso;
  • altrimenti, l'ip/host viene considerato l'IP remoto e l'iterazione si interrompe.

A questo punto resta solo da definire la regex "internalProxies" per coprire i seguenti range di IP: 130.211.0.0/22 e 35.191.0.0/16

Questo range è pubblicato da Google qui:

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}"

Dobbiamo aggiungere anche l'IP esterno del nostro load balancer, perché viene inserito nell'header X-Forwarded-For.

Nel nostro caso è: 35.186.199.42

La regex finale è quindi:

"130\.211\.\d{1,3}\.\d{1,3}|35\.191\.\d{1,3}\.\d{1,3}|35\.186\.199\.42"

Il risultato finale dovrebbe essere più o meno così:

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

Non resta che aggiungerlo al vostro server.xml e riavviare il servizio Tomcat.

Buon logging :)