Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Como registrar IPs remotos reais nos logs do Tomcat com Google Load Balancer

By Eran ChetzroniJan 24, 20192 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

1 2zp9g30kerhlin0nkhtc7q

No nosso suporte técnico, identificamos que o servidor Tomcat de um cliente no Google Cloud Platform não estava registrando o endereço IP remoto correto no log de acesso.

Isso acontecia, é claro, porque o servidor ficava atrás do excelente load balancer do Google, que adiciona o IP remoto do cliente ao header HTTP X-Forwarded-For.

1 2zp9g30kerhlin0nkhtc7q

Levamos algumas horas até encontrar a configuração correta no Tomcat, então decidimos publicar o passo a passo para você não perder tanto tempo quanto a gente:

Queríamos transformar isto:

remoteHostname: 130.211.2.139 // Endereço interno do load balancer
x-fwd-for= 192.115.200.197, 35.186.199.42

Nisto:

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

A classe "RemoteIpValve" substitui o endereço IP remoto e o hostname aparentes do cliente pela lista de IPs informada por um proxy ou load balancer em headers da requisição (por exemplo, "X-Forwarded-For").

Como funciona?

  • O RemoteIpValve percorre a lista de IPs e hostnames separados por vírgula enviada pelo load balancer ou proxy anterior, no header HTTP da requisição chamado $remoteIpHeader (valor padrão x-forwarded-for). Os valores são processados da direita para a esquerda.
  • Para cada ip/host da lista em internalProxies:
  • se bater com a lista de proxies internos, o ip/host é descartado/removido;
  • caso contrário, o ip/host é definido como o IP remoto e o loop é encerrado.

Agora basta montar a regex de "internalProxies" para contemplar as seguintes faixas de IP: 130.211.0.0/22 e 35.191.0.0/16

Essa faixa está publicada pelo Google aqui:

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

Também precisamos incluir o IP externo do nosso load balancer, já que ele entra no header X-Forwarded-For.

No nosso caso, é: 35.186.199.42

A regex final fica assim:

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

O resultado final deve ficar mais ou menos assim:

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

Pronto: é só adicionar isso ao seu server.xml e reiniciar o serviço do Tomcat.

Bons logs :)