L'ABC di Sicurezza in Kubernetes: Autentificazione, Autorizazione, Auditing

L'ABC di Sicurezza in Kubernetes: Autentificazione, Autorizazione, Auditing

Prima o dopu, in u funziunamentu di ogni sistema, u prublema di sicurità si sviluppa: assicurà autentificazione, separazione di diritti, auditing è altre attività. Digià creatu per Kubernetes tanti suluzioni, chì permettenu di ottene u rispettu di i normi ancu in ambienti assai esigenti... U stessu materiale hè dedicatu à l'aspetti basi di a sicurità implementati in i miccanismi integrati di u K8s. Prima di tuttu, serà utile à quelli chì cumincianu à cunnosce Kubernetes - cum'è un puntu di partenza per studià i prublemi di sicurità.

Autenticazione

Ci sò dui tipi di utilizatori in Kubernetes:

  • Cunti di serviziu - cunti gestiti da l'API Kubernetes;
  • Users - utilizatori "normali" gestiti da servizii esterni, indipendenti.

A principal diferenza trà questi tipi hè chì per i Service Accounts ci sò oggetti speciali in l'API Kubernetes (sò chjamati cusì - ServiceAccounts), chì sò ligati à un spaziu di nomi è un settore di dati d'autorizazione guardati in u cluster in l'uggetti di u tipu Secrets. Tali utilizatori (Conti di serviziu) sò principalmente destinati à gestisce i diritti d'accessu à l'API Kubernetes di i prucessi in esecuzione in u cluster Kubernetes.

L'Usuari Ordinarii ùn anu micca entrate in l'API Kubernetes: devenu esse gestite da meccanismi esterni. Sò destinati à e persone o prucessi chì campanu fora di u cluster.

Ogni dumanda API hè assuciata à un contu di serviziu, un utilizatore, o hè cunsideratu anonimu.

I dati di autentificazione di l'utilizatori includenu:

  • utilizatore - nome d'utilizatore (sensibile à u casu!);
  • UID - una stringa d'identificazione d'utilizatore leggibile da a macchina chì hè "più coherente è unicu chè u nome d'utilizatore";
  • gruppi - lista di gruppi à quale appartene l'utilizatore;
  • Extra - campi supplementari chì ponu esse utilizati da u mecanismu d'autorizazione.

Kubernetes pò utilizà un gran numaru di miccanismi di autentificazione: certificati X509, tokens Bearer, proxy autentificante, HTTP Basic Auth. Utilizendu sti miccanismi, pudete implementà un gran numaru di schemi d'autorizazione: da un schedariu staticu cù password à OpenID OAuth2.

Inoltre, hè pussibule aduprà parechji schemi d'autorizazione simultaneamente. Per automaticamente, u cluster usa:

  • Service Account tokens - per Service Accounts;
  • X509 - per l'utilizatori.

A quistione nantu à a gestione di ServiceAccounts hè fora di u scopu di stu articulu, ma per quelli chì volenu familiarizà cù questu prublema in più detail, vi cunsigliu di principià cù pagine di documentazione ufficiale. Fighjemu un ochju più vicinu à u prublema di cumu funziona i certificati X509.

Certificati per l'utilizatori (X.509)

U modu classicu di travaglià cù certificati implica:

  • generazione di chjave:
    mkdir -p ~/mynewuser/.certs/
    openssl genrsa -out ~/.certs/mynewuser.key 2048
  • generà una dumanda di certificatu:
    openssl req -new -key ~/.certs/mynewuser.key -out ~/.certs/mynewuser.csr -subj "/CN=mynewuser/O=company"
  • processà una dumanda di certificatu utilizendu e chjave di u CA di u cluster Kubernetes, ottene un certificatu d'utilizatore (per ottene un certificatu, duvete aduprà un contu chì hà accessu à a chjave CA di u cluster Kubernetes, chì per difettu si trova in /etc/kubernetes/pki/ca.key):
    openssl x509 -req -in ~/.certs/mynewuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out ~/.certs/mynewuser.crt -days 500
  • crià un schedariu di cunfigurazione:
    • descrizzione di cluster (specifica l'indirizzu è u locu di u schedariu di certificatu CA per una stallazione di cluster specificu):
      kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.100.200:6443
    • o cumu ùnopzione cunsigliata - ùn avete micca bisognu di specificà u certificatu radice (tandu kubectl ùn verificarà micca a correttezza di l'api-server di u cluster):
      kubectl config set-cluster kubernetes  --insecure-skip-tls-verify=true --server=https://192.168.100.200:6443
    • aghjunghje un utilizatore à u schedariu di cunfigurazione:
      kubectl config set-credentials mynewuser --client-certificate=.certs/mynewuser.crt  --client-key=.certs/mynewuser.key
    • aghjunghje cuntestu:
      kubectl config set-context mynewuser-context --cluster=kubernetes --namespace=target-namespace --user=mynewuser
    • assignazione di u cuntestu predeterminatu:
      kubectl config use-context mynewuser-context

Dopu à e manipulazioni sopra, in u schedariu .kube/config una cunfigurazione cum'è questu serà creata:

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /etc/kubernetes/pki/ca.crt
    server: https://192.168.100.200:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    namespace: target-namespace
    user: mynewuser
  name: mynewuser-context
current-context: mynewuser-context
kind: Config
preferences: {}
users:
- name: mynewuser
  user:
    client-certificate: /home/mynewuser/.certs/mynewuser.crt
    client-key: /home/mynewuser/.certs/mynewuser.key

Per fà più faciule di trasferisce a cunfigurazione trà i cunti è i servitori, hè utile per edità i valori di e seguenti chjave:

  • certificate-authority
  • client-certificate
  • client-key

Per fà questu, pudete codificà i schedarii specificati in elli usendu base64 è registrà in a cunfigurazione, aghjunghjendu u suffissu à u nome di e chjave. -data, i.e. avè ricevutu certificate-authority-data è simili.

Certificati cù kubeadm

Cù a liberazione Kubernetes 1.15 U travagliu cù i certificati hè diventatu assai più faciule grazia à a versione alfa di u so supportu in utilità kubeadm. Per esempiu, questu hè ciò chì generà un schedariu di cunfigurazione cù e chjavi di l'utilizatori puderia avà vede cusì:

kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200

NB: Ubligatoriu annunzià indirizzu pò esse truvatu in a cunfigurazione api-server, chì per difettu si trova in /etc/kubernetes/manifests/kube-apiserver.yaml.

A cunfigurazione risultante serà uscita in stdout. Hè bisognu à esse salvatu in ~/.kube/config contu d'utilizatore o à un schedariu specificatu in una variabile d'ambiente KUBECONFIG.

Scava più profonda

Per quelli chì volenu capisce i prublemi descritti più bè:

Accedi

U contu autorizatu predeterminatu ùn hà micca diritti per operà nantu à u cluster. Per cuncede permessi, Kubernetes implementa un mecanismu d'autorizazione.

Prima di a versione 1.6, Kubernetes hà utilizatu un tipu d'autorizazione chjamatu ABAC (Controllu d'accessu basatu in attributi). I dettagli nantu à questu ponu esse truvati in documentazione ufficiale. Stu approcciu hè attualmente cunsideratu legatu, ma pudete ancu aduprà cù altri tipi di autentificazione.

A manera attuale (è più flexible) di dividisce i diritti d'accessu à un cluster hè chjamatu RBAC (Role di accessu basatu nantu à u rolu). Hè statu dichjaratu stabile da a versione Kubernetes 1.8. RBAC implementa un mudellu di diritti in quale tuttu ciò chì ùn hè micca esplicitamente permessu hè pruibitu.
Per attivà RBAC, avete bisognu di inizià Kubernetes api-server cù u paràmetru --authorization-mode=RBAC. I paràmetri sò stabiliti in u manifestu cù a cunfigurazione api-server, chì per difettu si trova longu u percorsu /etc/kubernetes/manifests/kube-apiserver.yaml, in sezzione command. Tuttavia, RBAC hè digià attivatu per difettu, cusì probabilmente ùn deve micca preoccupatu: pudete verificà questu per u valore. authorization-mode (in u già citatu kube-apiserver.yaml). Per via, trà i so significati pò esse altri tipi d'autorizazione (node, webhook, always allow), ma lasciaremu a so cunsiderazione fora di u scopu di u materiale.

Per via, avemu digià publicatu articulu cù una descrizzione abbastanza dettagliata di i principii è e caratteristiche di u travagliu cù RBAC, cusì in più mi limiteraghju à una breve lista di i principii è esempii.

E seguenti entità API sò aduprate per cuntrullà l'accessu in Kubernetes via RBAC:

  • Role и ClusterRole - roli chì servenu per descriverà i diritti d'accessu:
  • Role permette di discrive i diritti in un spaziu di nomi;
  • ClusterRole - in u cluster, cumpresu à l'uggetti specifichi di u cluster cum'è nodi, urls non-risorse (vale à dì micca ligati à risorse Kubernetes - per esempiu, /version, /logs, /api*);
  • RoleBinding и ClusterRoleBinding - utilizatu per a rilegatura Role и ClusterRole à un utilizatore, gruppu d'utilizatori o ServiceAccount.

L'entità Role è RoleBinding sò limitati da u spaziu di nomi, i.e. deve esse in u stessu spaziu di nomi. In ogni casu, un RoleBinding pò riferisce à un ClusterRole, chì permette di creà un settore di permessi generici è cuntrullà l'accessu cù elli.

I roli descrizanu i diritti utilizendu insemi di regule chì cuntenenu:

  • Gruppi API - vede documentazione ufficiale da apiGroups e output kubectl api-resources;
  • risorse (Risorse: pod, namespace, deployment eccetera.);
  • Verbi (verbi: set, update etc.).
  • nomi di risorse (resourceNames) - per u casu quandu avete bisognu di furnisce l'accessu à una risorsa specifica, è micca à tutte e risorse di stu tipu.

Un analisi più detallatu di l'autorizazione in Kubernetes pò esse truvatu nantu à a pagina documentazione ufficiale. Invece (o megliu, in più di questu), daraghju esempi chì illustranu u so travagliu.

Esempii di entità RBAC

Semplice Role, chì permette di ottene una lista è u statutu di pods è monitorà in u namespace target-namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: target-namespace
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Esempiu: ClusterRole, chì vi permette di ottene una lista è u statutu di pods è monitorà in tuttu u cluster:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # секции "namespace" нет, так как ClusterRole задействует весь кластер
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

Esempiu: RoleBinding, chì permette à l'utilizatori mynewuser "leghje" pods in namespace my-namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: target-namespace
subjects:
- kind: User
  name: mynewuser # имя пользователя зависимо от регистра!
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role # здесь должно быть “Role” или “ClusterRole”
  name: pod-reader # имя Role, что находится в том же namespace,
                   # или имя ClusterRole, использование которой
                   # хотим разрешить пользователю
  apiGroup: rbac.authorization.k8s.io

Audit di l'avvenimentu

Schematically, l'architettura di Kubernetes pò esse rapprisintata cum'è seguente:

L'ABC di Sicurezza in Kubernetes: Autentificazione, Autorizazione, Auditing

U cumpunente chjave Kubernetes rispunsevuli di trattà e dumande hè api-server. Tutte e operazioni nantu à u cluster passanu per ellu. Pudete leghje più nantu à sti miccanismi interni in l'articulu "Cosa succede in Kubernetes quandu eseguite kubectl run?».

A verificazione di u sistema hè una funzione interessante in Kubernetes, chì hè disattivata per automaticamente. Permette di logu tutte e chjama à l'API Kubernetes. Comu pudete intuisce, tutte l'azzioni ligati à u monitoraghju è u cambiamentu di u statu di u cluster sò realizati attraversu questa API. Una bona descrizzione di e so capacità pò esse truvata (cum'è di solitu). documentazione ufficiale K8s. In seguitu, pruvaraghju à presentà u tema in una lingua più simplice.

Cusì, per attivà a verificazione, avemu bisognu di passà trè paràmetri richiesti à u cuntinuu in api-server, chì sò descritti in più detail sottu:

  • --audit-policy-file=/etc/kubernetes/policies/audit-policy.yaml
  • --audit-log-path=/var/log/kube-audit/audit.log
  • --audit-log-format=json

In più di questi trè paràmetri necessarii, ci sò parechje paràmetri supplementari ligati à l'auditu: da a rotazione di log à e descrizzioni di webhook. Esempiu di paràmetri di rotazione di log:

  • --audit-log-maxbackup=10
  • --audit-log-maxsize=100
  • --audit-log-maxage=7

Ma ùn avemu micca aspittà nantu à elli in più detail - pudete truvà tutti i dettagli in documentation kube-apserver.

Comu digià dettu, tutti i paràmetri sò stabiliti in u manifestu cù a cunfigurazione api-server (per difettu /etc/kubernetes/manifests/kube-apiserver.yaml), in a sezione command. Riturnemu à i 3 paràmetri necessarii è analizàli:

  1. audit-policy-file - percorsu à u schedariu YAML chì descrive a pulitica di auditu. Riturneremu à u so cuntenutu più tardi, ma per ora vi nutà chì u schedariu deve esse leghjite da u prucessu api-server. Per quessa, hè necessariu di muntallu in u cuntinuu, per quale pudete aghjunghje u codice seguente à e sezzioni appropritate di a cunfigurazione:
      volumeMounts:
        - mountPath: /etc/kubernetes/policies
          name: policies
          readOnly: true
      volumes:
      - hostPath:
          path: /etc/kubernetes/policies
          type: DirectoryOrCreate
        name: policies
  2. audit-log-path - percorso à u schedariu di log. U percorsu deve esse ancu accessibile à u prucessu api-server, cusì discrimu u so muntatu in u listessu modu:
      volumeMounts:
        - mountPath: /var/log/kube-audit
          name: logs
          readOnly: false
      volumes:
      - hostPath:
          path: /var/log/kube-audit
          type: DirectoryOrCreate
        name: logs
  3. audit-log-format - formatu di log di auditu. U difettu hè json, ma u formatu di testu legatu hè ancu dispunibule (legacy).

Politica di Audit

Avà nantu à u schedariu citatu chì descrive a pulitica di logging. U primu cuncettu di pulitica di auditu hè level, livellu di logging. Sò i seguenti:

  • None - ùn fate micca log;
  • Metadata - metadata di dumanda di log: utilizatore, tempu di dumanda, risorsa di destinazione (pod, namespace, etc.), tipu d'azzione (verbu), etc.;
  • Request - log metadata è corpu di dumanda;
  • RequestResponse - log metadata, corpu di dumanda è corpu di risposta.

L'ultimi dui livelli (Request и RequestResponse) ùn logu micca e dumande chì ùn anu micca accessu à e risorse (accessi à l'urls chjamati non-resources).

Ancu tutte e dumande passanu parechje tappe:

  • RequestReceived - a tappa quandu a dumanda hè ricivuta da u processatore è ùn hè ancu stata trasmessa più in a catena di processori;
  • ResponseStarted - i headers di risposta sò mandati, ma prima chì u corpu di risposta hè mandatu. Generatu per dumande longu (per esempiu, watch);
  • ResponseComplete - u corpu di risposta hè statu mandatu, ùn ci sarà più infurmazione;
  • Panic - l'avvenimenti sò generati quandu una situazione anormale hè rilevata.

Per saltà ogni passu chì pudete aduprà omitStages.

In un schedariu di pulitica, pudemu discrive parechje rùbbriche cù diversi livelli di logging. A prima regula currispondente truvata in a descrizzione di a pulitica serà applicata.

U daemon kubelet monitoreghja i cambiamenti in u manifestu cù a cunfigurazione api-server è, s'ellu hè rilevatu, riavvia u cuntinuu cù api-server. Ma ci hè un dettu impurtante: i cambiamenti in u schedariu di pulitica seranu ignorati da ellu. Dopu avè fattu cambiamenti à u schedariu di pulitica, avete bisognu di riavvia l'api-server manualmente. Siccomu api-server hè iniziatu cum'è pod staticu, squadra kubectl delete ùn farà micca riavvià. Vi tuccherà à fà lu manually docker stop nantu à kube-masters, induve a pulitica di audit hè stata cambiata:

docker stop $(docker ps | grep k8s_kube-apiserver | awk '{print $1}')

Quandu attivate a verificazione, hè impurtante ricurdà chì a carica nantu à kube-apiserver aumenta. In particulare, u cunsumu di memoria per almacenà u cuntestu di dumanda aumenta. Logging principia solu dopu chì l'intestazione di risposta hè mandata. A carica dipende ancu da a cunfigurazione di a pulitica di auditu.

Esempii di pulitiche

Fighjemu a struttura di i schedarii di pulitica cù esempi.

Eccu un schedariu simplice policyper logà tuttu à u livellu Metadata:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata

In a pulitica pudete specificà una lista di utilizatori (Users и ServiceAccounts) è gruppi di utilizatori. Per esempiu, questu hè cumu ignurà l'utilizatori di u sistema, ma logu tuttu u restu à u livellu Request:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: None
    userGroups:
      - "system:serviceaccounts"
      - "system:nodes"
    users:
      - "system:anonymous"
      - "system:apiserver"
      - "system:kube-controller-manager"
      - "system:kube-scheduler"
  - level: Request

Hè ancu pussibule di discrive i miri:

  • spazii di nomi (namespaces);
  • Verbi (verbi: get, update, delete è altri);
  • risorse (Risorse, à dì: pod, configmaps etc.) è gruppi di risorse (apiGroups).

Attenti! Risorse è gruppi di risorse (gruppi API, vale à dì apiGroups), è e so versioni installate in u cluster, ponu esse ottenute cù i cumandamenti:

kubectl api-resources
kubectl api-versions

A seguente pulitica di audit hè furnita cum'è una dimostrazione di e migliori pratiche in Documentazione Alibaba Cloud:

apiVersion: audit.k8s.io/v1beta1
kind: Policy
# Не логировать стадию RequestReceived
omitStages:
  - "RequestReceived"
rules:
  # Не логировать события, считающиеся малозначительными и не опасными:
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
      - group: "" # это api group с пустым именем, к которому относятся
                  # базовые ресурсы Kubernetes, называемые “core”
        resources: ["endpoints", "services"]
  - level: None
    users: ["system:unsecured"]
    namespaces: ["kube-system"]
    verbs: ["get"]
    resources:
      - group: "" # core
        resources: ["configmaps"]
  - level: None
    users: ["kubelet"]
    verbs: ["get"]
    resources:
      - group: "" # core
        resources: ["nodes"]
  - level: None
    userGroups: ["system:nodes"]
    verbs: ["get"]
    resources:
      - group: "" # core
        resources: ["nodes"]
  - level: None
    users:
      - system:kube-controller-manager
      - system:kube-scheduler
      - system:serviceaccount:kube-system:endpoint-controller
    verbs: ["get", "update"]
    namespaces: ["kube-system"]
    resources:
      - group: "" # core
        resources: ["endpoints"]
  - level: None
    users: ["system:apiserver"]
    verbs: ["get"]
    resources:
      - group: "" # core
        resources: ["namespaces"]
  # Не логировать обращения к read-only URLs:
  - level: None
    nonResourceURLs:
      - /healthz*
      - /version
      - /swagger*
  # Не логировать сообщения, относящиеся к типу ресурсов “события”:
  - level: None
    resources:
      - group: "" # core
        resources: ["events"]
  # Ресурсы типа Secret, ConfigMap и TokenReview могут содержать  секретные данные,
  # поэтому логируем только метаданные связанных с ними запросов
  - level: Metadata
    resources:
      - group: "" # core
        resources: ["secrets", "configmaps"]
      - group: authentication.k8s.io
        resources: ["tokenreviews"]
  # Действия типа get, list и watch могут быть ресурсоёмкими; не логируем их
  - level: Request
    verbs: ["get", "list", "watch"]
    resources:
      - group: "" # core
      - group: "admissionregistration.k8s.io"
      - group: "apps"
      - group: "authentication.k8s.io"
      - group: "authorization.k8s.io"
      - group: "autoscaling"
      - group: "batch"
      - group: "certificates.k8s.io"
      - group: "extensions"
      - group: "networking.k8s.io"
      - group: "policy"
      - group: "rbac.authorization.k8s.io"
      - group: "settings.k8s.io"
      - group: "storage.k8s.io"
  # Уровень логирования по умолчанию для стандартных ресурсов API
  - level: RequestResponse
    resources:
      - group: "" # core
      - group: "admissionregistration.k8s.io"
      - group: "apps"
      - group: "authentication.k8s.io"
      - group: "authorization.k8s.io"
      - group: "autoscaling"
      - group: "batch"
      - group: "certificates.k8s.io"
      - group: "extensions"
      - group: "networking.k8s.io"
      - group: "policy"
      - group: "rbac.authorization.k8s.io"
      - group: "settings.k8s.io"
      - group: "storage.k8s.io"
  # Уровень логирования по умолчанию для всех остальных запросов
  - level: Metadata

Un altru bon esempiu di pulitica di auditu hè prufilu utilizatu in GCE.

Per risponde rapidamente à l'avvenimenti di auditu, hè pussibule descrive u webhook. Stu prublema hè cupartu in documentazione ufficiale, Lascià fora di u scopu di stu articulu.

Risultati

L'articulu furnisce una panoramica di i meccanismi di sicurezza di basa in i clusters Kubernetes, chì permettenu di creà cunti d'utilizatori persunalizati, separà i so diritti è registrà e so azzioni. Spergu chì serà utile à quelli chì anu affruntatu tali prublemi in teoria o in pratica. Aghju ricumandemu ancu di leghje a lista di altri materiali nantu à u tema di sicurezza in Kubernetes, chì hè datu in "PS" - forsi trà elli truverete i dettagli necessarii nantu à i prublemi chì sò pertinenti per voi.

PS

Leghjite puru nant'à u nostru blog:

Source: www.habr.com

Add a comment