Basic auth
Without any authentication all ingresses are unprotected, unless they offer their own auth. One easy way to add some security to this is using basic auth. This wil also allow us to secure the private registry easily if we use one. All with the same credentials. See the docs for more details.
Credentials
cat basic-auth-secret.yaml | envsubst | kubectl apply -f -
basic-auth-secret.yaml
# Note: in a kubernetes secret the string (e.g. generated by htpasswd) must be base64-encoded first.
# To create an encoded user:password pair, the following command can be used:
# htpasswd -nb user password | openssl base64
# Or create a new file with the credentials you want and then convert it when your are done
# htpasswd -c auth username
# *enter and reenter password*
# htpasswd auth username2
# *enter and reenter password*
# base64 auth
# copy and paste into below
# the |2 should stay regardless of how many users. It is yaml syntax.
# Below are username/passwords test/test and test2/test2
# https://doc.traefik.io/traefik/middlewares/basicauth/
apiVersion: v1
kind: Secret
metadata:
name: my-basic-auth-secret
namespace: default
data:
users: |2
dGVzdDokYXByMSRINnVza2trVyRJZ1hMUDZld1RyU3VCa1RycUU4d2ovCnRlc3QyOiRhcHIxJGQ5
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
Middleware
cat basic-auth-middleware.yaml | envsubst | kubectl apply -f -
basic-auth-middleware.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: my-basic-auth
spec:
basicAuth:
secret: my-basic-auth-secret
Add Middleware
Depending on if you are using Ingressroute or Ingress you can add the middleware.
Traefik Ingressroute
cat traefik-ingressroute.yaml | envsubst | kubectl apply -f -
traefik-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: dashboard
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`traefik.${DOMAIN}`)
kind: Rule
services:
- name: api@internal
kind: TraefikService
middlewares:
- name: my-basic-auth
tls:
secretName: traefik-tls
Ingress
**Note: ** The middleware is prefixed with the namespace, in this case default.
cat traefik-dashboard-ingress-basic-auth.yaml | envsubst | kubectl apply -f -
traefik-dashboard-ingress-basic-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
namespace: kube-system
annotations:
spec.ingressClassName: traefik
traefik.ingress.kubernetes.io/router.middlewares: default-my-basic-auth@kubernetescrd
spec:
rules:
- host: traefik.${DOMAIN}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traefik-dashboard
port:
number: 9000
Test it
Access https://traefik.yourdomain.com and see that it now needs username and password. The combination is test/test.
Rotate credentials (Optional but smart)
These credentials may not be the best, so lets try to rotate them.
htpasswd -c mynewcreds user1
# enter and reenter password
htpasswd mynewcreds user2
#enter and reenter password
htpasswd mynewcreds user3
#enter and reenter password*
cat mynewcreds | base64 > mynewcreds64
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: my-basic-auth-secret
namespace: default
data:
users: |2
$(head -1 mynewcreds64 | tail -1)
$(head -2 mynewcreds64 | tail -1)
$(head -3 mynewcreds64 | tail -1)
EOF