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.

DirectiveWhen it actsWhat it can change
proxy_passBefore any bytes leave the proxyWhich upstream receives the request
proxy_redirectAfter the upstream respondsMatching 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.

Artigos relacionados