Blog

Say goodbye to improvised HTTPS Redirection Workarounds

0 l6usq1enidmrjtru (1)

Native redirect support for Google Kubernetes Engine’s (GKE) Ingress has arrived.

When we at DoiT International help clients with all things cloud, certain topics tend to pop up more than others — one particular question even followed me from my previous job:

“What’s the proper way of redirecting HTTP traffic to HTTPS, using the (default) GCLB ingress controller of GKE?”

In the past, I’d suggest workarounds such as maintaining a dedicated backend for redirection or resort to 3rd-party ingress solutions that don’t come with advanced traffic management features of GCLBs.

But now things just got a lot easier with Google Cloud’s release of native redirect support in GKE Ingress load balancers.

Read on to explore:

  • Why this is such a big deal, and
  • How to simplify the way you maintain your infrastructure as code with it
0 l6usq1enidmrjtru (1)
Photo by Jamie Street on Unsplash

Why bother?

Unencrypted HTTP is on its way out. With free certificate services offered through cloud platforms such as AWS and GCP, as well as independent providers like Let’s Encrypt, ZeroSSL, BuyPass Go SSL, and many more, there is no excuse to not using TLS at least on your production front-end load balancers.

The more interesting question is what to do on port 80, if anything. You may choose to just leave the port closed, hoping the browser will try TLS on port 443 next. But this may incur unwanted delays, and any unintentional fully-qualified http-link to your site will produce an error page. Even with browsers starting to prefer TLS connections and browser extensions for further tuning, there’s a case for leaving port 80 available. And let’s not forget HTTP Strict Transport Security and Upgrade Insecure Requests declarations to enforce the usage of TLS connections.

To know about these directives, however, a browser still needs to know about them by downloading them at least once — unless you’re part of the exclusive club of hsts addresses hardcoded into browsers. With TLS no longer adding any computational overhead, there’s no reason to serve the same content both encrypted and unencrypted, but many good reasons against it.

Generally, what you want in most use-cases is an HTTP status 301 or 308 redirect from HTTP to HTTPS. So what is the idiomatic way of doing this in Kubernetes, without resorting to local hacks and more infrastructure to maintain?

HTTPS redirects in Kubernetes ingress

Redirecting from the HTTP port is a job for the ingress controller. An early beta version of the ingress spec mentioned the annotation ingress.kubernetes.io/ssl-redirect, but implementation support really only caught on through custom (controller-specific) annotations.

The popular nginx ingress controller even performs the redirect by default, when TLS is enabled. But on Google Cloud, the GKE default ingress controller ingress-gce uses GCLB load balancers, which — while otherwise being beyond awesome — did not support HTTP to HTTPS redirects for a long, long time. That has finally changed, with the introduction of redirect support in HTTP traffic management. Nevertheless, utilizing this from inside an ingress declaration still was not supported, leading to tons of hacks, workarounds and dismay.

Until now, that is. 🎉

Supported GKE Versions

The solution outlined below is only officially supported in Kubernetes 1.18.10-gke.600 and up, but works in currently-available 1.17.x-gke versions as well. So if you’re on the stable release channel, you can enable support by upgrading your clusters to the 1.17 series, or use any version from the regular or rapid channels.

SSL-redirect support in GKE ingress: FrontendConfig

So native HTTPS redirection support has finally arrived in GKE. The implementation uses FrontendConfig CRDs, (which also govern SSL policies, by the way).

You can choose between five different HTTP status codes for the actual redirect.

Here’s an example using a status 308 permanent redirect:

apiVersion: networking.gke.io/

v1beta1

kind:

FrontendConfig

metadata:
 name:

my-frontend-config

spec:
 redirectToHttps:
   enabled:

true

responseCodeName: 

PERMANENT_REDIRECT

Association of this FrontendConfig resource with your Ingress object happens through the annotation keynetworking.gke.io/v1beta1.FrontendConfig of the ingress declaration:

apiVersion: networking.k8s.io/

v1beta1


kind: 

Ingress


metadata:
  annotations:
    networking.gke.io/

v1beta1

.FrontendConfig: 

"my-frontend-config"


...

Notice that you will need to use a v1beta1 apiVersion namespace for this to work. At some later stage, support is likely to spread to the non-beta versions, so you may want to keep an eye on the declarations for future cluster upgrades.

I put up a more complete working example on Github. For all the gory details of how to configure this feature, head over to the official documentation of Google’s Ingress Features.

Conclusion

I’m thrilled that GCP has listened to the community and implemented this long-overdue functionality. Start 2021 fresh by throwing away your local hacks and enjoy a clean, declarative, and idiomatic approach for making unencrypted HTTP a thing of the past!

Further Information

Subscribe to updates, news and more.

Related blogs