O que o REMOTE_ADDR do PHP realmente informa atrás de uma VPN
É um valor que o servidor web forneceu, não uma consulta ao túnel. Percorra o caminho do pedido, verifique quem pode reescrevê-lo e mantenha a identidade na aplicação.
Alguém pergunta por que um utilizador de VPN aparece no registo da aplicação com um endereço que pertence à gateway, ou com um endereço que mudou depois do almoço. A resposta começa por aquilo que o valor é: uma entrada que o servidor web colocou no ambiente do pedido. Não é uma consulta ao túnel, não é uma identidade de certificado e não é a promessa de que o número pertence a uma só pessoa. Lê-lo como qualquer destas três coisas produz respostas confiantes que estão erradas de formas diferentes.
O valor vem do servidor, não do túnel
O PHP recebe o ambiente do pedido daquilo que executou o script. A referência das variáveis de servidor do PHP descreve estas entradas como criadas pelo servidor web, com uma disponibilidade que depende da forma como o pedido chegou.
Um script executado como hook de linha de comandos da VPN é um contexto de execução completamente diferente. Não tem pedido web, não tem socket de cliente e não tem REMOTE_ADDR, e é por isso que copiar código web para um hook produz valores vazios em vez de errados. O hook tem o seu próprio ambiente, preenchido pelo daemon, e está documentado em separado. Procurar REMOTE_ADDR aí é procurar uma variável que nunca foi definida.
Tenha essa distinção presente antes de comparar dois registos. Pode estar a comparar um pedido de página com um hook, o que não é comparação nenhuma. Verifique primeiro o contexto de execução e depois o endereço.
Percorra o caminho do pedido antes de confiar no número
O endereço reportado é o par da ligação que o servidor web viu. Introduza qualquer coisa entre o cliente e esse servidor e o par muda. Tradução, terminação e balanceamento movem cada uma a observação um salto mais longe do utilizador.
Quatro caminhos comuns produzem quatro observações diferentes.
| Path to the listener | What can be reported |
|---|---|
| Client routed straight to the private listener, no translation | The client's tunnel address |
| Gateway translates the source before forwarding | The gateway's translated address |
| Reverse proxy terminates the client and opens its own backend connection | The proxy's backend address |
| Load balancer in front of two proxies | Whichever hop the server treats as its peer |
Anote o caminho com o nome do destino, a família de endereços e cada ponto de tradução. Sem esse mapa, um valor correto e um valor errado parecem idênticos numa linha de registo. Duas linhas de diagrama poupam uma tarde de discussão.
A substituição só acontece onde está configurada
Um servidor ou framework pode substituir deliberadamente o endereço do cliente. O módulo remote-IP do Apache e o módulo real-IP do NGINX fazem ambos isso, e o valor que o PHP recebe depende dessa configuração e dos parâmetros passados ao gestor do script.
Portanto, REMOTE_ADDR não é universalmente o par TCP intacto. É o par tal como o servidor decidiu reportá-lo depois de aplicar a sua própria política. Essa distinção decide se o valor é prova ou decoração.
Pergunte ao responsável do servidor qual campo é autoritativo nesta instalação e como o par original é preservado quando a substituição acontece. Se ninguém souber responder, o registo ainda não prova nada.
Não leia os cabeçalhos de encaminhamento com fé
Quem chama pode enviar ele próprio cabeçalhos de encaminhamento. Tratar a primeira entrada separada por vírgulas como endereço de utilizador verificado é decidir acreditar em quem se ligar, o oposto daquilo para que o cabeçalho serve. O cabeçalho descreve uma cadeia, e só uma camada de confiança pode abonar essa cadeia.
Use o suporte de proxies de confiança do servidor ou do framework com a cadeia de proxies real configurada, e deixe-o descartar valores de origens fora dessa cadeia. A análise escrita à mão é onde vive a maioria das falhas interessantes.
Um endereço reportado por um proxy também não altera a origem dos pacotes que uma firewall a montante vê. Mantenha os metadados HTTP e a filtragem de rede como observações separadas, porque respondem a perguntas diferentes.
Use a identidade da aplicação para decidir
Para aceder aos registos de um utilizador, apoie-se no principal autenticado e nas regras de autorização da aplicação. Um endereço interno pode ser reatribuído, e um endereço traduzido pode representar centenas de utilizadores simultâneos. Nenhuma destas propriedades pode ser reparada por uma verificação de endereço.
Se as operações precisarem de ligar um pedido a uma sessão VPN, junte o endereço observado e o carimbo temporal aos registos de sessão autoritativos segundo o modelo de tradução que documentou. Isso produz uma associação defensável; um endereço sozinho não.
Para diagnóstico, registe os poucos campos de que precisa em vez de todo o array do servidor, que pode transportar cabeçalhos e material de autenticação. A conclusão útil diz o que este valor significa nesta instalação, não qual valor se parece mais com um cliente.