Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Registra las IPs remotas reales en los logs de Tomcat con Google Load Balancer

By Eran ChetzroniJan 24, 20192 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

1 2zp9g30kerhlin0nkhtc7q

En nuestras operaciones de soporte técnico nos dimos cuenta de que el servidor Tomcat de un cliente en Google Cloud Platform no estaba usando la dirección IP remota correcta en el access log.

Esto ocurría, claro, porque estaba detrás del estupendo load balancer de Google, que agrega la IP remota del cliente al header HTTP X-Forwarded-For.

1 2zp9g30kerhlin0nkhtc7q

Nos llevó varias horas dar con la configuración correcta de Tomcat, así que decidimos publicarla para que ojalá tú no tengas que invertir tanto tiempo como nosotros:

Queríamos pasar de esto:

remoteHostname: 130.211.2.139 // Dirección interna del load balancer
x-fwd-for= 192.115.200.197, 35.186.199.42

A esto:

remoteHostname: 192.115.200.197 // IP real del cliente
x-fwd-for= 192.115.200.197, 35.186.199.42

La clase "RemoteIpValve" reemplaza la IP remota y el hostname aparentes del cliente en la petición por la lista de direcciones IP que entrega un proxy o un load balancer a través de los headers de la petición (por ejemplo, "X-Forwarded-For").

¿Cómo funciona?

  • RemoteIpValve recorre la lista de IPs y hostnames separados por comas que pasa el load balancer o proxy previo en el header HTTP de la petición indicado por $remoteIpHeader (valor por defecto: x-forwarded-for). Los valores se procesan de derecha a izquierda.
  • Para cada ip/host de la lista en internalProxies:
  • si coincide con la lista de proxies internos, esa ip/host se descarta;
  • en caso contrario, esa ip/host se toma como la IP remota y el recorrido se detiene.

Ahora solo falta armar el regex de "internalProxies" para cubrir los siguientes rangos de IP: 130.211.0.0/22 y 35.191.0.0/16

Google publica estos rangos aquí:

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

También hay que sumar la IP externa de nuestro load balancer, porque también aparece en el header X-Forwarded-For.

En nuestro caso es: 35.186.199.42

El regex final queda así:

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

El resultado final debería verse más o menos así:

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

Solo agrega esto a tu server.xml y reinicia el servicio de Tomcat.

¡A loggear con tranquilidad! :)