Introducere în autorizația Kubernetes a Hashicorp Consul

Introducere în autorizația Kubernetes a Hashicorp Consul

Așa este, după eliberare Hashicorp Consul 1.5.0 la începutul lunii mai 2019, în Consul poți autoriza aplicațiile și serviciile care rulează în Kubernetes nativ.

În acest tutorial vom crea pas cu pas POC (Proof of concept, PoC) care demonstrează această nouă caracteristică Se așteaptă să aveți cunoștințe de bază despre Kubernetes și Hashicorp's Consul Deși puteți utiliza orice platformă cloud sau mediu local, în acest tutorial vom folosi Platforma Google.

Revizuire

Dacă mergem la Consultați documentația privind modalitatea de autorizare a acesteia, vom obține o prezentare generală rapidă a scopului și a cazului de utilizare, precum și câteva detalii tehnice și o prezentare generală a logicii. Recomand cu căldură să-l citiți cel puțin o dată înainte de a continua, deoarece acum voi explica și le voi mesteca pe toate.

Introducere în autorizația Kubernetes a Hashicorp Consul

Diagrama 1: Prezentare generală oficială a metodei de autorizare Consul

Să ne uităm înăuntru documentație pentru o anumită metodă de autorizare Kubernetes.

Sigur, există informații utile acolo, dar nu există un ghid despre cum să le folosiți pe toate. Așa că, ca orice persoană sănătoasă la minte, cercetezi Internetul după îndrumări. Și apoi... Eșuezi. S-a întâmplat. Să reparăm asta.

Înainte de a trece la crearea POC-ului nostru, să ne întoarcem la prezentarea generală a metodelor de autorizare ale Consulului (Diagrama 1) și să o rafinăm în contextul Kubernetes.

Arhitectură

În acest tutorial, vom crea un server Consul pe o mașină separată care va comunica cu un cluster Kubernetes cu clientul Consul instalat. Apoi vom crea aplicația noastră inactivă în pod și vom folosi metoda noastră de autorizare configurată pentru a citi din magazinul nostru de chei/valoare Consul.

Diagrama de mai jos detaliază arhitectura pe care o creăm în acest tutorial, precum și logica din spatele metodei de autorizare, care va fi explicată mai târziu.

Introducere în autorizația Kubernetes a Hashicorp Consul

Diagrama 2: Prezentare generală a metodei de autorizare Kubernetes

O notă rapidă: serverul Consul nu trebuie să locuiască în afara clusterului Kubernetes pentru ca acest lucru să funcționeze. Dar da, el poate face așa și cutare.

Deci, luând diagrama de prezentare generală a Consulului (Diagrama 1) și aplicându-i Kubernetes, obținem diagrama de mai sus (Diagrama 2), iar logica aici este următoarea:

  1. Fiecare pod va avea atașat un cont de serviciu care conține un token JWT generat și cunoscut de Kubernetes. Acest token este de asemenea inserat în pod în mod implicit.
  2. Aplicația sau serviciul nostru din interiorul podului inițiază o comandă de conectare către clientul nostru Consul. Solicitarea de conectare va include, de asemenea, simbolul și numele nostru special creat metoda de autorizare (tip Kubernetes). Acest pas #2 corespunde pasului 1 al diagramei Consul (Schema 1).
  3. Clientul nostru Consul va transmite apoi această solicitare către serverul nostru Consul.
  4. MAGIE! Aici serverul Consul verifică autenticitatea cererii, colectează informații despre identitatea cererii și o compară cu orice reguli predefinite asociate. Mai jos este o altă diagramă pentru a ilustra acest lucru. Acest pas corespunde pașilor 3, 4 și 5 din diagrama generală Consul (Diagrama 1).
  5. Serverul nostru Consul generează un token Consul cu permisiuni conform regulilor noastre de metodă de autorizare specificate (pe care le-am definit) cu privire la identitatea solicitantului. Apoi va trimite acel token înapoi. Aceasta corespunde pasului 6 al diagramei Consul (Diagrama 1).
  6. Clientul nostru Consul transmite jetonul către aplicația sau serviciul solicitant.

Aplicația sau serviciul nostru poate folosi acum acest token Consul pentru a comunica cu datele noastre Consul, așa cum este determinat de privilegiile jetonului.

Magia este dezvăluită!

Pentru cei dintre voi care nu sunt mulțumiți doar de un iepure din pălărie și doresc să știe cum funcționează... permiteți-mi să vă arăt cât de adânc gaura de iepure".

