Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

¡Adiós a los workarounds improvisados para redirección HTTPS!

By Bernhard WeisshuhnJan 27, 20214 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

Cuando en DoiT International asesoramos a clientes en todo lo relacionado con la nube, hay temas que aparecen una y otra vez. Una pregunta en particular me persigue incluso desde mi trabajo anterior:

"¿Cuál es la forma correcta de redirigir tráfico HTTP a HTTPS usando el ingress controller GCLB (el predeterminado) de GKE?"

Antes solía recomendar workarounds como mantener un backend dedicado para la redirección o recurrir a soluciones de ingress de terceros que no incluyen las funciones avanzadas de gestión de tráfico de los GCLB.

Pero ahora todo se volvió mucho más sencillo gracias al lanzamiento por parte de Google Cloud del soporte nativo de redirección en los load balancers de GKE Ingress.

Sigue leyendo para descubrir:

  • Por qué esto es tan relevante, y
  • Cómo simplificar el mantenimiento de tu infraestructura como código gracias a esta novedad

Foto de Jamie Street en Unsplash

¿Por qué importa?

El HTTP sin cifrar tiene los días contados. Con servicios gratuitos de certificados que ofrecen plataformas en la nube como AWS y GCP, además de proveedores independientes como Let's Encrypt, ZeroSSL, BuyPass Go SSL y muchos más, ya no hay excusa para no usar TLS, al menos en los load balancers de front-end en producción.

La pregunta más interesante es qué hacer con el puerto 80, si es que se hace algo. Puedes optar por dejarlo cerrado y confiar en que el navegador pruebe TLS en el puerto 443 a continuación. Pero esto puede provocar demoras innecesarias, y cualquier enlace http totalmente cualificado no intencional hacia tu sitio terminará en una página de error. Aunque los navegadores empiezan a preferir conexiones TLS y existen extensiones para afinar todavía más este comportamiento, sigue habiendo razones para mantener el puerto 80 abierto. Y no olvidemos las declaraciones HTTP Strict Transport Security y Upgrade Insecure Requests, que sirven para forzar el uso de conexiones TLS.

Sin embargo, para conocer estas directivas, el navegador todavía necesita descargarlas al menos una vez, salvo que pertenezcas al club exclusivo de las direcciones hsts integradas por defecto en los navegadores. Como TLS ya no implica sobrecarga computacional alguna, no tiene sentido servir el mismo contenido cifrado y sin cifrar a la vez, y sí hay muchas razones para no hacerlo.

En general, lo que se busca en la mayoría de los casos es una redirección con código HTTP 301 o 308 desde HTTP hacia HTTPS. Entonces, ¿cuál es la forma idiomática de lograrlo en Kubernetes, sin recurrir a parches locales y sumar más infraestructura por mantener?

Redirecciones HTTPS en el ingress de Kubernetes

Redirigir desde el puerto HTTP es tarea del ingress controller. Una versión beta temprana de la especificación de ingress mencionaba la anotación ingress.kubernetes.io/ssl-redirect, pero el soporte real terminó llegando a través de anotaciones personalizadas (específicas de cada controlador).

El popular ingress controller de nginx incluso aplica la redirección por defecto cuando TLS está habilitado. En cambio, en Google Cloud, el ingress controller predeterminado de GKE, ingress-gce, utiliza load balancers GCLB, los cuales —pese a ser excelentes en todo lo demás— no soportaron redirecciones de HTTP a HTTPS durante muchísimo tiempo. Eso por fin cambió con la incorporación del soporte de redirección en la gestión de tráfico HTTP. Aun así, aprovecharlo desde una declaración de ingress seguía sin estar soportado, lo que daba lugar a una infinidad de hacks, workarounds y frustración.

Hasta ahora. 🎉

Versiones de GKE soportadas

La solución que se describe a continuación solo está oficialmente soportada en Kubernetes 1.18.10-gke.600 en adelante, aunque también funciona en las versiones 1.17.x-gke disponibles actualmente. Así que, si estás en el canal de release stable, puedes habilitar el soporte actualizando tus clusters a la serie 1.17, o bien usar cualquier versión de los canales regular o rapid.

Versiones de GKE soportadas al momento de redactar este artículo

Soporte de SSL-redirect en GKE ingress: FrontendConfig

Por fin llegó a GKE el soporte nativo de redirección HTTPS. La implementación se basa en CRDs FrontendConfig (que, por cierto, también rigen las políticas de SSL).

Puedes elegir entre cinco códigos de estado HTTP distintos para la redirección.

Aquí tienes un ejemplo con una redirección permanente con código 308:

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
 name: my-frontend-config
spec:
 redirectToHttps:
   enabled: true
   responseCodeName: PERMANENT_REDIRECT

La asociación de este recurso FrontendConfig con tu objeto Ingress se realiza mediante la clave de anotación networking.gke.io/v1beta1.FrontendConfig en la declaración del ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: "my-frontend-config"
...

Ten en cuenta que necesitarás usar un namespace de apiVersion v1beta1 para que esto funcione. Es probable que más adelante el soporte llegue a las versiones no-beta, así que conviene estar atento a las declaraciones de cara a futuras actualizaciones del cluster.

Publiqué un ejemplo más completo y funcional en Github. Para conocer todos los detalles sobre cómo configurar esta función, consulta la documentación oficial de Ingress Features de Google.

Más información

Me entusiasma que GCP haya escuchado a la comunidad y implementado esta funcionalidad tan esperada. ¡Arranca 2021 con buen pie: deshazte de tus parches locales y aprovecha un enfoque limpio, declarativo e idiomático para que el HTTP sin cifrar pase a la historia!