Kubernetes Dashboard with Azure AD OAuth and Let’s Encrypt on AKS

In this post I want to show you how to protect your Kubernetes Dashboard through an OAuth 2 authentication with Azure AD as identity provider and Let’s Encrypt certificates.

I’m using OAuth 2 Proxy together with the NGINX Ingress Controller to authenticate my Azure AD account against the Kubernetes Dashboard. For issuing the Let’s Encrypt certificates I’m using cert-manager with the NGINX HTTP ACME solver.

I’m using the domain k8s.nicoo.org for the Kubernetes Dashboard and auth.nicoo.org for the OAuth 2 Proxy. You should change those in your setup.

Prerequisites

  • AKS cluster (or any other type of Kubernetes cluster)
  • Azure CLI to retrieve the kubeconfig (az aks get-credentials)
  • kubectl
  • Helm 3

Registering an Application

Before you start, you need to register an application in Azure AD and create a client secret for it. You will need this for the OAuth 2 Proxy later.

Make sure you enter a Redirect URI. The callback URI for the OAuth 2 Proxy is https://yourdomain.com/oauth2/callback.

Register an application

Also create a client secret and note it down for later.

Create a client secret for the application

Installing cert-manager

To issue and renew Let’s Encrypt certificates install Jet Stack’s cert-manager. Just execute the below commands.

# Creates namespace
kubectl create namespace cert-manager

# Adds Jet Stack's repository to your Helm client
helm repo add jetstack https://charts.jetstack.io

# Updates repositories
helm repo update

# Installs cert-manager CRDs
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.1/cert-manager.crds.yaml

# Installs cert-manager
helm upgrade cert-manager jetstack/cert-manager \
    --install \
    --namespace cert-manager \
    --version v0.15.1

For cert-manager to issue Let’s Encrypt certificates you need to create a ClusterIssuer object for Let’s Encrypt. Just paste the below code to a file named cert-manager-clusterissuer.yaml.

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx

Apply the configuration to the Kubernetes cluster.

kubectl apply -f cert-manager-clusterissuer.yaml --namespace cert-manager

Installing OAuth 2 Proxy

To install OAuth 2 Proxy execute the below commands. Make sure you modify the domain names and set config.clientID to the application’s client ID and config.clientSecret to the application’s client secret.

If you want to restrict the access to the Kubernetes Dashboard to certain users add their email addresses to authenticatedEmailsFile.restricted_access.

# Creates namespace
kubectl create namespace oauth2-proxy

# Adds Helm's stable repository to your Helm client
helm repo add stable https://kubernetes-charts.storage.googleapis.com/

# Updates repositories
helm repo update

# Installs OAuth 2 Proxy
helm upgrade oauth2-proxy stable/oauth2-proxy \
    --install \
    --namespace oauth2-proxy \
    --set nodeSelector."beta\.kubernetes\.io/os"=linux \
    --set extraArgs.provider=azure \
    --set extraArgs.whitelist-domain=.nicoo.org \
    --set extraArgs.cookie-domain=.nicoo.org \
    --set authenticatedEmailsFile.enabled=true \
    --set authenticatedEmailsFile.restricted_access=your-email-address@example.com \
    --set config.clientID=1f371b4b-14c0-4966-8319-858d519e3a6c \
    --set config.clientSecret=I8U~HSIk1.m-3D-LjXXI7R_1TIl38C7oPK \
    --set ingress.enabled=true \
    --set ingress.annotations."kubernets\.io/ingress\.class"=nginx \
    --set ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"=\"true\" \
    --set ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod \
    --set ingress.hosts={auth.nicoo.org} \
    --set ingress.tls[0].hosts[0]=auth.nicoo.org \
    --set ingress.tls[0].secretName=auth-nicoo-org-tls \
    --version 3.1.0

Preparing the Kubernetes Dashboard

Since AKS comes with a pre-deployed Kubernetes Dashboard, we can start with the configuration right away.

In order for the Kubernetes Dashboard to access objects within the cluster, you need to assign the cluster-admin role (or any other role, in case you want to disable certain features on the Kubernetes Dashboard) to the Kubernetes Dashboard service account.

kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard

Now you need to expose the Kubernetes Dashboard to the internet through an Ingress object.

Paste the below code to a file named kubernetes-dashboard-ingress.yaml.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/auth-url: "https://auth.nicoo.org/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://auth.nicoo.org/oauth2/start?rd=https%3A%2F%2F$host$request_uri"
spec:
  tls:
  - hosts:
      - k8s.nicoo.org
    secretName: k8s-nicoo-org-tls
  rules:
  - host: k8s.nicoo.org
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 80

Apply the configuration to the Kubernetes cluster.

kubectl apply -f kubernetes-dashboard-ingress.yaml --namespace kube-system

Installing the Ingress Controller

In order for Kubernetes to interpret the Ingress object, you need to install an ingress controller, since AKS does not come with a pre-deployed one. I’m using the NGINX Ingress Controller.

# Creates namespace
kubectl create namespace ingress-controller

# Installs NGINX Ingress Controller
helm upgrade nginx stable/nginx-ingress \
    --install \
    --namespace ingress-controller \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
    --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \
    --version=1.39.1

Test your Setup

When you now try to access your Kubernetes Dashboard you should be redirected to the Microsoft login page where you need to login with your Azure AD account.

During the first login you need to grant permissions to the Kubernetes Dashboard application.

Grant permissions to the Kubernetes Dashboard application

Afterwards you will be redirected to the Kubernetes Dashboard.

Kubernetes Dashboard

Leave a Comment