Pular para o conteúdo

Endereço IP

O endereço IP tem um papel fundamental em HTTP — ele é usado para controle de acesso, auditoria, análise baseada em geografia e mais. Echo expõe Context#RealIP() para recuperá-lo.

Recuperar o IP real do cliente não é trivial, especialmente quando proxies L7 ficam na frente da sua aplicação. Nesse caso, o IP real precisa ser repassado por HTTP dos proxies para sua app — mas você não deve confiar incondicionalmente em headers HTTP, ou corre o risco de ser enganado. Isso é um risco de segurança.

Para recuperar o IP de forma confiável e segura, sua aplicação precisa conhecer toda a sua infraestrutura. No Echo, você configura isso por meio de Echo#IPExtractor.

Comece com duas perguntas para encontrar a abordagem correta:

  1. Você coloca algum proxy HTTP (L7) na frente da aplicação? Isso inclui load balancers de nuvem (como AWS ALB ou GCP HTTP LB) e proxies open-source (como Nginx, Envoy ou um gateway de ingresso Istio).
  2. Se sim, qual header HTTP seus proxies usam para passar o IP do cliente para a aplicação?

Se não há proxy (a app encara a internet diretamente), o único endereço em que você pode confiar é o da camada de rede. Todo header HTTP não é confiável porque clientes têm controle total sobre eles.

Use echo.ExtractIPDirect():

e.IPExtractor = echo.ExtractIPDirect()

X-Forwarded-For (XFF) é o header mais comum para retransmitir IPs de clientes. A cada salto, o proxy acrescenta o IP do request ao final do header.

┌──────────┐ ┌──────────┐ ┌──────────┐
───────────>│ Proxy 1 │───────────>│ Proxy 2 │───────────>│ Your app │
│ (IP: b) │ │ (IP: c) │ │ │
└──────────┘ └──────────┘ └──────────┘
Case 1.
XFF: "" "a" "a, b"
~~~~~~
Case 2.
XFF: "x" "x, a" "x, a, b"
~~~~~~~~~
↑ What your app will see

Nesse caso, pegue a primeira leitura de IP não confiável a partir da direita. Nunca pegue a primeira da esquerda, pois o cliente a controla. Aqui “confiável” significa que você tem certeza de que o IP pertence à sua infraestrutura. No exemplo acima, se b e c são confiáveis, o IP do cliente é a nos dois casos — nunca x.

Use ExtractIPFromXFFHeader(...TrustOption):

e.IPExtractor = echo.ExtractIPFromXFFHeader()

Por padrão, ele confia em endereços IP internos — loopback, link-local unicast, private-use e unique local addresses de RFC 6890, RFC 4291 e RFC 4193. Controle isso com TrustOptions:

e.IPExtractor = echo.ExtractIPFromXFFHeader(
echo.TrustLoopback(false), // e.g. IPv4 starting with 127.
echo.TrustLinkLocal(false), // e.g. IPv4 starting with 169.254.
echo.TrustPrivateNet(false), // e.g. IPv4 starting with 10. or 192.168.
echo.TrustIPRange(lbIPRange),
)

X-Real-IP é outro header para retransmitir o IP do cliente, mas diferentemente de XFF ele carrega apenas um único endereço.

Se seus proxies definem este header, use ExtractIPFromRealIPHeader(...TrustOption):

e.IPExtractor = echo.ExtractIPFromRealIPHeader()

Assim como com XFF, ele confia em endereços IP internos por padrão e aceita as mesmas TrustOptions.

Por padrão, Echo considera ao mesmo tempo o primeiro header XFF, o header X-Real-IP e o IP da camada de rede.

Como este artigo deve deixar claro, essa não é uma boa escolha. Ela continua sendo o padrão apenas por compatibilidade retroativa.