12

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
Asier Gomez
  • 6,034
  • 18
  • 52
  • 105

3 Answers3

38

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.

Bobby
  • 18,217
  • 15
  • 74
  • 89
d0bry
  • 2,232
  • 9
  • 16
  • Really thanks!, I was forgetting to add the encrypted password. – Asier Gomez May 03 '18 at 07:39
  • 3
    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. – Adam Sibik Oct 27 '19 at 22:43
  • 3
    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. – rudolfbyker Oct 26 '21 at 14:16
  • 2
    Facing the same problem @rudolfbyker – CertainlyNotAdrian Mar 30 '22 at 20:26
  • 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`) – Craig Otis Feb 11 '23 at 14:43
8

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:

bztes
  • 130
  • 1
  • 3
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

Chris
  • 5,109
  • 3
  • 19
  • 40