
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.

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 balancerx-fwd-for= 192.115.200.197, 35.186.199.42en cela :
remoteHostname: 192.115.200.197 // Vraie IP du clientx-fwd-for= 192.115.200.197, 35.186.199.42La 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éfautx-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 :)