When setting up my new K3s cluster I needed some sort of redirect from HTTP to HTTPS. One option that is often found when searching for this issue is to redirect all traffic with Traefik. This however is not suitable if you just want some services to redirect and not everything in the cluster. Especially if you are using ACME with HTTP challenges – a global redirect would render those challenges useless, as they cannot get responded to (because it redirects away from HTTP to a non-existent HTTPS). A solution to this issue is to redirect only specific services. For this a redirect from HTTP to HTTPS with a Traefik middleware present a viable remedy.
In this example I am using K3s in version v1.21.0+k3s1 which comes with Traefik in version 2.4.8.
The first step is to create a Traefik Middleware resource with a redirectScheme. This scheme will redirect HTTP traffic to HTTPS. The following yaml file can be easily applied to achieve this.
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: redirect-https spec: redirectScheme: scheme: https permanent: true
Now this newly created middleware resource can be used in an Ingress object to tell the ingress to redirect traffic in the aforementioned way. A very important detail which is omitted in the documentation however, is that the name of the resource in the annotation has to have a prefix for the namespace it’s created in. In the example above this is the default namespace. So you need to set this as a prefix and @kubernetescrd
always as a suffix to the name of your middleware.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: traefik.ingress.kubernetes.io/router.middlewares: default-redirect-https@kubernetescrd name: grafana namespace: grafana spec: rules: - host: grafana.example.com http: paths: - backend: service: name: grafana port: number: 3000 path: / pathType: ImplementationSpecific
After editing the annotation in this way, Traefik should now make use of it correctly. You successfully created a redirect from HTTP to HTTPS with a Traefik middleware.
Carlos
It works like a charm. It was very hard to find this post on google. Any of those articles helped me.
Thank you!
lookas
Nice solution. Thank you for your excellent post!
Quan
Hi,
My approach is much simpler and you only need to care once.
The original docs is here: https://rancher.com/docs/k3s/latest/en/helm/#customizing-packaged-components-with-helmchartconfig
1. Edit the file `/var/lib/rancher/k3s/server/manifests/traefik-config.yaml` on the master
2. add the ports.web.redirectTo: websecure
Here is my example:
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
ports:
web:
redirectTo: websecure
ssl:
enabled: true
permanentRedirect: true
enforced: true
useCertManager: true
dashboard:
enabled: true
Tobey
This would redirect everything in the cluster though, wouldn’t it? As mentioned in my post, my goal was to not have everything redirect but to have control over what gets redirected and what doesn’t. So yes, your approach is simpler, if you just want everything to redirect.
EK
@Tobey,
I’m new to k8s and using rancher. I’m facing exactly the same issue certificates are added in asecret and secret is mentioned in the Ingres file. however the only missing piece I’m missing is middleware. my question is when you say “redirect only specific urls to https” is it correctly to assume that every rule mentioned in this Ingress file would redirect http to https and for other routes define them in other Ingress resource files without referencing middleware?
Tobey
There are other possibilities to have traefik redirect everything to HTTPS. But I need to have some ingresses route over HTTP. So this approach here allows me to specify on each ingress if it should redirect to HTTPS. This is done using the middleware annotation (see ingress.yaml on line 5). If you delete this annotation on the ingress, then the request will not automatically redirect to HTTPS. So you can – by specifying this annotation on an ingress – decide if this ingress should redirect to HTTPS. The default behaviour is still to NOT redirect, but with this middleware you can tell this exact ingress featuring the annotation to redirect.
EK
I’m trying to use the same however i get 404 on https on all endpoints. for http,it returns 301 with a corresponding https value in location header but on trying that i get 404. any ideas?
Tobey
Hard to say without seeing the sources. If you want to, upload the related yaml files to pastebin, github or something else and send me the link, then I’ll take a look. If you already have a private github repository you could add me of course.
Medo
Awesome, thanks!
Shweta
I have one doubt in my project as per current implementations http url showing 403 . Can we redirect trafiek from http to https even if http diplays 403. Do i need to create 2 ingress?
Anonymous
its 404 not 403
Tobey
I’m not sure I understand your issue. If you redirect http -> https then Traefik does not care for the status code returned by http. Your http request is redirected to https immediately and not after the http request has been made. You may imagine this as an URL rewrite.
Tom
Thank you so much!
Mercede
i was having issue with path rewriting. had spent quite much time, even posted it on traefik slack group. all useless. then i visited this page accidently and read this
“A very important detail which is omitted in the documentation however, is that the name of the resource in the annotation has to have a prefix for the namespace it’s created in. In the example above this is the default namespace.”
and then tried and problem was fixed. thank you so much
Tobey
I’m glad this was of help to you! 🙂