Quando nós, da DoiT International, ajudamos clientes em tudo que envolve nuvem, alguns assuntos aparecem com mais frequência do que outros — e tem uma pergunta em especial que me acompanha desde o emprego anterior:
"Qual é a forma certa de redirecionar tráfego HTTP para HTTPS usando o ingress controller GCLB (padrão) do GKE?"
Antigamente, eu sugeria gambiarras como manter um backend dedicado só para o redirecionamento ou apelar para soluções de ingress de terceiros, que não trazem os recursos avançados de gerenciamento de tráfego dos GCLBs.
Mas agora a vida ficou muito mais fácil com o lançamento, pelo Google Cloud, do suporte nativo a redirecionamentos nos load balancers do GKE Ingress.
Continue lendo para descobrir:
- Por que isso é uma grande novidade; e
- Como simplificar a forma como você mantém sua infraestrutura como código com esse recurso
Foto de Jamie Street no Unsplash
Por que se preocupar com isso?
O HTTP sem criptografia está com os dias contados. Com serviços de certificados gratuitos oferecidos por plataformas de nuvem como AWS e GCP, além de provedores independentes como Let's Encrypt, ZeroSSL, BuyPass Go SSL e muitos outros, não dá mais para usar a desculpa de não rodar TLS pelo menos nos load balancers de front-end em produção.
A pergunta mais interessante é o que fazer na porta 80, se é que algo deve ser feito. Você pode simplesmente deixar a porta fechada, na esperança de que o navegador tente o TLS na porta 443 em seguida. Mas isso pode causar atrasos indesejados, e qualquer link http totalmente qualificado para o seu site, criado sem querer, vai cair em uma página de erro. Mesmo com os navegadores começando a preferir conexões TLS e com extensões de navegador para refinar o comportamento, ainda há motivos para manter a porta 80 disponível. E não dá para esquecer das declarações HTTP Strict Transport Security e Upgrade Insecure Requests, que forçam o uso de conexões TLS.
Para conhecer essas diretivas, no entanto, o navegador ainda precisa baixá-las pelo menos uma vez — a não ser que você faça parte do clube exclusivo de endereços hsts pré-configurados nos navegadores. Como o TLS já não acrescenta overhead computacional, não há motivo para servir o mesmo conteúdo criptografado e sem criptografia, e existem vários bons motivos para não fazer isso.
Em geral, na maioria dos casos, o que você quer é um redirecionamento HTTP com status 301 ou 308 de HTTP para HTTPS. Então qual é a forma idiomática de fazer isso no Kubernetes, sem recorrer a hacks locais e a mais infraestrutura para manter?
Redirecionamentos HTTPS no ingress do Kubernetes
Redirecionar a partir da porta HTTP é tarefa do ingress controller. Uma versão beta inicial da especificação do ingress mencionava a annotation ingress.kubernetes.io/ssl-redirect, mas, na prática, o suporte só pegou de verdade por meio de annotations customizadas (específicas de cada controller).
O popular ingress controller nginx até faz o redirecionamento por padrão quando o TLS está habilitado. Mas, no Google Cloud, o ingress controller padrão do GKE — o ingress-gce — usa load balancers GCLB, que, embora sejam excelentes em diversos outros aspectos, passaram muito, muito tempo sem suportar o redirecionamento de HTTP para HTTPS. Isso finalmente mudou, com a chegada do suporte a redirecionamentos no gerenciamento de tráfego HTTP. Mesmo assim, usar esse recurso a partir de uma declaração de ingress ainda não era suportado, o que gerava um monte de hacks, gambiarras e frustração.
Até agora. 🎉
Versões do GKE suportadas
A solução descrita abaixo só tem suporte oficial no Kubernetes 1.18.10-gke.600 e versões superiores, mas também funciona nas versões 1.17.x-gke disponíveis atualmente. Então, se você está no canal de release stable, pode habilitar o suporte atualizando seus clusters para a série 1.17, ou usar qualquer versão dos canais regular ou rapid.
Versões do GKE suportadas no momento desta publicação
Suporte a redirecionamento SSL no GKE ingress: FrontendConfig
O suporte nativo a redirecionamento HTTPS finalmente chegou ao GKE. A implementação usa FrontendConfig CRDs (que, aliás, também controlam políticas de SSL).
Você pode escolher entre cinco códigos de status HTTP diferentes para o redirecionamento.
Veja um exemplo usando um redirecionamento permanente com status 308:
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: my-frontend-config
spec:
redirectToHttps:
enabled: true
responseCodeName: PERMANENT_REDIRECT
A associação desse recurso FrontendConfig com seu objeto Ingress acontece pela chave de annotation networking.gke.io/v1beta1.FrontendConfig na declaração do ingress:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
networking.gke.io/v1beta1.FrontendConfig: "my-frontend-config"
...
Repare que você precisa usar o namespace de apiVersion v1beta1 para que isso funcione. Em algum momento, é provável que o suporte se estenda às versões não-beta, então vale ficar de olho nas declarações nas próximas atualizações de cluster.
Subi um exemplo mais completo e funcional no Github. Para todos os detalhes de como configurar esse recurso, confira a documentação oficial dos Recursos de Ingress do Google.
Mais informações
- Documentação do GCP sobre Recursos de Ingress: redirecionamento https
- O projeto de exemplo no Github da DoiT International
Fico muito feliz em ver que o GCP ouviu a comunidade e implementou essa funcionalidade que já estava mais do que atrasada. Comece 2021 com o pé direito: jogue fora seus hacks locais e aproveite uma abordagem limpa, declarativa e idiomática para mandar o HTTP sem criptografia para o passado!