După cum am menționat mai devreme, pasul nostru „magic” (Figura 2: Pasul 4) este locul în care serverul Consul autentifică cererea, colectează informații despre cerere și o compară cu orice reguli predefinite asociate. Acest pas corespunde pașilor 3, 4 și 5 din diagrama generală Consul (Diagrama 1). Mai jos este o diagramă (Diagrama 3), al cărei scop este să arate clar ce se întâmplă de fapt sub capotă metodă specifică de autorizare Kubernetes.

Introducere în autorizația Kubernetes a Hashicorp Consul

Diagrama 3: Magia este dezvăluită!

  1. Ca punct de plecare, clientul nostru Consul transmite cererea de conectare către serverul nostru Consul cu simbolul de cont Kubernetes și numele de instanță specific al metodei de autorizare care a fost creată mai devreme. Acest pas corespunde pasului 3 din explicația precedentă a circuitului.
  2. Acum serverul Consul (sau liderul) trebuie să verifice autenticitatea jetonului primit. Prin urmare, va consulta clusterul Kubernetes (prin clientul Consul) și, cu permisiunile corespunzătoare, vom afla dacă token-ul este autentic și cui îi aparține.
  3. Solicitarea validată este apoi returnată liderului Consul, iar serverul Consul caută instanța metodei de autorizare cu numele specificat din cererea de conectare (și tipul Kubernetes).
  4. Liderul consul identifică instanța specificată a metodei de autorizare (dacă este găsită) și citește setul de reguli obligatorii care îi sunt atașate. Apoi citește aceste reguli și le compară cu atributele de identitate verificate.
  5. TA-dah! Să trecem la pasul 5 din explicația precedentă a circuitului.

Rulați Consul-server pe o mașină virtuală obișnuită

De acum înainte, voi oferi în mare parte instrucțiuni despre cum să creez acest POC, adesea în puncte, fără explicații complete pentru propoziții. De asemenea, așa cum am menționat mai devreme, voi folosi GCP pentru a crea toată infrastructura, dar puteți crea aceeași infrastructură oriunde altundeva.

  • Porniți mașina virtuală (instanță/server).

Introducere în autorizația Kubernetes a Hashicorp Consul

  • Creați o regulă pentru firewall (grup de securitate în AWS):
  • Îmi place să atribui același nume de mașină atât regulii, cât și etichetei de rețea, în acest caz „skywiz-consul-server-poc”.
  • Găsiți adresa IP a computerului dvs. local și adăugați-o la lista de adrese IP sursă, astfel încât să putem accesa interfața cu utilizatorul (UI).
  • Deschideți portul 8500 pentru UI. Faceți clic pe Creare. Vom schimba acest firewall din nou în curând [legătură].
  • Adăugați o regulă de firewall la instanță. Reveniți la tabloul de bord VM de pe Consul Server și adăugați „skywiz-consul-server-poc” în câmpul de etichete de rețea. Faceți clic pe Salvare.

Introducere în autorizația Kubernetes a Hashicorp Consul

  • Instalați Consul pe o mașină virtuală, verificați aici. Amintiți-vă că aveți nevoie de versiunea Consul ≥ 1.5 [link]
  • Să creăm un singur nod Consul - configurația este următoarea.

groupadd --system consul
useradd -s /sbin/nologin --system -g consul consul
mkdir -p /var/lib/consul
chown -R consul:consul /var/lib/consul
chmod -R 775 /var/lib/consul
mkdir /etc/consul.d
chown -R consul:consul /etc/consul.d

  • Pentru un ghid mai detaliat despre instalarea Consul și configurarea unui grup de 3 noduri, consultați aici.
  • Creați un fișier /etc/consul.d/agent.json după cum urmează [legătură]:

### /etc/consul.d/agent.json
{
 "acl" : {
 "enabled": true,
 "default_policy": "deny",
 "enable_token_persistence": true
 }
}

  • Porniți serverul nostru Consul:

