Dienste im Kubernetes Cluster mit Keycloak und OAuth schützen
Inhaltsverzeichnis
Ziel des Artikels ist es, die notwendigen Schritte zum Absichern eines Dienstes im Kubernetes Clusters mittels OAuth zu dokumentieren.
Keycloak installieren
Als Identity Provider kommt Keycloak zum Einsatz.
helm repo add codecentric https://codecentric.github.io/helm-charts
curl https://raw.githubusercontent.com/codecentric/helm-charts/master/charts/keycloak/values.yaml -o values.yaml
patch <<EOF
--- values.yaml.sav 2020-04-23 07:29:12.280000000 +0200
+++ values.yaml 2020-04-23 07:34:18.212000000 +0200
@@ -240,12 +240,12 @@ keycloak:
## Ingress configuration.
## ref: https://kubernetes.io/docs/user-guide/ingress/
ingress:
- enabled: false
+ enabled: true
path: /
- annotations: {}
- # kubernetes.io/ingress.class: nginx
- # kubernetes.io/tls-acme: "true"
+ annotations:
+ kubernetes.io/ingress.class: nginx
+ kubernetes.io/tls-acme: "true"
# ingress.kubernetes.io/affinity: cookie
labels: {}
@@ -253,13 +253,13 @@ keycloak:
## List of hosts for the ingress
hosts:
- - keycloak.example.com
+ - xxx.mydomain.com
## TLS configuration
- tls: []
- # - hosts:
- # - keycloak.example.com
- # secretName: tls-keycloak
+ tls:
+ - hosts:
+ - xxx.mydomain.com
+ secretName: tls-keycloak
## OpenShift route configuration.
## ref: https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html
@@ -287,10 +287,10 @@ keycloak:
## Persistence configuration
persistence:
# If true, the Postgres chart is deployed
- deployPostgres: false
+ deployPostgres: true
# The database vendor. Can be either "postgres", "mysql", "mariadb", or "h2"
- dbVendor: h2
+ dbVendor: postgres
## The following values only apply if "deployPostgres" is set to "false"
dbName: keycloak
EOF
kubectl create namespace keycloak
helm upgrade -i -n keycloak keycloak codecentric/keycloak -f values.yaml
Keycloak konfigurieren
Basierend auf https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/ und https://oauth2-proxy.github.io/oauth2-proxy/auth-configuration#keycloak-auth-provider
- Neuen Realm anlegen, z.B.
local
- Neuen Client anlegen, z.B.
k8s-ingress
- Access Type auf
confidential
- Valid redirect URL auf
https://*
- Credentials -> Secret notieren
- Neuen Mapper anlegen per
Create
:- Name
groups
- Mapper Type
Group Membership
- Token Claim Name
groups
- Name
- Access Type auf
- Neue Gruppe anlegen, z.B. admin
- Neuen User anlegen
- Email eintragen
- Email bestätigen
- Gruppe beitreten
- bei Bedarf OTP aktivieren
- Credentials setzen
Dienst anpassen und schützen
Am Beispiel Kubernetes Dashboard:
cat <<EOF > enable-oauth.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/use-port-in-redirects: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
name: dashboard
namespace: kube-dashboard
spec:
tls:
- hosts:
- xxx.mydomain.com
secretName: xxx.mydomain.com-tls
rules:
- host: xxx.mydomain.com
http:
paths:
- backend:
serviceName: kubernetes-dashboard
servicePort: 8443
path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: oauth2-proxy
namespace: kube-dashboard
spec:
rules:
- host: xxx.mydomain.com
http:
paths:
- backend:
serviceName: oauth2-proxy
servicePort: 4180
path: /oauth2
tls:
- hosts:
- xxx.mydomain.com
secretName: xxx.mydomain.com-tls
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: oauth2-proxy
name: oauth2-proxy
namespace: kube-dashboard
spec:
replicas: 1
selector:
matchLabels:
k8s-app: oauth2-proxy
template:
metadata:
labels:
k8s-app: oauth2-proxy
spec:
containers:
- args:
- --provider=keycloak
- --client-id=k8s-ingress
- --client-secret=5e656d5b-xxxx-xxxx-8845-xxxxxxxxxxxx
- --login-url=https://keycloak.mydomain.com/auth/realms/local/protocol/openid-connect/auth
- --redeem-url=https://keycloak.mydomain.com/auth/realms/local/protocol/openid-connect/token
- --validate-url=https://keycloak.mydomain.com/auth/realms/local/protocol/openid-connect/userinfo
- --keycloak-group=/admin
- --email-domain=*
- --http-address=0.0.0.0:4180
# Register a new application
# https://github.com/settings/applications/new
env:
# docker run -ti --rm python:3-alpine python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));'
- name: OAUTH2_PROXY_COOKIE_SECRET
value: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
image: quay.io/pusher/oauth2_proxy:latest
imagePullPolicy: Always
name: oauth2-proxy
ports:
- containerPort: 4180
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: oauth2-proxy
name: oauth2-proxy
namespace: kube-dashboard
spec:
ports:
- name: http
port: 4180
protocol: TCP
targetPort: 4180
selector:
k8s-app: oauth2-proxy
EOF