Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Journaliser les vraies IP distantes dans Tomcat avec Google Load Balancer

By Eran ChetzroniJan 24, 20192 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

1 2zp9g30kerhlin0nkhtc7q

Dans le cadre de notre support technique, nous avons constaté que le serveur Tomcat d'un client hébergé sur Google Cloud Platform n'utilisait pas la bonne adresse IP distante dans son journal d'accès.

La cause était évidente : le serveur se trouvait derrière le formidable load balancer de Google, qui ajoute l'adresse IP distante du client à l'en-tête HTTP X-Forwarded-For.

1 2zp9g30kerhlin0nkhtc7q

Il nous a fallu plusieurs heures pour trouver la bonne configuration Tomcat. Nous avons donc choisi de la partager publiquement, pour vous éviter d'y passer autant de temps que nous :

Nous voulions transformer ceci :

remoteHostname: 130.211.2.139 // Adresse interne du load balancer
x-fwd-for= 192.115.200.197, 35.186.199.42

en cela :

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

La classe RemoteIpValve remplace l'adresse IP distante et le hostname apparents du client par la liste d'adresses IP transmise par un proxy ou un load balancer dans un en-tête de requête (par exemple X-Forwarded-For).

Comment cela fonctionne-t-il ?

  • RemoteIpValve parcourt la liste d'IP et de hostnames séparés par des virgules, transmise par le load balancer ou le proxy en amont dans l'en-tête HTTP de la requête nommé $remoteIpHeader (valeur par défaut x-forwarded-for). Les valeurs sont traitées de droite à gauche.
  • Pour chaque ip/host de la liste dans internalProxies :
  • s'il correspond à la liste des proxies internes, l'ip/host est absorbé puis supprimé ;
  • sinon, l'ip/host est déclaré comme étant l'IP distante et la boucle s'arrête.

Il ne reste plus qu'à écrire la regex internalProxies couvrant les plages IP suivantes : 130.211.0.0/22 et 35.191.0.0/16.

Ces plages sont publiées par Google ici :

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

Il faut également ajouter l'IP externe de notre load balancer, puisqu'elle figure aussi dans l'en-tête X-Forwarded-For.

Dans notre cas : 35.186.199.42.

La regex obtenue est donc :

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

Le résultat final ressemble à ceci :

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

Ajoutez simplement ce bloc à votre server.xml, puis redémarrez le service Tomcat.

Bon logging :)