consul agent 
-server 
-ui 
-client 0.0.0.0 
-data-dir=/var/lib/consul 
-bootstrap-expect=1 
-config-dir=/etc/consul.d

  • Ar trebui să vedeți o mulțime de rezultate și să ajungeți cu „... actualizare blocată de ACL-uri”.
  • Găsiți adresa IP externă a serverului Consul și deschideți un browser cu această adresă IP pe portul 8500. Asigurați-vă că se deschide interfața de utilizare.
  • Încercați să adăugați o pereche cheie/valoare. Trebuie să fie o greșeală. Acest lucru se datorează faptului că am încărcat serverul Consul cu un ACL și am dezactivat toate regulile.
  • Reveniți la shell-ul dvs. pe serverul Consul și începeți procesul în fundal sau într-un alt mod de a-l pune în funcțiune și introduceți următoarele:

consul acl bootstrap

  • Găsiți valoarea „SecretID” și reveniți la interfața de utilizare. În fila ACL, introduceți ID-ul secret al jetonului pe care tocmai l-ați copiat. Copiați SecretID în altă parte, vom avea nevoie de el mai târziu.
  • Acum adăugați o pereche cheie/valoare. Pentru acest POC, adăugați următoarele: cheie: „custom-ns/test_key”, valoare: „Sunt în folderul custom-ns!”

Lansarea unui cluster Kubernetes pentru aplicația noastră cu clientul Consul ca Daemonset

  • Creați un cluster K8s (Kubernetes). Îl vom crea în aceeași zonă cu serverul pentru un acces mai rapid și astfel putem folosi aceeași subrețea pentru a ne conecta cu ușurință la adresele IP interne. O vom numi „skywiz-app-with-consul-client-poc”.

Introducere în autorizația Kubernetes a Hashicorp Consul

  • Ca o notă secundară, iată un tutorial bun pe care l-am întâlnit în timpul instalării unui cluster POC Consul cu Consul Connect.
  • De asemenea, vom folosi graficul de conducere Hashicorp cu un fișier de valori extins.
  • Instalați și configurați Helm. Etape de configurare:

kubectl create serviceaccount tiller --namespace kube-system
kubectl create clusterrolebinding tiller-admin-binding 
   --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
./helm init --service-account=tiller
./helm update

### poc-helm-consul-values.yaml
global:
 enabled: false
 image: "consul:latest"
# Expose the Consul UI through this LoadBalancer
ui:
 enabled: false
# Allow Consul to inject the Connect proxy into Kubernetes containers
connectInject:
 enabled: false
# Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect.
client:
 enabled: true
 join: ["<PRIVATE_IP_CONSUL_SERVER>"]
 extraConfig: |
{
  "acl" : {
 "enabled": true,   
 "default_policy": "deny",   
 "enable_token_persistence": true 
  }
}
# Minimal Consul configuration. Not suitable for production.
server:
 enabled: false
# Sync Kubernetes and Consul services
syncCatalog:
 enabled: false

  • Aplicați diagrama de cârmă:

./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc

  • Când încearcă să ruleze, va avea nevoie de permisiuni pentru serverul Consul, așa că să le adăugăm.
  • Observați „Intervalul de adrese Pod” situat pe tabloul de bord al clusterului și consultați regula noastră de firewall „skywiz-consul-server-poc”.
  • Adăugați intervalul de adrese pentru pod la lista de adrese IP și deschideți porturile 8301 și 8300.

Introducere în autorizația Kubernetes a Hashicorp Consul

  • Accesați interfața Consul UI și după câteva minute veți vedea clusterul nostru care apare în fila noduri.

Introducere în autorizația Kubernetes a Hashicorp Consul

Configurarea unei metode de autorizare prin integrarea Consul cu Kubernetes

  • Reveniți la shell-ul serverului Consul și exportați simbolul pe care l-ați salvat mai devreme:

export CONSUL_HTTP_TOKEN=<SecretID>

  • Vom avea nevoie de informații din clusterul nostru Kubernetes pentru a crea o instanță a metodei de autentificare:
  • kubernetes-gazdă

kubectl get endpoints | grep kubernetes

  • kubernetes-service-account-jwt

kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "- name:"
kubectl get secret <secret_name_from_prev_command> -o yaml | grep token:

  • Token-ul este codificat base64, așa că decriptați-l folosind instrumentul dvs. preferat [legătură]
  • kubernetes-ca-cert

kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt:

  • Luați certificatul „ca.crt” (după decodare base64) și scrieți-l în fișierul „ca.crt”.
  • Acum instanțiați metoda de autentificare, înlocuind substituenții cu valorile pe care tocmai le-ați primit.

