How to force SSL for Kubernetes Ingress on GKE

Solution 1:

https://github.com/kubernetes/ingress-gce#frontend-https

You can block HTTP through the annotation kubernetes.io/ingress.allow-http: "false" or redirect HTTP to HTTPS by specifying a custom backend. Unfortunately GCE doesn't handle redirection or rewriting at the L7 layer directly for you, yet. (see https://github.com/kubernetes/ingress-gce#ingress-cannot-redirect-http-to-https)

Update: GCP now handles redirection rules for load balancers, including HTTP to HTTPS. There doesn't appear to be a method to create these through Kubernetes YAML yet.

Solution 2:

This was already correctly answered by a comment on the accepted answer. But since the comment is buried I missed it several times.

As of GKE version 1.18.10-gke.600 you can add a k8s frontend config to redirect from http to https.

https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#https_redirect

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: ssl-redirect
spec:
  redirectToHttps:
    enabled: true

# add below to ingress
# metadata:
#   annotations:
#     networking.gke.io/v1beta1.FrontendConfig: ssl-redirect

Solution 3:

The annotation has changed:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
...

Here is the annotation change PR: https://github.com/kubernetes/contrib/pull/1462/files

Solution 4:

If you are not bound to the GCLB Ingress Controller you could have a look at the Nginx Ingress Controller. This controller is different to the builtin one in multiple ways. First and foremost you need to deploy and manage one by yourself. But if you are willing to do so, you get the benefit of not depending on the GCE LB (20$/month) and getting support for IPv6/websockets.

The documentation states:

By default the controller redirects (301) to HTTPS if TLS is enabled for that ingress . If you want to disable that behaviour globally, you can use ssl-redirect: "false" in the NGINX config map.

The recently released 0.9.0-beta.3 comes with an additional annotation for explicitly enforcing this redirect:

Force redirect to SSL using the annotation ingress.kubernetes.io/force-ssl-redirect

Solution 5:

Google has responded to our requests and is testing HTTP->HTTPS SSL redirection on their load balancers. Their latest answer said it should be in Alpha sometime before the end of January 2020.

Their comment:

Thank you for your patience on this issue. The feature is currently in testing and we expect to enter Alpha phase before the end of January. Our PM team will have an announcement with more details as we get closer to the Alpha launch.

My fingers are crossed that we'll have a straightforward solution to this very common feature in the near future.


UPDATE (April 2020):

HTTP(S) rewrites is now a Generally Available feature. It's still a bit rough around the edges and does not work out-of-the-box with the GCE Ingress Controller unfortunately. But time will tell and hopefully a native solution will appear.