Cada linha do registo de acesso mostra o mesmo endereço de loopback, enquanto a página carrega e o certificado é validado corretamente. Nada está avariado no sentido de ser inacessível, e é por isso que este caso sobrevive durante meses. O que se avariou foi a atribuição: o backend web registra o endereço do salto que reencaminhou a ligação, e cada decisão posterior que confiou no registo herdou a mesma resposta errada.

As verificações abaixo vão do cabo para dentro. Pare na primeira que explica o valor que vê, porque cada passo seguinte assume que os anteriores já são verdadeiros. Nenhuma delas exige adivinhar a configuração do front-end.

Siga as duas ligações, não a linha do registo

O Port-Share multiplexa dois protocolos num único ouvinte TCP. O OpenVPN inspeciona os primeiros bytes de uma ligação de entrada, mantém-na quando parece do seu próprio protocolo e entrega tudo o resto a um segundo destino. Esse destino é normalmente um servidor web no mesmo anfitrião, pelo que o socket aceite do servidor web tem o processo OpenVPN como par.

ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'

O primeiro comando mostra quem é dono do ouvinte público. O segundo mostra as ligações que chegam à porta do backend, e o endereço do seu par é o que o registo de acesso vai imprimir. Se esse par for loopback, o registo é rigoroso e a informação perdeu-se uma camada antes. Mudar o nome do campo do registo ou ativar um módulo de IP de cliente não vai recuperar um endereço que a ligação nunca transportou.

Esta é a verificação que decide tudo o resto. Se o par do backend for o endereço do navegador, partilhar a porta não é o seu problema e o formato do registo é.

O reencaminhamento de transporte não é injeção de cabeçalho

O reencaminhador move bytes. Não analisa HTTP, por isso não pode inserir um cabeçalho num pedido que nunca lê como pedido, nem pode acrescentar nada a um fluxo TLS que deixa passar intacto. Um módulo que espera um cabeçalho de proxy continuará à espera de um que nenhum componente produz.

Dois mecanismos podem transportar o endereço original, e ambos exigem acordo nas duas pontas. O protocolo PROXY antepõe um pequeno cabeçalho à ligação, e o backend tem de estar configurado para o esperar; um backend que não o espera tratará esses bytes como o início do pedido e falhará de forma confusa. Os cabeçalhos de proxy de confiança como X-Forwarded-For funcionam quando um proxy que compreende HTTP os define e ao backend se diz quais os pares que os podem afirmar.

Nenhum dos dois é automático, e nenhum é seguro por omissão. Um backend que acredita em qualquer cabeçalho reencaminhado de entrada permite ao cliente escolher o seu próprio endereço, o que transforma uma imprecisão do registo numa fuga ao controlo de acesso. Execute a demonstração uma vez num anfitrião de testes antes de confiar em qualquer cabeçalho num caminho de produção.

curl -sS -H 'X-Forwarded-For: 127.0.0.1' https://site.example.com/health
grep -F '127.0.0.1' /var/log/nginx/access.log | tail -n 3

O diretório opcional de mapeamento de origens

Partilhar a porta tem um argumento de diretório opcional que registra um mapeamento entre o endereço de origem original e a ligação de reencaminhamento, em plataformas onde a funcionalidade está implementada. Espera-se que o lado web consulte esse mapeamento; não é um cabeçalho e não é injetado no pedido.

Esse desenho merece ser conhecido porque explica por que algumas instalações relatam endereços reais e outras não, com uma configuração de front-end aparentemente idêntica. A diferença está no lado recetor, e costuma viver num módulo ou numa correção que a maioria dos servidores web empacotados não ativa por omissão. Leia a documentação do seu servidor web para saber o gancho exato que oferece e confirme que o módulo está carregado em vez de o presumir.

Se seguir este caminho, trate-o como uma integração de duas metades: o mapeamento escrito pelo reencaminhador e a consulta feita pelo backend. Verifique ambos e confirme que o diretório sobrevive a um reinício e não cresce sem limite num ouvinte ocupado.

Decida que componente garante o endereço

Antes de alterar a configuração, nomeie o componente a quem é permitido afirmar um endereço de cliente e os componentes a quem é permitido acreditarem nele. Uma única resposta escrita evita a deriva habitual, em que três camadas diferentes confiam cada uma numa fonte diferente.

Três desenhos cobrem a maioria das necessidades. Mantenha o ouvinte público e o ouvinte web separados, para que o servidor web veja pares reais e não exista qualquer problema de atribuição. Coloque à frente um proxy inverso que compreenda HTTP, termine ou analise o pedido aí, e deixe-o definir um cabeçalho reencaminhado para um backend que só confia nesse proxy. Ou mantenha a partilha de porta e aceite que os registos mostram o salto, com regras de acesso escritas contra a identidade da aplicação em vez de um endereço.

O que não funciona é tratar um endereço de loopback reencaminhado como prova de que o pedido se originou nesta máquina. Essa inferência é exatamente ao contrário: o endereço está presente precisamente porque um componente local fez a ligação. Uma regra escrita assim admite qualquer pessoa que consiga alcançar o ouvinte.

Teste a regra, não a página

Uma página que carrega prova que o caminho de reencaminhamento funciona e não diz nada sobre a atribuição. Teste o consumidor do endereço: a regra de acesso, o limite de taxa, a entrada de auditoria, a consulta geográfica.

curl -sS -o /dev/null -w '%{http_code}\n' https://site.example.com/
tail -n 5 /var/log/nginx/access.log
grep -c '' /var/log/nginx/access.log

Compare um pedido externo autorizado com os registos tanto do front-end como do backend, e confirme que uma regra que devia negar ainda nega e uma que devia admitir ainda admite. Se a linha do registo está correta mas a regra continua a comportar-se como se todos fossem locais, a regra lê um campo diferente daquele que corrigiu.

Termine escrevendo a cadeia de atribuição nas notas de implementação: que ouvinte, que reencaminhador, que cabeçalho ou mapeamento e que backend está configurado para confiar nele. A próxima pessoa que ler uma linha de registo precisará das quatro, e a ausência dessa nota é como o mesmo pedido de suporte se reabre um ano depois. Mantenha-a ao lado da configuração e não num fio de conversa.

Artigos relacionados