consul acl auth-method create 
-type "kubernetes" 
-name "auth-method-skywiz-consul-poc" 
-description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc" 
-kubernetes-host "<k8s_endpoint_retrieved earlier>" 
[email protected] 
-kubernetes-service-account-
jwt="<decoded_token_retrieved_earlier>"

  • În continuare trebuie să creăm o regulă și să o atașăm noului rol. Pentru această parte puteți folosi Consul UI, dar vom folosi linia de comandă.
  • Scrieți o regulă

### kv-custom-ns-policy.hcl
key_prefix "custom-ns/" {
 policy = "write"
}

  • Aplicați regula

consul acl policy create 
-name kv-custom-ns-policy 
-description "This is an example policy for kv at custom-ns/" 
-rules @kv-custom-ns-policy.hcl

  • Găsiți ID-ul regulii pe care tocmai ați creat-o din rezultat.
  • Creați un rol cu ​​o nouă regulă.

consul acl role create 
-name "custom-ns-role" 
-description "This is an example role for custom-ns namespace" 
-policy-id <policy_id>

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-ns-role' 
-selector='serviceaccount.namespace=="custom-ns"'

În sfârșit configurații

Drepturi de acces

  • Creați drepturi de acces. Trebuie să acordăm Consulului permisiunea de a verifica și identifica identitatea jetonului contului de serviciu K8s.
  • Scrieți următoarele în fișier [legătură]:

###skywiz-poc-consul-server_rbac.yaml
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: review-tokens
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: system:auth-delegator
 apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: service-account-getter
 namespace: default
rules:
- apiGroups: [""]
 resources: ["serviceaccounts"]
 verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: get-service-accounts
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: service-account-getter
 apiGroup: rbac.authorization.k8s.io

  • Să creăm drepturi de acces

kubectl create -f skywiz-poc-consul-server_rbac.yaml

Conectarea la Consul Client

  • După cum s-a menționat aiciExistă mai multe opțiuni pentru conectarea la daemonset, dar vom trece la următoarea soluție simplă:
  • Aplicați următorul fișier [legătură].

### poc-consul-client-ds-svc.yaml
apiVersion: v1
kind: Service
metadata:
 name: consul-ds-client
spec:
 selector:
   app: consul
   chart: consul-helm
   component: client
   hasDNS: "true"
   release: skywiz-app-with-consul-client-poc
 ports:
 - protocol: TCP
   port: 80
   targetPort: 8500

  • Apoi utilizați următoarea comandă încorporată pentru a crea o configurație [legătură]. Vă rugăm să rețineți că ne referim la numele serviciului nostru, înlocuiți-l dacă este necesar.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
 labels:
   addonmanager.kubernetes.io/mode: EnsureExists
 name: kube-dns
 namespace: kube-system
data:
 stubDomains: |
   {"consul": ["$(kubectl get svc consul-ds-client -o jsonpath='{.spec.clusterIP}')"]}
EOF

Testarea metodei de autentificare

Acum să vedem magia în acțiune!

  • Creați mai multe dosare cu chei cu aceeași cheie de nivel superior (de ex. /sample_key) și o valoare la alegere. Creați politici și roluri adecvate pentru noi căi cheie. Vom face legăturile mai târziu.

Introducere în autorizația Kubernetes a Hashicorp Consul

Test de spațiu de nume personalizat:

  • Să ne creăm propriul spațiu de nume:

kubectl create namespace custom-ns

  • Să creăm un pod în noul nostru spațiu de nume. Scrieți configurația pentru pod.

###poc-ubuntu-custom-ns.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-ns
 namespace: custom-ns
spec:
 containers:
 - name: poc-ubuntu-custom-ns
   image: ubuntu
   command: ["/bin/bash", "-ec", "sleep infinity"]
 restartPolicy: Never

  • Creați sub:

kubectl create -f poc-ubuntu-custom-ns.yaml

  • Odată ce containerul rulează, mergeți acolo și instalați curl.

kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash
apt-get update && apt-get install curl -y

  • Acum vom trimite o cerere de conectare către Consul folosind metoda de autorizare pe care am creat-o mai devreme [legătură].
  • Pentru a vedea simbolul introdus din contul dvs. de serviciu:

cat /run/secrets/kubernetes.io/serviceaccount/token

  • Scrieți următoarele într-un fișier din interiorul containerului:

### payload.json
{
 "AuthMethod": "auth-method-test",
 "BearerToken": "<jwt_token>"
}

  • Log in!

