How to create Users in Kubernetes the right way?
I this post I will show you how you can create Users in Kubernetes the right way.
Parts of the K8S Security Lab series
Container Runetime Security
- Part1: How to deploy CRI-O with Firecracker?
- Part2: How to deploy CRI-O with gVisor?
- Part3: How to deploy containerd with Firecracker?
- Part4: How to deploy containerd with gVisor?
- Part5: How to deploy containerd with kata containers?
Advanced Kernel Security
- Part1: Hardening Kubernetes with seccomp
- Part2: Linux user namespace management wit CRI-O in Kubernetes
- Part3: Hardening Kubernetes with seccomp
Network Security
- Part1: RKE2 Install With Calico
- Part2: RKE2 Install With Cilium
- Part3: CNI-Genie: network separation with multiple CNI
- Part3: Configurre network wit nmstate operator
- Part3: Kubernetes Network Policy
- Part4: Kubernetes with external Ingress Controller with vxlan
- Part4: Kubernetes with external Ingress Controller with bgp
- Part4: Central authentication with oauth2-proxy
- Part5: Secure your applications with Pomerium Ingress Controller
- Part6: CrowdSec Intrusion Detection System (IDS) for Kubernetes
- Part7: Kubernetes audit logs and Falco
Secure Kubernetes Install
- Part1: Best Practices to keeping Kubernetes Clusters Secure
- Part2: Kubernetes Secure Install
- Part3: Kubernetes Hardening Guide with CIS 1.6 Benchmark
- Part4: Kubernetes Certificate Rotation
User Security
- Part1: How to create kubeconfig?
- Part2: How to create Users in Kubernetes the right way?
- Part3: Kubernetes Single Sign-on with Pinniped OpenID Connect
- Part4: Kubectl authentication with Kuberos Depricated !!
- Part5: Kubernetes authentication with Keycloak and gangway Depricated !!
- Part6: kube-openid-connect 1.0 Depricated !!
Image Security
Pod Security
- Part1: Using Admission Controllers
- Part2: RKE2 Pod Security Policy
- Part3: Kubernetes Pod Security Admission
- Part4: Kubernetes: How to migrate Pod Security Policy to Pod Security Admission?
- Part5: Pod Security Standards using Kyverno
- Part6: Kubernetes Cluster Policy with Kyverno
Secret Security
- Part1: Kubernetes and Vault integration
- Part2: Kubernetes External Vault integration
- Part3: ArgoCD and kubeseal to encript secrets
- Part4: Flux2 and kubeseal to encrypt secrets
- Part5: Flux2 and Mozilla SOPS to encrypt secrets
Monitoring and Observability
- Part6: K8S Logging And Monitoring
- Part7: Install Grafana Loki with Helm3
Backup
Users in Kubernetes
All Kubernetes clusters have two categories of users: service accounts managed by Kubernetes, and normal users. Kubernetes does not have objects which represent normal user accounts. Normal users cannot be added to a cluster through an API call.
So how we choud create an user account?
Any user that presents a valid certificate signed by the cluster’s certificate authority (CA) is considered authenticated. So you need to create a certificate for you username.
Why I need a user account insted of service account?
A service account is wisible and its token can be mounted in to a pod so theat pod has the same privileges as you.
Generate new certificate
First, we have to generate a private key and a certificate signing request:
openssl genrsa -out devopstales.pem
openssl req -new -key devopstales.pem -out devopstales.csr -subj "/CN=devopstales"
devopstales
well be my username. You can add your user to specific groups by addin them as groups like devops-groupe
:
openssl req -new -key ivnilv.pem -out ivnilv.csr -subj "/CN=devopstales/O=devops-groupe"
Signing the certificate
Use the csr file for generating a CertificateSigningRequest
object n Kubernetes:
cat devopstales.csr | base64 | tr -d '\n'
cat <<'EOF'> devopstales-csr.yaml
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: user-request-devopstales
spec:
groups:
- system:authenticated
request: LS0tLS1CRUdJTi...
usages:
- digital signature
- key encipherment
- client auth
EOF
OR from Kubernetes v1.22 (in this example it will expire after 10 years):
cat devopstales.csr | base64 | tr -d '\n'
cat <<'EOF'> devopstales-csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: user-request-devopstales
spec:
groups:
- system:authenticated
request: LS0tLS1CRUdJTi...
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 315569260
usages:
- digital signature
- key encipherment
- client auth
EOF
Create the CertificateSigningRequest
and approve it. Then the Kubernetes api server will generate the certificate theat you can use to authentication.
kubectl create -f devopstales-csr.yaml
kubectl certificate approve user-request-devopstales
kubectl get csr
NAME AGE REQUESTOR CONDITION
user-request-devopstales 1m admin Approved,Issued
Now the certificate should be signed. You can download the new signed public key from the csr resource:
kubectl get csr user-request-devopstales -o jsonpath='{.status.certificate}' | base64 -d > devopstales-user.crt
Create new user config file
kubectl --kubeconfig ~/.kube/config-devopstales config set-cluster preprod --insecure-skip-tls-verify=true --server=https://KUBERNETES-API-ADDRESS
kubectl --kubeconfig ~/.kube/config-devopstales config set-credentials devopstales --client-certificate=devopstales-user.crt --client-key=devopstales.pem --embed-certs=true
kubectl --kubeconfig ~/.kube/config-devopstales config set-context default --cluster=preprod --user=devopstales
kubectl --kubeconfig ~/.kube/config-devopstales config use-context default
Ofcourse you need rbac for this user:
cat <<'EOF'> devopstales-rbac.yaml
apiVersion: v1
kind: Namespace
metadata:
name: devopstales-ns
spec: {}
status: {}
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: devopstales
namespace: devopstales-ns
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: devopstales
namespace: devopstales-ns
subjects:
- kind: User
name: devopstales
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: devopstales
EOF
kubectl apply -f devopstales-rbac.yaml
Let’s test if the new kubeconfig we generated worked fine:
kubectl --kubeconfig ~/.kube/config-devopstales get pods
Conclusion
As we can see creating certificate for all the users is a hard task for the administratos if we hawe many users. A better solution to use an sso based authentication proxy like my Kubectl OpenID Connect.