Friday, June 25, 2021

Kubernetes Dashboard SSO OIDC with keycloak-Part2

 Kubernetes does not have its own user management and relies on external providers like Keycloak. First we need to integrate an OpeniD prodiver (for me keycloak) with the kubernetes api server.

nano /etc/kubernetes/manifests/kube-apiserver.yaml
...
    command:
    - /hyperkube
    - apiserver
    - --advertise-address=10.10.40.30
...

    - --oidc-issuer-url=https://192.168.56.162:8443/auth/realms/mydomain
    - --oidc-client-id=k8s
    - --oidc-username-claim=email
    - --oidc-groups-claim=groups
    # for self sign cert or custom ca
    - --oidc-ca-file=/etc/kubernetes/pki/rootca.pem
...

systemctl restart docker kubelet

Make you have working ingress controller is also installed on your kubernetes cluster.you can install the same using helm or maually.

helm install stable/nginx-ingress \
    --name nginx-ingress \
    --namespace=nginx-ingress \
    --set rbac.create=true \
    --set controller.kind=DaemonSet \
    --set controller.hostNetwork=true \
    --set controller.daemonset.useHostPort=true \
    --set controller.stats.enabled=true \
    --set controller.metrics.enabled=true

kubectl --namespace nginx-ingress get services -o wide -w nginx-ingress-controller
kubectl create secret tls default-ingress-tls --key /path/to/private.pem --cert /path/to/cert.pem --namespace nginx-ingress

We need an authentication proxy before the dashboard. I will use keycloak-gatekeeper for that purpose.

nano proxy-deplayment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dasboard-proxy
  labels:
    app.kubernetes.io/name: dasboard-proxy
  namespace: kubernetes-dashboard
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: dasboard-proxy
  template:
    metadata:
      labels:
        app.kubernetes.io/name: dasboard-proxy
    spec:
      containers:
        - name: dasboard-proxy
          image: "keycloak/keycloak-gatekeeper:latest"
          command:
            - /opt/keycloak-gatekeeper
            - --discovery-url=https://192.168.56.162:8443/auth/realms/mydomain/.well-known/openid-configuration
- --client-id=k8s - --client-secret=43219919-0904-4338-bc0f-c986e1891a7a - --listen=0.0.0.0:3000 - --encryption-key=AgXa7xRcoClDEU0ZDSH4X0XhL5Qy2Z2j - --redirection-url=https://dashboard.nrathi.io - --enable-refresh-tokens=true - --upstream-url=https://kubernetes-dashboard # debug: #- --upstream-url=http://echo:8080 # for self sign cert or custom ca #- --skip-upstream-tls-verify #- --skip-openid-provider-tls-verify ports: - name: http containerPort: 3000 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: dasboard-proxy labels: app.kubernetes.io/name: dasboard-proxy namespace: kubernetes-dashboard spec: type: ClusterIP ports: - port: 3000 targetPort: http protocol: TCP name: http selector: app.kubernetes.io/name: dasboard-proxy --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: dasboard-proxy annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/proxy-buffer-size: "64k" cert-manager.io/cluster-issuer: ca-issuer namespace: kubernetes-dashboard spec: tls: - hosts: - dashboard.nrathi.io secretName: dasboard-proxy-tls rules: - host: dashboard.devopstales.intra http: paths: - backend: serviceName: dasboard-proxy servicePort: 3000

Now you can login at dashboard.devopstales.intra but you haven’t got any privileges so lets create. some.

nano devops-group-rbac.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: devops-cluster-admin
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: devopstales
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
subjects:
- kind: User
  name: "devopstales"
  namespace: "kube-system"
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name:  cluster-admin

Thursday, April 15, 2021

Kubernetes Dashboard SSO OIDC with keycloak-Part1

 Hello Guys,

For a long time i was working on this how to chive a SSO for k8s dashboard and I have failed many time while setup the sso for my K8S cluster and after searching a lot on internet and putting together a complete documentation how we can achieve it without any buying any domain and with a self sign ssl certs. I was trying to achieve it only with the open source software available and on base metal cluster.

here is my setup looks like for POC.

  


  1. Vm1 (Pfsense)        192.168.56.100
  2. vm2  (console)        192.168.56.109
  3. vm3   (keycloak)     192.168.56.162
  4. vm4   (master-sso)  192.168.56.164 
for the sake of the simplicity i am not going to include the integration between keycloak and Active directory or OpenLdap i will cover it in another post.

so lets start.

In pfsense which is my router so that i can create a local network on my Laptop it have two interfaces 

1 NAT  2 hostonly adapter and i have stop the DHCP server run by the virtualbox


on Console VM I have installed a  GUI based centos so that i can use browser in that  network.

 yum groupinstall "GNOME Desktop" "Graphical Administration Tools"

Make it boot by default in init 5 mode

 ln -sf /lib/systemd/system/runlevel5.target /etc/systemd/system/default.target

apart form this i have also make the ssh password less auth on keycloak and master-sso server for this 

ssh-keygen -t rsa

ssh-copy-id  root@keycloak

ssh-copy-id  root@master-sso

Setup Keycloak server with Selfsign cert with CA

  • Update & Upgrade your server
apt updateapt upgrade
  • Install JDK 8, keycloak need Java to run
apt-get install openjdk-8-jdk
  • Download keycloak, the program directory will run in /opt
wget https://downloads.jboss.org/keycloak/8.0.2/keycloak-8.0.2.tar.gztar -xzf keycloak-8.0.2.tar.gz -C /opt/mv /opt/keycloak-8.0.2 /opt/keycloak
  • Create user & group for keycloak
groupadd keycloakuseradd -r -g keycloak -d /opt/keycloak -s /sbin/nologin keycloak
  • How to run the keycloak? using systemd service file
mkdir -p /etc/keycloakcp /opt/keycloak/docs/contrib/scripts/systemd/wildfly.conf /etc/keycloak/keycloak.confcp /opt/keycloak/docs/contrib/scripts/systemd/launch.sh /opt/keycloak/bin/cp /opt/keycloak/docs/contrib/scripts/systemd/wildfly.service /etc/systemd/system/keycloak.service
  • Edit launch.sh and specify home environment variable
vi /opt/keycloak/bin/launch.shWILDFLY_HOME='/opt/keycloak/'
  • Edit keycloak service
vi /etc/systemd/system/keycloak.service[Unit]Description=The Keycloak ServerAfter=syslog.target network.targetBefore=httpd.service[Service]Environment=LAUNCH_JBOSS_IN_BACKGROUND=1EnvironmentFile=/etc/keycloak/keycloak.confUser=keycloakGroup=keycloakLimitNOFILE=102642PIDFile=/var/run/keycloak/keycloak.pidExecStart=/opt/keycloak/bin/launch.sh $WILDFLY_MODE $WILDFLY_CONFIG $WILDFLY_BINDStandardOutput=null[Install]WantedBy=multi-user.target
  • Set permission in keycloak directory to user that we create before
chown keycloak:keycloak -R /opt/keycloakchmod o+x /opt/keycloak/bin
  • Start keycloak service
systemctl daemon-reloadsystemctl enable keycloaksystemctl start keycloaksystemctl status keycloak
  • Create admin user
/opt/keycloak/bin/add-user-keycloak.sh -r master -u <username> -p <password>systemctl restart keycloak
  • Open keycloak web
http://IP_SERVER:8080/auth



Secure the Keycloak using SSL

Kubernetes currently not support provider with http, should be https. This tutorial will create self signed CA for keycloak.

  • Create folder for certificate
mkdir -p /opt/kc-certificate
  • Edit openssl configuration
vi /etc/ssl/openssl.cnf# RANDFILE = $ENV::HOME/.rnd
  • Generate CA, I am using wildcard domain.
cd /opt/kc-certificateopenssl genrsa -out ca.key 2048openssl req -new -x509 -key ca.key -out ca.crt -subj "/C=US/ST=CA/O=Acme, Inc./CN=*.nrathi.io"keytool -import -file ca.crt -keystore ca.truststore -keypass PASSWORD -storepass PASSWORD
openssl genrsa -out keycloak.key 2048openssl req -new -key keycloak.key -out keycloak.csr -subj "/C=US/ST=CA/O=Acme, Inc./CN=*.nrathi.io"openssl x509 -req -days 3650 -in keycloak.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out keycloak.crtopenssl pkcs12 -export -in keycloak.crt -inkey keycloak.key -out keycloak.p12 -name myserverkeystore -CAfile ca.crtkeytool -importkeystore -deststorepass PASSWORD -destkeypass PASSWORD -destkeystore keycloak.keystore -srckeystore keycloak.p12 -srcstoretype PKCS12 -srcstorepass PASSWORD

if you ask for password, just add `PASSWORD`

  • Copy generated certificate into keyclock directory
cp ca.truststore /opt/keycloak/standalone/configuration/cp keycloak.keystore /opt/keycloak/standalone/configuration/
  • Change the permission again
chown keycloak:keycloak -R /opt/keycloak
  • Enter to jboss CLI
cd /opt/keycloak/./bin/jboss-cli.shconnect
  • Setup the SSL
/core-service=management/security-realm=ssl-realm:add()/core-service=management/security-realm=ssl-realm/server-identity=ssl:add(keystore-relative-to=jboss.server.config.dir,keystore-path=keycloak.keystore, keystore-password=PASSWORD)/core-service=management/security-realm=ssl-realm/authentication=truststore:add(keystore-relative-to=jboss.server.config.dir,keystore-path=ca.truststore, keystore-password=PASSWORD)/subsystem=undertow/server=default-server/https-listener=https:remove()/subsystem=undertow/server=default-server/https-listener=https:add(socket-binding=https, security-realm=ssl-realm,enable-http2=true, verify-client=REQUESTED)reloadexit
  • Restart Keycloak
systemctl restart keycloak
  • Open keycloak
https://IP_SERVER:8443/auth

you will see warning because self signed certificate, just accept that certificate.




Good, Integration with kubernetes will be in the Part 2.