Ir para o conteúdo principal
Github

Proxy e Load balancers

Servidores proxy, balanceadores de carga e outros intermediários podem alterar a forma como uma solicitação chega à aplicação. Quando há terminação TLS no proxy ou encaminhamento por outro host, a aplicação deixa de enxergar diretamente algumas informações da conexão original:

Essas informações são úteis em redirecionamentos, geração de URLs absolutas, registros de acesso, aplicação de políticas e geolocalização aproximada. Porém, um cabeçalho não é confiável só por estar presente: a aplicação deve aceitar esses valores apenas de proxies explicitamente confiáveis.

Configurando

Guia rápido para configurar o Inphinit quando a aplicação roda atrás de um load balancer ou proxy reverso.

1. Verifique quais cabeçalhos o servidor envia

Confirme quais cabeçalhos o load balancer ou proxy realmente envia à aplicação. Os nomes abaixo são convenções comuns; o conjunto disponível depende do produto e da configuração:

  • X-Forwarded-For
  • X-Forwarded-Proto
  • X-Forwarded-Host
  • X-Forwarded-Prefix

2. Determine os IPs confiáveis

Defina quais endereços IP ou redes correspondem aos proxies autorizados a fornecer esses cabeçalhos. O Inphinit só confia nos valores encaminhados quando o endereço que se conectou diretamente à aplicação estiver nessa lista:

  • IP do load balancer/proxy: use setKnownProxies.
  • Rede (CIDR) do load balancer/proxy: use setKnownNetworks.

Exemplos:

Tipo Exemplo
IP único 10.0.0.5
Rede CIDR 10.0.0.0/24

Segurança: qualquer cliente pode enviar cabeçalhos X-Forwarded-* falsos. Cadastre somente proxies que você conhece, evite redes amplas e, sempre que possível, bloqueie o acesso direto à aplicação (por firewall ou security group) para que ninguém contorne o proxy.

3. Habilite APP_FORWARDED

Nas variáveis de ambiente do servidor, defina:

APP_FORWARDED=1

Se estiver utilizando o arquivo .env, habilite essa variável nele.

4. Ajuste o system/main.php

Use uma das opções abaixo.

Por rede (CIDR)

$forwarded->setKnownNetworks(array( '10.0.0.0/24', '192.168.0.0/16' ));

Por IP (proxy)

$forwarded->setKnownProxies(array( '10.0.0.5', '10.0.0.6' ));

Referência rápida: provedores comuns

Provedor Cabeçalhos comuns IPs confiáveis
Cloudflare X-Forwarded-For, X-Forwarded-Proto, CF-Connecting-IP, CF-Visitor Use as faixas oficiais, mantendo-as atualizadas: https://www.cloudflare.com/ips/
AWS ALB/ELB X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Port Os IPs dos nós não são fixos. Use os CIDRs das sub-redes onde o ALB está, não a VPC inteira, e restrinja a entrada da aplicação ao security group do ALB.
AWS CloudFront X-Forwarded-For, CloudFront-Forwarded-Proto, CloudFront-Viewer-Address (alguns são opcionais e precisam ser habilitados na distribuição) Faixas publicadas em https://ip-ranges.amazonaws.com/ip-ranges.json (serviço CLOUDFRONT_ORIGIN_FACING, os IPs que o CloudFront usa para se conectar à sua origem). O CloudFront não envia X-Forwarded-Proto; veja o exemplo na seção "Ajustando os cabeçalhos".

Se houver mais de um proxy na frente (ex.: Cloudflare + ALB), inclua todos os IPs/redes intermediários na lista de confiáveis. Cada proxy deve acrescentar seu valor aos cabeçalhos, ou sobrescrevê-los, e nunca repassar valores arbitrários enviados pelo cliente.

Obtendo informações

Com APP_FORWARDED habilitada, as variáveis $forwarded e $app->forwarded ficam disponíveis. Os métodos getIp(), getProto(), getHost() e getPrefix() retornam, respectivamente, o IP do cliente, o esquema original, o host original e o prefixo de caminho informado pelo proxy, de acordo com os cabeçalhos e as flags configurados. Exemplo:

$app->action('GET', '/sample', function ($app) { $ip = $app->forwarded->getIp(); });

Se a aplicação puder rodar em ambientes diferentes, com ou sem proxy, trate os dois cenários. Sem o componente, use $_SERVER['REMOTE_ADDR'], que é o endereço de quem se conectou diretamente ao servidor:

$app->action('GET', '/sample', function ($app) { if ($app->forwarded) { $ip = $app->forwarded->getIp(); } else { $ip = $_SERVER['REMOTE_ADDR']; } });

Para montar URLs, use sempre as constantes INPHINIT_PATH e INPHINIT_BASE_URL: elas já refletem os valores encaminhados (esquema, host e prefixo), incluindo os cabeçalhos personalizados definidos com $forwarded->setHeaderName(). Como host e esquema afetam as URLs absolutas, aceite esses valores apenas de proxies confiáveis. Exemplo:

$app->action('GET', '/sample', function ($app) { // Obtém o IP $ip = $app->forwarded ? $app->forwarded->getIp() : $_SERVER['REMOTE_ADDR']; // Obtém protocolo://host/prefixo/rota $url = INPHINIT_BASE_URL . INPHINIT_PATH; });

Ajustando os cabeçalhos

Por padrão, o componente usa X-Forwarded-For, X-Forwarded-Proto e X-Forwarded-Host. Alguns proxies usam cabeçalhos próprios ou enviam informações adicionais; nesse caso, ajuste as flags e os nomes dos cabeçalhos em main.php. O exemplo abaixo habilita também X-Forwarded-Prefix. Habilite apenas o que o proxy realmente envia:

use Inphinit\Experimental\Http\Forwarded; $forwarded->setFlags(Forwarded::IP|Forwarded::PROTO|Forwarded::HOST|Forwarded::PREFIX); $app->action('GET', '/', 'Home::index');

A seguir, todas as flags suportadas:

Flag Descrição
Forwarded::IP O valor de $forwarded->getIp() será obtido de X-Forwarded-For ou do cabeçalho configurado.
Forwarded::PROTO O valor de $forwarded->getProto() será obtido de X-Forwarded-Proto ou do cabeçalho configurado.
Forwarded::HOST O valor de $forwarded->getHost() será obtido de X-Forwarded-Host ou do cabeçalho configurado.
Forwarded::PREFIX O valor de $forwarded->getPrefix() será obtido de X-Forwarded-Prefix ou do cabeçalho configurado.
Forwarded::RFC7239 Os valores serão obtidos do cabeçalho padronizado Forwarded (RFC 7239), que define os parâmetros for (cliente), proto (protocolo) e host (host); o RFC não define prefixo de caminho. Essa flag tem prioridade sobre as demais, então use-a apenas se o proxy enviar esse cabeçalho.

Proxies e provedores também podem enviar cabeçalhos específicos, como Client-Ip e CF-Connecting-IP. Como o nome varia conforme o provedor, configure-o no main.php:

use Inphinit\Experimental\Http\Forwarded; // Customiza o cabeçalho que retorna o IP $forwarded->setHeaderName(Forwarded::IP, 'cf-connecting-ip'); // Customiza o cabeçalho que retorna o esquema (https ou http) $forwarded->setHeaderName(Forwarded::PROTO, 'x-url-scheme'); // Customiza o cabeçalho que retorna o host $forwarded->setHeaderName(Forwarded::HOST, 'x-host'); $app->action('GET', '/', 'Home::index');

Exemplo para o AWS CloudFront, que informa o esquema em CloudFront-Forwarded-Proto (habilite-o na política de requisição da origem):

use Inphinit\Experimental\Http\Forwarded; $forwarded->setHeaderName(Forwarded::PROTO, 'cloudfront-forwarded-proto'); $app->action('GET', '/', 'Home::index');