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:
- 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).
- Se sim, qual header HTTP seus proxies usam para passar o IP do cliente para a aplicação?
Caso 1: Sem proxy
Seção intitulada “Caso 1: Sem proxy”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()Caso 2: Proxies usando o header X-Forwarded-For
Seção intitulada “Caso 2: Proxies usando o header X-Forwarded-For”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 seeNesse 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),)Caso 3: Proxies usando o header X-Real-IP
Seção intitulada “Caso 3: Proxies usando o header X-Real-IP”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.
Comportamento padrão
Seção intitulada “Comportamento padrão”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.