proxy_redirect não liga o NGINX ao seu host VPN
proxy_redirect reescreve cabeçalhos numa resposta que já chegou; nunca escolhe o upstream. Verifique proxy_pass, a rota até ao backend e depois os cabeçalhos.
O nome contém a palavra redirect, por isso ela é colada num bloco location quando um backend atrás da VPN não é alcançável. Nada muda, e a conclusão óbvia é que a diretiva está quebrada ou precisa de outra sintaxe. O que realmente aconteceu é mais simples e menos lisonjeiro: o proxy_redirect atua sobre uma resposta que já voltou, e nesta implantação nenhum pedido chegou tão longe.
Duas diretivas, dois momentos num único pedido
Um pedido HTTP através de um proxy reverso passa por várias decisões em sequência, e as duas diretivas ficam nos extremos opostos dessa sequência. Uma escolhe para onde vai o pedido. A outra edita certos cabeçalhos na resposta que volta.
| Directive | When it acts | What it can change |
|---|---|---|
proxy_pass | Before any bytes leave the proxy | Which upstream receives the request |
proxy_redirect | After the upstream responds | Matching Location and Refresh text |
Essa ordem é a resposta inteira. Se a segunda linha nunca for executada porque a primeira falhou, a segunda diretiva não está mal configurada, é simplesmente inalcançável. Por muito que se reescreva a segunda linha, a resposta que ela devia editar não vai surgir. Diagnostique a partir da primeira linha para fora, e o comportamento confuso resolve-se numa rota em falta ou numa ligação recusada.
Escolher o upstream pertence ao proxy_pass
Suponha que o NGINX corre num host de entrada público e alcança uma aplicação em 10.40.0.20:8080 através da sua VPN. O fragmento que escolhe essa aplicação é assim, dentro de um bloco server existente:
location / {
proxy_pass http://10.40.0.20:8080;
}
Use o esquema, o endereço e a porta reais, e trate isto como um fragmento e não como uma implantação. O host de entrada também tem de manter a rota VPN, um caminho de encaminhamento permitido e tráfego de retorno funcional para esse serviço, porque um proxy que alcança um endereço no papel ainda precisa do consentimento do kernel.
A referência do módulo proxy mantém a seleção do upstream separada da reescrita dos cabeçalhos de resposta, e nota que um valor proxy_pass com um URI altera a forma como o prefixo location correspondente é substituído. Acrescentar ou remover componentes do caminho sem verificar o URL que a aplicação espera é uma forma fiável de produzir um 404 que parece uma falha de encaminhamento.
proxy_redirect corrige respostas que expõem um endereço privado
Quando o tráfego começa a fluir, um backend pode responder com um cabeçalho Location que nomeia o seu endereço privado. Um navegador que siga esse cabeçalho sai do ponto de entrada público e tenta alcançar algo que não consegue resolver. Uma reescrita de resposta configurada de propósito mapeia o URL privado no público:
proxy_redirect http://10.40.0.20:8080/ https://app.example.com/;
Substitua os dois lados por valores reais. Compreenda também o âmbito estreito: o texto dos cabeçalhos Location e Refresh correspondentes é reescrito, mas os URL incorporados em HTML, JavaScript ou ficheiros descarregados não.
Se uma aplicação constrói ligações absolutas por todo o lado, a solução duradoura é a sua própria configuração de URL externo, não uma lista crescente de regras de reescrita no proxy. Acrescentar regras até a saída parecer correta produz uma configuração que falha na primeira página que ninguém testou. Uma única definição correta da aplicação substitui toda a coleção.
O que uma reescrita de cabeçalho não consegue reparar
Vários problemas vizinhos parecem problemas de redirecionamento e não são. O cabeçalho Host enviado ao upstream pode ter de corresponder ao host virtual do backend. Um upstream TLS pode exigir um nome de servidor específico mais verificação do certificado, e reescrever um cabeçalho de resposta não ajuda em nenhum dos casos.
O âmbito dos cookies e os atributos de domínio pertencem à aplicação e à sua configuração. Um proxy pode descartar ou reescrever cabeçalhos o dia inteiro e ainda produzir uma sessão que falha no segundo pedido, porque o cookie foi emitido para um host que o navegador nunca visitou. Essa falha parece intermitente, e é por isso que sobrevive tanto tempo numa fila de pedidos. Ler o domínio do cookie costuma encerrar a investigação num minuto.
Mantenha também a autenticação e a seleção do backend limitadas à aplicação prevista. Um proxy reverso público deve expor uma única aplicação através da VPN do servidor em vez de tornar-se uma porta de entrada genérica para cada endereço privado que esse host consiga alcançar. Um único location genérico que reencaminha tudo o que o chamador pede transforma um serviço exposto num mapa da sua rede privada. Nomeie o upstream explicitamente e mantenha-o lá.
Teste pela ordem em que o pedido viaja
Confirme três coisas em sequência: o NGINX escolheu o location previsto, concluiu um pedido ao backend, e o navegador seguiu qualquer redirecionamento posterior e carregou os sub-recursos. Cada passo tem as suas linhas de log, e lê-las por ordem transforma um 502 vago numa constatação concreta.
A distinção de que precisa é entre uma ligação upstream falhada e um navegador enviado para um nome privado inalcançável. A primeira aparece no log de erros do proxy; a segunda aparece como um pedido que nunca chega, com o navegador a queixar-se de um host que não consegue resolver. Dois problemas diferentes, dois ficheiros diferentes, e só um deles envolve o proxy_redirect.