De ABC fan Feiligens yn Kubernetes: Autentikaasje, Autorisaasje, Auditing

De ABC fan Feiligens yn Kubernetes: Autentikaasje, Autorisaasje, Auditing

Ier of letter, yn 'e wurking fan elk systeem, ûntstiet it probleem fan feiligens: garandearjen fan autentikaasje, skieding fan rjochten, kontrôle en oare taken. Al makke foar Kubernetes in protte oplossings. Alderearst sil it nuttich wêze foar dyjingen dy't begjinne yn 'e kunde te kommen mei Kubernetes - as útgongspunt foar it studearjen fan feiligens-relatearre problemen.

Ferifikaasje

D'r binne twa soarten brûkers yn Kubernetes:

  • Service Accounts - akkounts beheard troch de Kubernetes API;
  • brûkers - "normale" brûkers beheard troch eksterne, ûnôfhinklike tsjinsten.

It wichtichste ferskil tusken dizze typen is dat foar Service Accounts d'r spesjale objekten binne yn 'e Kubernetes API (se wurde neamd dat - ServiceAccounts), dy't keppele binne oan in nammeromte en in set autorisaasjegegevens opslein yn it kluster yn objekten fan it type Geheimen. Sokke brûkers (tsjinstakkounts) binne primêr bedoeld om tagongsrjochten te behearjen foar de Kubernetes API fan prosessen dy't rinne yn it Kubernetes-kluster.

Gewoane brûkers hawwe gjin yngongen yn 'e Kubernetes API: se moatte wurde beheard troch eksterne meganismen. Se binne bedoeld foar minsken of prosessen dy't bûten it kluster libje.

Elk API-fersyk is assosjearre mei of in tsjinstaccount, in brûker, of wurdt as anonym beskôge.

Gegevens foar brûkersautentikaasje omfetsje:

  • brûkersnamme - brûkersnamme (hoofdlettergefoel!);
  • UID - in masine-lêsbere brûker identifikaasje tekenrige dy't is "konsekwinter en unyk as de brûkersnamme";
  • groepen - list fan groepen dêr't de brûker heart by;
  • Ekstra - ekstra fjilden dy't kinne wurde brûkt troch it autorisaasjemeganisme.

Kubernetes kinne in grut oantal autentikaasjemeganismen brûke: X509-sertifikaten, Bearer-tokens, autentisearjende proxy, HTTP Basic Auth. Mei dizze meganismen kinne jo in grut oantal autorisaasjeskema's ymplementearje: fan in statysk bestân mei wachtwurden oant OpenID OAuth2.

Boppedat is it mooglik om ferskate autorisaasjeskema's tagelyk te brûken. Standert brûkt it kluster:

  • tsjinst account tokens - foar Service Accounts;
  • X509 - foar brûkers.

De fraach oer it behearen fan ServiceAccounts leit bûten it berik fan dit artikel, mar foar dyjingen dy't harsels mei dit probleem yn mear detail witte wolle, advisearje ik te begjinnen mei offisjele dokumintaasje siden. Wy sille in tichterby besjen op it probleem fan hoe't X509-sertifikaten wurkje.

Sertifikaten foar brûkers (X.509)

De klassike manier fan wurkjen mei sertifikaten omfettet:

  • kaai ​​generaasje:
    mkdir -p ~/mynewuser/.certs/
    openssl genrsa -out ~/.certs/mynewuser.key 2048
  • it generearjen fan in sertifikaatfersyk:
    openssl req -new -key ~/.certs/mynewuser.key -out ~/.certs/mynewuser.csr -subj "/CN=mynewuser/O=company"
  • it ferwurkjen fan in sertifikaatfersyk mei de Kubernetes kluster CA-kaaien, it krijen fan in brûkerssertifikaat (om in sertifikaat te krijen, moatte jo in akkount brûke dy't tagong hat ta de Kubernetes cluster CA-kaai, dy't standert leit yn /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
  • in konfiguraasjetriem oanmeitsje:
    • klusterbeskriuwing (spesifisearje it adres en de lokaasje fan it CA-sertifikaatbestân foar in spesifike klusterynstallaasje):
      kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.100.200:6443
    • of hoe netoanrikkemandearre opsje - jo hoege it root-sertifikaat net op te jaan (dan sil kubectl de krektens fan 'e api-tsjinner fan it kluster net kontrolearje):
      kubectl config set-cluster kubernetes  --insecure-skip-tls-verify=true --server=https://192.168.100.200:6443
    • in brûker tafoegje oan it konfiguraasjetriem:
      kubectl config set-credentials mynewuser --client-certificate=.certs/mynewuser.crt  --client-key=.certs/mynewuser.key
    • kontekst tafoegje:
      kubectl config set-context mynewuser-context --cluster=kubernetes --namespace=target-namespace --user=mynewuser
    • standert kontekst opdracht:
      kubectl config use-context mynewuser-context

Nei de boppesteande manipulaasjes, yn 'e triem .kube/config in konfiguraasje lykas dit sil oanmakke wurde:

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

Om it makliker te meitsjen om de konfiguraasje oer te bringen tusken akkounts en servers, is it handich om de wearden fan 'e folgjende kaaien te bewurkjen:

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

Om dit te dwaan, kinne jo de yn har spesifisearre bestannen kodearje mei base64 en registrearje se yn 'e konfiguraasje, tafoegje it efterheaksel oan' e namme fan 'e kaaien -data, d.w.s. krigen hawwe certificate-authority-data en sa.

Sertifikaten mei kubeadm

Mei de frijlitting Kubernetes 1.15 wurkjen mei sertifikaten is folle makliker wurden tank oan de alfa ferzje fan syn stipe yn kubeadm nut. Dit is bygelyks wat it generearjen fan in konfiguraasjetriem mei brûkerskaaien no der útsjen kin:

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

NB: Ferplicht advertearje adres kin fûn wurde yn 'e api-tsjinner konfiguraasje, dy't standert leit yn /etc/kubernetes/manifests/kube-apiserver.yaml.

De resultearjende konfiguraasje sil wurde útfierd nei stdout. It moat wurde bewarre yn ~/.kube/config brûkersaccount of nei in bestân opjûn yn in omjouwingsfariabele KUBECONFIG.

Djipper grave

Foar dyjingen dy't de beskreaune problemen yngeand wolle begripe:

Oanmelde

It standert autorisearre akkount hat gjin rjochten om op it kluster te operearjen. Om tastimmingen te jaan, implementeart Kubernetes in autorisaasjemeganisme.

Foarôfgeand oan ferzje 1.6 brûkte Kubernetes in autorisaasjetype neamd ABAC (Attribute-basearre tagongskontrôle). Details deroer kinne fûn wurde yn offisjele dokumintaasje. Dizze oanpak wurdt op it stuit beskôge as legacy, mar jo kinne it noch brûke neist oare autentikaasjetypen.

De hjoeddeiske (en fleksibeler) manier om tagongsrjochten ta in kluster te dielen wurdt neamd RBAC (Rol-basearre tagong kontrôle). It is sûnt ferzje stabyl ferklearre Kubernetes 1.8. RBAC fiert in rjochtenmodel út wêryn alles wat net eksplisyt tastien is ferbean is.
Om ynskeakelje RBAC, Jo moatte Kubernetes api-tsjinner begjinne mei de parameter --authorization-mode=RBAC. De parameters wurde ynsteld yn it manifest mei de api-tsjinner konfiguraasje, dy't standert leit lâns it paad /etc/kubernetes/manifests/kube-apiserver.yaml, yn seksje command. RBAC is lykwols al standert ynskeakele, dus wierskynlik moatte jo der gjin soargen oer hawwe: jo kinne dit ferifiearje troch de wearde authorization-mode (yn 'e al neamde kube-apiserver.yaml). Trouwens, ûnder syn betsjuttingen kinne d'r oare soarten autorisaasje wêze (node, webhook, always allow), mar wy sille har konsideraasje bûten it berik fan it materiaal litte.

Troch de wei, wy hawwe al publisearre in artikel mei in frij detaillearre beskriuwing fan 'e begjinsels en funksjes fan it wurkjen mei RBAC, dus fierder sil ik my beheine ta in koarte list fan' e basis en foarbylden.

De folgjende API-entiteiten wurde brûkt om tagong te kontrolearjen yn Kubernetes fia RBAC:

  • Role и ClusterRole - rollen dy't tsjinje om tagongsrjochten te beskriuwen:
  • Role lit jo rjochten binnen in nammeromte beskriuwe;
  • ClusterRole - binnen it kluster, ynklusyf oan klusterspesifike objekten lykas knooppunten, net-boarnen urls (dat wol sizze net relatearre oan Kubernetes-boarnen - bygelyks, /version, /logs, /api*);
  • RoleBinding и ClusterRoleBinding - brûkt foar bining Role и ClusterRole oan in brûker, brûkersgroep of ServiceAccount.

De Role en RoleBinding entiteiten wurde beheind troch nammeromte, d.w.s. moat binnen deselde nammeromte wêze. In RoleBinding kin lykwols in ClusterRole ferwize, wêrmei jo in set generyske tagongsrjochten kinne oanmeitsje en tagong kontrolearje mei har.

Rollen beskriuwe rjochten mei help fan sets regels dy't befetsje:

  • API-groepen - sjoch offisjele dokumintaasje troch apiGroups en útfier kubectl api-resources;
  • boarnen (Boarnen: pod, namespace, deployment ensafuorthinne.);
  • tiidwurden (tiidwurden: set, update ensfh.).
  • boarne nammen (resourceNames) - foar it gefal as jo tagong moatte jaan ta in spesifike boarne, en net ta alle boarnen fan dit type.

In mear detaillearre analyze fan autorisaasje yn Kubernetes is te finen op 'e side offisjele dokumintaasje. Ynstee (of leaver, neist dit) sil ik foarbylden jaan dy't har wurk yllustrearje.

Foarbylden fan RBAC-entiteiten

Simple Role, wêrmei jo in list en status fan pods krije kinne en se yn 'e nammeromte kontrolearje 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"]

Foarbyld: ClusterRole, wêrmei jo in list en status fan pods kinne krije en se troch it heule kluster kontrolearje:

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

Foarbyld: RoleBinding, wêrmei de brûker mynewuser "lêze" pods yn nammeromte 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

Event audit

Skematysk kin de Kubernetes-arsjitektuer as folget wurde fertsjintwurdige:

De ABC fan Feiligens yn Kubernetes: Autentikaasje, Autorisaasje, Auditing

De kaai Kubernetes komponint ferantwurdlik foar it ferwurkjen fan oanfragen is api-tsjinner. Alle operaasjes op it kluster geane der troch. Jo kinne mear lêze oer dizze ynterne meganismen yn it artikel "Wat bart der yn Kubernetes as jo kubectl run útfiere?".

Systeemkontrôle is in nijsgjirrige funksje yn Kubernetes, dy't standert útskeakele is. It lit jo alle oproppen oanmelde by de Kubernetes API. Lykas jo miskien riede, wurde alle aksjes yn ferbân mei it kontrolearjen en feroarjen fan de steat fan it kluster útfierd fia dizze API. In goede beskriuwing fan syn mooglikheden kin (lykas gewoanlik) fûn wurde yn offisjele dokumintaasje K8s. Dêrnei sil ik besykje it ûnderwerp yn ienfâldiger taal te presintearjen.

En sa, om auditing mooglik te meitsjen, moatte wy trije fereaske parameters trochjaan oan de kontener yn api-server, dy't hjirûnder yn mear detail beskreaun wurde:

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

Neist dizze trije needsaaklike parameters binne d'r in protte ekstra ynstellingen yn ferbân mei auditing: fan logrotaasje oant webhookbeskriuwingen. Foarbyld fan parameters foar logrotaasje:

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

Mar wy sille net yn mear detail oer har gean - jo kinne alle details fine yn kube-apiserver dokumintaasje.

Lykas al neamd, binne alle parameters ynsteld yn it manifest mei de api-server-konfiguraasje (standert /etc/kubernetes/manifests/kube-apiserver.yaml), yn seksje command. Litte wy weromgean nei de 3 fereaske parameters en analysearje se:

  1. audit-policy-file - paad nei it YAML-bestân dat it kontrôlebelied beskriuwt. Wy sille letter weromkomme nei de ynhâld, mar foar no sil ik opmerke dat it bestân lêsber wêze moat troch it api-serverproses. Dêrom is it nedich om it yn 'e kontener te montearjen, wêrfoar jo de folgjende koade kinne tafoegje oan' e passende seksjes fan 'e konfiguraasje:
      volumeMounts:
        - mountPath: /etc/kubernetes/policies
          name: policies
          readOnly: true
      volumes:
      - hostPath:
          path: /etc/kubernetes/policies
          type: DirectoryOrCreate
        name: policies
  2. audit-log-path - paad nei it logbestân. It paad moat ek tagonklik wêze foar it api-serverproses, dus beskriuwe wy de montage op deselde manier:
      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 - opmaak fan audit log. De standert is json, mar it legacy tekstformaat is ek beskikber (legacy).

Auditbelied

No oer it neamde bestân dat it loggingbelied beskriuwt. It earste konsept fan kontrôlebelied is level, logging nivo. Se binne as folget:

  • None - net oanmelde;
  • Metadata - logfersykmetadata: brûker, tiid oanfreegje, doelboarne (pod, nammeromte, ensfh.), Aksjetype (tiidwurd), ensfh.;
  • Request - log metadata en fersyk lichem;
  • RequestResponse - log metadata, fersyk lichem en antwurd lichem.

De lêste twa nivo's (Request и RequestResponse) net oanmelde oanfragen dy't gjin tagong hawwe ta boarnen (tagongen ta saneamde net-boarnen urls).

Ek alle oanfragen geane troch ferskate stadia:

  • RequestReceived - it poadium wêryn it fersyk wurdt ûntfongen troch de prosessor en noch net fierder oer de keatling fan ferwurkers ferstjoerd is;
  • ResponseStarted - antwurdkoppen wurde ferstjoerd, mar foardat it antwurd lichem wurdt ferstjoerd. Generearre foar langrinnende fragen (bygelyks, watch);
  • ResponseComplete - it antwurdorgaan is stjoerd, gjin ynformaasje mear wurdt ferstjoerd;
  • Panic - eveneminten wurde generearre as in abnormale situaasje wurdt ûntdutsen.

Om alle stappen oer te slaan dy't jo kinne brûke omitStages.

Yn in beliedsbestân kinne wy ​​ferskate seksjes beskriuwe mei ferskate loggingsnivo's. De earste oerienkommende regel fûn yn 'e beliedsbeskriuwing sil tapast wurde.

De kubelet-daemon kontrolearret feroaringen yn it manifest mei de konfiguraasje fan api-server en, as der ien wurdt ûntdutsen, start de kontener opnij mei api-tsjinner. Mar d'r is in wichtich detail: feroarings yn it beliedsbestân wurde der troch negearre. Nei it meitsjen fan wizigingen yn it beliedsbestân, moatte jo de api-tsjinner manuell opnij starte. Sûnt api-tsjinner is begûn as statyske pod, team kubectl delete sil net feroarsaakje dat it opnij starte. Jo moatte it mei de hân dwaan docker stop op kube-masters, wêr't it kontrôlebelied feroare is:

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

By it ynskeakeljen fan kontrôle is it wichtich om dat te ûnthâlden de lading op kube-apiserver nimt ta. Benammen ûnthâld konsumpsje foar it bewarjen fan fersyk kontekst nimt ta. Logging begjint pas nei't de antwurdkop is ferstjoerd. De lading hinget ek ôf fan 'e konfiguraasje fan' e kontrôlebelied.

Foarbylden fan belied

Litte wy nei de struktuer fan beliedsbestannen sjen mei foarbylden.

Hjir is in ienfâldige triem policyom alles op it nivo te loggen Metadata:

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

Yn belied kinne jo in list mei brûkers opjaan (Users и ServiceAccounts) en brûkersgroepen. Bygelyks, dit is hoe't wy systeem brûkers sille negearje, mar al it oare oanmelde op it nivo 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

It is ek mooglik om de doelen te beskriuwen:

  • nammeromten (namespaces);
  • tiidwurden (tiidwurden: get, update, delete en oaren);
  • boarnen (Boarnen, nammentlik: pod, configmaps ensfh.) en boarnegroepen (apiGroups).

Wês oandacht! Boarnen en boarnegroepen (API-groepen, dus apiGroups), lykas har ferzjes ynstalleare yn it kluster, kinne wurde krigen mei de kommando's:

kubectl api-resources
kubectl api-versions

It folgjende kontrôlebelied wurdt levere as in demonstraasje fan bêste praktiken yn Alibaba Cloud dokumintaasje:

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

In oar goed foarbyld fan kontrôlebelied is profyl brûkt yn GCE.

Om gau te reagearjen op audit eveneminten, is it mooglik beskriuwe webhook. Dit probleem wurdt behannele yn offisjele dokumintaasje, Ik lit it bûten it berik fan dit artikel.

Resultaten

It artikel jout in oersjoch fan basisfeiligensmeganismen yn Kubernetes-klusters, wêrtroch jo personaliseare brûkersakkounts kinne oanmeitsje, har rjochten skiede en har aksjes opnimme. Ik hoopje dat it nuttich wêze sil foar dyjingen dy't yn teory of yn 'e praktyk mei sokke problemen te krijen hawwe. Ik riede ek oan dat jo de list mei oare materialen lêze oer it ûnderwerp fan feiligens yn Kubernetes, dy't wurdt jûn yn "PS" - miskien sille jo ûnder harren de nedige details fine oer de problemen dy't foar jo relevant binne.

PS

Lês ek op ús blog:

Boarne: www.habr.com

Add a comment