curl 
--request POST 
--data @payload.json 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Pentru a parcurge pașii de mai sus într-o singură linie (deoarece vom efectua mai multe teste), puteți face următoarele:

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Lucrări! Cel puțin ar trebui. Acum luați SecretID și încercați să accesați cheia/valoarea la care ar trebui să avem acces.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: <SecretID_from_prev_response>”

  • Puteți decoda „Value” în baza64 și puteți vedea că se potrivește cu valoarea din custom-ns/test_key din interfața de utilizare. Dacă ați folosit aceeași valoare de mai sus în acest tutorial, valoarea dvs. codificată ar fi IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.

Testul contului de serviciu utilizator:

  • Creați un ServiceAccount personalizat folosind următoarea comandă [legătură].

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
 name: custom-sa
EOF

  • Creați un nou fișier de configurare pentru pod. Vă rugăm să rețineți că am inclus instalarea curlului pentru a economisi forța de muncă :)

###poc-ubuntu-custom-sa.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-sa
 namespace: default
spec:
 serviceAccountName: custom-sa
 containers:
 - name: poc-ubuntu-custom-sa
   image: ubuntu
   command: ["/bin/bash","-ec"]
   args: ["apt-get update && apt-get install curl -y; sleep infinity"]
 restartPolicy: Never

  • După aceea, rulați o coajă în interiorul containerului.

kubectl exec -it poc-ubuntu-custom-sa /bin/bash

  • Log in!

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Acces refuzat. Oh, am uitat să adăugăm o nouă reguli obligatorii cu permisiunile corespunzătoare, să facem asta acum.

Repetați pașii anteriori de mai sus:
a) Creați o politică identică pentru prefixul „custom-sa/”.
b) Creați un rol, numiți-l „personalizat-sa-rol”
c) Atașați Politica la Rol.

  • Creați o legare a regulilor (posibil numai din cli/api). Observați semnificația diferită a steagului selector.

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-sa-role' 
-selector='serviceaccount.name=="custom-sa"'

  • Conectați-vă din nou din containerul „poc-ubuntu-custom-sa”. Succes!
  • Verificați accesul nostru la calea personalizat-sa/key.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: <SecretID>”

  • De asemenea, vă puteți asigura că acest token nu acordă acces la kv în „custom-ns/”. Doar repetați comanda de mai sus după ce ați înlocuit „custom-sa” cu prefixul „custom-ns”.
    Acces refuzat.

Exemplu de suprapunere:

  • Este demn de remarcat faptul că toate mapările obligatorii de reguli vor fi adăugate la simbolul cu aceste drepturi.
  • Containerul nostru „poc-ubuntu-custom-sa” se află în spațiul de nume implicit - așa că să-l folosim pentru o altă legătură de reguli.
  • Repetați pașii anteriori:
    a) Creați o politică identică pentru prefixul cheii „implicit/”.
    b) Creați un rol, numiți-l „default-ns-role”
    c) Atașați Politica la Rol.
  • Creați o legare a regulilor (posibil numai din cli/api)

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='default-ns-role' 
-selector='serviceaccount.namespace=="default"'

  • Reveniți la containerul nostru „poc-ubuntu-custom-sa” și încercați să accesați calea kv „implicit/”.
  • Acces refuzat.
    Puteți vizualiza acreditările specificate pentru fiecare token din UI sub ACL > Tokens. După cum puteți vedea, simbolul nostru actual are un singur „rol personalizat” atașat. Jetonul pe care îl folosim în prezent a fost generat când ne-am autentificat și a existat o singură legare a regulilor care se potrivea atunci. Trebuie să ne autentificăm din nou și să folosim noul token.
  • Asigurați-vă că puteți citi atât căile kv „custom-sa/” cât și „default/”.
    Succes!
    Acest lucru se datorează faptului că „poc-ubuntu-custom-sa” nostru se potrivește cu legăturile regulilor „custom-sa” și „default-ns”.

Concluzie

Gestiunea simbolului TTL?

La momentul scrierii acestui articol, nu există o modalitate integrată de a determina TTL-ul pentru token-urile generate de această metodă de autorizare. Ar fi o oportunitate fantastică de a asigura automatizarea securizată a autorizației Consulului.

Există o opțiune de a crea manual un token cu TTL:

Sperăm că în viitorul apropiat vom putea controla modul în care sunt generate jetoanele (pe regulă sau metodă de autorizare) și să adăugăm TTL.

Până atunci, se sugerează să utilizați un punct final de deconectare în logica dvs.

Citiți și alte articole de pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu