ERR_TOO_MANY_REDIRECTS atrás de uma CDN: as duas definições que fazem loop juntas.
Uma CDN que vai buscar a origem em HTTP simples e uma origem que força HTTP para HTTPS estão cada uma bem sozinhas e entram em loop juntas. Como reconhecer o par, reproduzi-lo num único pedido e fechar as duas pontas.
Neste artigo 4 secções
- O par a procurar quando um website atrás de uma CDN devolve ERR_TOO_MANY_REDIRECTS: um SSL mode da CDN que vai buscar a origem em HTTP simples, e uma origem que força o redirecionamento de HTTP para HTTPS sem verificar o que o proxy já fez.
- Duas falhas, cada uma inofensiva sozinha. Muitas origens servem HTTP atrás de uma CDN que termina o TLS, e muitas origens forçam HTTPS. Só as duas juntas fazem loop.
- O loop pode não deixar nenhuma entrada no access log, porque a camada que responde ao redirecionamento pode não registar pedidos de rotina. O silêncio parece ausência de tráfego e aponta a procura na direção errada.
- Reproduza-o com um pedido à origem, pelo caminho que os visitantes seguem, e depois corrija as duas pontas, para que o loop não se possa formar seja como for que o website esteja exposto.
Ativar o proxy da CDN à frente de uma origem que força HTTPS basta para iniciar o loop. Ambas as definições são razoáveis, e nenhuma por si só estraga nada. Mudar uma definição e testar a partir de um caminho que contorna a CDN parece uma correção, enquanto todos os visitantes reais continuam em loop.
O mecanismo: duas pontas, um loop
O SSL mode da CDN estava definido como "Flexible": o browser fala HTTPS com a CDN, mas a CDN fala HTTP simples com a origem. Uma definição defensável por si só. Muitas origens servem HTTP atrás de uma CDN que termina o TLS.
O edge da origem, entretanto, forçava o redirecionamento de todos os pedidos HTTP para HTTPS, sem consciência do proxy: emitia o redirecionamento sem verificar o header que diz que este pedido já era HTTPS à porta da frente. Assim, a CDN vai buscar em HTTP, a origem responde «vai para HTTPS», o pedido seguinte do browser chega à CDN como HTTPS, a CDN vai buscar a origem de novo em HTTP, e a origem redireciona outra vez. Infinito, por construção. Flexible sozinho está bem. O redirecionamento forçado sozinho está bem. Só os dois juntos fazem loop.
O bug que não registou nada
Se a camada que responde ao redirecionamento não regista pedidos de rotina, o loop não deixa nada no access log. O silêncio parece que não chegou tráfego nenhum, e a investigação vai a todo o lado menos ao sítio certo. A regra: quando um bug não deixa logs, pare de perseguir o silêncio e reproduza o mecanismo.
Reproduza o mecanismo
$ curl -I -H 'X-Forwarded-Proto: https' http://origin.example/
HTTP/1.1 301 Moved Permanently
Location: https://origin.example/
# told the origin the request was already HTTPS. it redirects anyway.Um pedido reproduz o loop, pelo caminho que os visitantes seguem. Um teste a partir de qualquer outro caminho passa e não prova nada.
Corrija as duas pontas
| A PONTA | A CORREÇÃO |
|---|---|
| O lado da CDN | O SSL mode passou para "Full (Strict)": a CDN fala HTTPS real e verificado com a origem. |
| QUALQUER UMA DAS CORREÇÕES QUEBRA O LOOP. AS DUAS TORNAM-NO IMPOSSÍVEL.O lado da origem | O redirecionamento passou a ter consciência do proxy: verifica o header do protocolo reencaminhado e nunca devolve um pedido que já era HTTPS à porta da frente. |
Corrigir uma ponta de uma incompatibilidade de duas pontas deixa uma configuração «armada» à espera da próxima alteração. Feche as duas pontas e não resta nenhuma combinação que circule: pausar a CDN, trocar de CDN, alterar a origem, e o loop não tem onde voltar a formar-se.
“Nenhuma das pontas estava avariada. As duas juntas estavam.”
Respostas diretas
Como corrijo o ERR_TOO_MANY_REDIRECTS atrás de uma CDN?+
Verifique o par, não uma única definição. Se a CDN vai buscar a sua origem em HTTP simples (um SSL mode do tipo "Flexible") e a sua origem força o redirecionamento de HTTP para HTTPS, fazem loop. Passe a CDN para HTTPS completo e estrito até à origem, e dê ao redirecionamento da origem consciência do proxy.
Porque é que o meu loop de redirecionamentos não mostra nada nos access logs?+
A camada que entra em loop pode não registar pedidos de rotina, por isso o loop é invisível. Não persiga o silêncio. Reproduza o mecanismo com um pedido à origem e leia o que ela faz.
O que faz o X-Forwarded-Proto?+
Um proxy define-o para dizer à origem que protocolo o visitante usou realmente. Uma origem que redireciona HTTP para HTTPS tem de o verificar, caso contrário devolve pedidos que já eram HTTPS no proxy, e é assim que os loops começam.
O Flexible SSL mode é mau?+
É uma troca com uma aresta afiada: o tráfego entre a CDN e a origem vai sem encriptação, e combinado com um redirecionamento forçado na origem faz loop. O modo completo e estrito, com um certificado real na origem, remove os dois problemas.
Porque é que funcionou quando eu testei?+
Um teste que não passa pela CDN segue um caminho diferente do dos seus visitantes. Reproduza pelo caminho exato que falha, headers incluídos. É nessa diferença que esta classe de bugs se esconde.
A lutar com um bug que não regista nada?
O silêncio também é um sintoma. Reproduzimos a falha, lemos as fontes primárias e corrigimos as duas pontas.
Fale com um engenheiroChegou ao fim.
Ponha a leitura em prática
O que executa?
Fale-nos da carga de trabalho, do tráfego e dos requisitos de recuperação. Comece pelo configurador de servidores ou discuta os detalhes com um engenheiro.
Escrito pelos engenheiros que constroem e operam a infraestrutura que descreve.Fale com um engenheiro
