Kubernetes basic authentication with Traefik
Asked Answered
T

3

13

I am trying to configure Basic Authentication on a Nginx example with Traefik as Ingress controller.

I just create the secret "mypasswd" on the Kubernetes secrets.

This is the Ingress I am using:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginxingress
  annotations:
    ingress.kubernetes.io/auth-type: basic
    ingress.kubernetes.io/auth-realm: traefik
    ingress.kubernetes.io/auth-secret: mypasswd
spec:
  rules:
  - host: nginx.mycompany.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginxservice
          servicePort: 80

I check in the Traefik dashboard and it appear, if I access to nginx.mycompany.com I can check the Nginx webpage, but without the basic authentication.

This is my nginx deployment:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Nginx service:

apiVersion: v1
kind: Service
metadata:
  labels:
    name: nginxservice
  name: nginxservice
spec:
  ports:
    # The port that this service should serve on.
    - port: 80
  # Label keys and values that must match in order to receive traffic for this service.
  selector:
    app: nginx
  type: ClusterIP
Tillage answered 2/5, 2018 at 9:2 Comment(0)
F
37

It is popular to use basic authentication. In reference to Kubernetes documentation, you should be able to protect access to Traefik using the following steps :

  1. Create authentication file using htpasswd tool. You'll be asked for a password for the user:

htpasswd -c ./auth

  1. Now use kubectl to create a secret in the monitoring namespace using the file created by htpasswd.

kubectl create secret generic mysecret --from-file auth --namespace=monitoring

  1. Enable basic authentication by attaching annotations to Ingress object:

ingress.kubernetes.io/auth-type: "basic"

ingress.kubernetes.io/auth-secret: "mysecret"

So, full example config of basic authentication can looks like:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: prometheus-dashboard
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: traefik
    ingress.kubernetes.io/auth-type: "basic"
    ingress.kubernetes.io/auth-secret: "mysecret"
spec:
  rules:
  - host: dashboard.prometheus.example.com
    http:
      paths:
      - backend:
          serviceName: prometheus
          servicePort: 9090
  1. You can apply the example as following:

kubectl create -f prometheus-ingress.yaml -n monitoring

This should work without any issues.

Forbearance answered 2/5, 2018 at 15:18 Comment(5)
Really thanks!, I was forgetting to add the encrypted password.Tillage
Also, remember that unless told otherwise, Traefik will forward Authorization request header to the backend apps. Some of them are sensitive to it, in which case you might get an error message (Grafana being an example). Use this annotation ingress.kubernetes.io/auth-remove-header: true not to pass authorization header to the backend.Turbosupercharger
These annotations do not seem to have any effect. I'm using K3s v1.21.5+k3s2 with Traefik 2. The ingress works, but never asks for a password.Turnstone
Facing the same problem @TurnstonePlacencia
Same issue - no amount of annotation swizzling, or credential configuration, seem to cause Traefik to present an authentication challenge. The service/ingress is unprotected. (Using k3s v1.25.6+k3s1)Ucayali
M
9

Basic Auth configuration for Kubernetes and Traefik 2 seems to have slightly changed. It took me some time to find the solution, that's why I want to share it. I use k3s btw.

Step 1 + 2 are identical to what @d0bry wrote, create the secret:

printf "my-username:`openssl passwd -apr1`\n" >> my-auth
kubectl create secret generic my-auth --from-file my-auth --namespace my-namespace

Step 3 is to create the ingress object and apply a middleware that will handle the authentication

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: my-auth-middleware
  namespace: my-namespace
spec:
  basicAuth:
    removeHeader: true
    secret: my-auth
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  namespace: my-namespace
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/router.middlewares: my-namespace-my-auth-middleware@kubernetescrd
spec:
  rules:
    - host: my.domain.net
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-service
                port:
                  number: 8080

And then of course apply the configuration

kubectl apply -f my-ingress.yaml

refs:

Malvasia answered 10/11, 2021 at 14:55 Comment(0)
K
3

With the latest traefik (verified with 2.7) it got even simpler. Just create a secret of type kubernetes.io/basic-auth and use that in your middleware. No need to create the username:password string first and create a secret from that.

apiVersion: v1
kind: Secret
metadata:
  name: my-auth
  namespace: my-namespace
type: kubernetes.io/basic-auth
data:
  username: <username in base64>
  password: <password in base64>
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: my-auth-middleware
  namespace: my-namespace
spec:
  basicAuth:
    removeHeader: true
    secret: my-auth

Note that the password is not hashed as it is with htpasswd, but only base64 encoded.

Ref docs

Kendre answered 19/10, 2022 at 12:17 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.