Autentificarea prin certificate în Kubernetes este o parte extrem de importantă procesului de securizare a întregului cluster. Autentificarea definește CINE poate accesa un cluster, folosind diferite metode (fișiere cu username și parolă sau username și tokens, certificate, LDAP, ServiceAccounts).
În acest articol voi arăta cum se poate crea un certificat și o cheie de autentificare la un cluster Kubernetes pentru un user oarecare - să-l numim, cu totul întâmplător, bobses; request-ul de certificat pentru acest utilizator va fi semnat în 2 moduri: manual și automat.
Premise
Prescurtări folosite:
- CA = Certificate Authorithy
- CRT = Certificat
- CSR = Certificate Signing Request
- Key = Cheie privată
- CN = Common Name
În Kubernetes, conturile sunt de 2 tipuri:
- ServiceAccount (de exemplu, este folosit de poduri pentru a accesa resursele k8s) - sunt gestionate de API-ul kubernetes
- Normal User - nu este o resursă kubernetes; este cineva care deține un certificat și o cheie. Acest certificat al unui user normal trebuie să fie semnat de CA-ul clusterului k8s. În certificatul clientului, username-ul trebuie trecut sub Common Name (CN): /CN=bobses
Cum obținem un certificat semnat de kubernetes
În mare, procedura recomandată presupune să avem un CSR creat cu comanda openssl
. Includem acest CSR în resursa kubernetes numită CertificateSigningRequest, resursă care este trimisă ulterior la API-ul k8s, care folosește CA-ul clusterului pentru a semna și emite certificatul.
Această procedură o putem considera semnare automată și este mult mai sigură și mai ușoară decât, să spunem, descărcarea CA din clusterul k8s și semnarea individuală a fiecărui certificat (manuală).
Imaginile de mai jos ilustrează ceea ce se întâmplă în ambele situații:
Semnarea manuală
Semnarea automată
Invalidarea unui certificat în kubernetes
Nu există nicio modalitate de a invalida un certificat - dacă un certificat a fost semnat și emis, el poate fi folosit până la expirare.
În cazul în care bănuim că avem o scurgere de informații și vrem să ștergem toate drepturile pe care un certificat le dă unui utilizator, putem apela la RBAC - jonglăm cu drepturile userului respectiv din roluri și rolebindings.
O altă modalitate, greoaie și de evitat, este generarea unui alt CA pentru clusterul k8s și regenerarea tuturor celorlalte certificate.
Exerciții
- Crearea unei chei private pentru utilizatorul bobses
- Generarea CSR pentru userul bobses pe baza cheii private anterioare
- Semnarea manuală a CSR-ului folosind CA-ul din kubernetes pentru generarea CRT
- Semnarea automată a CSR: crearea unei resurse CSR în k8s , semnarea folosind API-ul k8s, apoi descărcarea certificatului
- Conectarea la API-ul kbernetes folosind cheia privată de la pasul 1 și certificatul obținut manual sau automat (pașii 3 și 4).
1. Crearea cheii private (KEY)
openssl genrsa -out bobses.key 2048
2. Crearea request-ului (CSR)
openssl req -new -key bobses.key -out bobses.csr
În acest moment, avem 2 fișiere: cheia privată bobses.key și CSR-ul bobses.csr
3. Semnarea manuală
Căutăm în cluster locul unde se află Certificate Authorithy (de obicei, îl găsim în /etc/kubernetes/pki/ca.crt):
find /etc/kubernetes/pki | grep ca.crt
Comanda de semnare (indicăm fișierul .csr, fișierul ca.crt, cheia privată ca.key a clusterului k8s, dar și fișierul unde va rezulta certificatul semnat):
openssl x509 -req -in bobses.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out bobses.crt -days 500
În cazul în care folosiți clusterul k3s construit în contul free tier de la Oracle Cloud, acesta se află la /var/lib/rancher/k3s/server/tls/server-ca.crt, iar comanda va fi:
openssl x509 -req -in bobses.csr -CA /var/lib/rancher/k3s/server/tls/server-ca.crt -CAkey /var/lib/rancher/k3s/server/tls/server-ca.key -CAcreateserial -out bobses.crt -days 500
Observăm că a apărut și certificatul bobses.crt:
Pentru a verifica validitatea noului certificat, se poate da comanda:
openssl x509 -in bobses.crt -text -noout
Conținutul certificatului poate fi văzut cu comanda cat bobses.crt
.
4. Semnare automată via API
a. Trebuie să creăm o resursă kubernetes de tip CertificateSigningRequest. Fișierul manifest va fi de forma:
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: bobses
spec:
groups:
- system:authenticated
request: {{CSR_CODAT_BASE_64}} ## aici se trece hashul base64 al csr-ului generat la pasul 2
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
La request se va trece hash-ul base64 al fisierului bobses.csr generat la pasul 2:
cat bobses.csr | base64 | tr -d "\n"
Instalăm fișierul .yaml de mai sus:
kubectl apply -f bobses-auto.yaml
Vizualizăm resursele de tip certificatesigningrequest din cluster - observăm statusul Pending al noii resurse instalate:
kubectl get certificatesigningrequest
b. Aprobăm CSR-ul aflat în starea Pending cu comanda:
kubectl certificate approve bobses
c. Obținerea și descărcarea certificatului:
kubectl get csr bobses -ojsonpath="{.status.certificate}" | base64 -d > bobses-auto.crt
Documentația oficială se află aici: https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/
5. Conectarea la clusterul k8s
Folosim comenzile de mai jos (atenție la numele clusterului!) - definim userul bobses, contextul bobses și setăm contextul folosit:
kubectl config set-credentials bobses --client-key=bobses.key --client-certificate=bobses.crt
kubectl config set-context bobses --cluster=default --user=bobses
kubectl config get-contexts
kubectl config use-context bobses
La final, remarcăm că userul bobses, deși se conectează prin intermediul unor certificate în kubernetes (este autentificat), nu are absolut niciun drept (nu poate nici măcar să listeze noduri, poduri sau namespace-uri):
Pentru a-i acorda userului bobses anumite permisiuni in cluster, vom folosi autorizarea RBAC și vom defini CE poate să facă userul bobses după autentificare - dar asta în articolul următor.
Concluzii
Automatizând aprobarea CSR prin intermediul API-ului kubernetes, eliminăm accesul direct la CA-ul din cluster. Accesul la CA din cluster trebuie să fie minim, căci prin intermediul lui se creează certificate trusted pentru întregul cluster k8s.
[…] Verificare folosind un user existent bobses creat ca în acest articol. […]