Biztonsági ABC a Kubernetesben: hitelesítés, jogosultságkezelés, auditálás

Biztonsági ABC a Kubernetesben: hitelesítés, jogosultságkezelés, auditálás

Előbb-utóbb bármely rendszer üzemeltetése során felmerül a biztonság kérdése: a hitelesítés, a jogosultságok elválasztása, az auditálás és más feladatok biztosítása. A Kuberneteshez már létrehoztak számos megoldást, amelyek lehetővé teszik a megfelelést a szabványoknak, még nagyon igényes környezetekben is… Ez az anyag a Kubernetesben megvalósított biztonság alapvető aspektusainak szentelt figyelmet. Elsősorban azoknak lesz hasznos, akik most ismerkednek a Kubernetes-szel, mint kiindulópont a biztonság témaköreinek tanulmányozásához.

Hitelesítés

A Kubernetesben kétféle felhasználó létezik:

  • Szolgáltatásfiókok — a Kubernetes API által kezelt fiókok;
  • Felhasználók — a külső, független szolgáltatások által kezelt „normális” felhasználók.

Az alapvető különbség a két típus között az, hogy a Szolgáltatásfiókok számára külön objektumok léteznek a Kubernetes API-ban (azokat így hívják — ServiceAccounts), amelyek névterekhez és a klaszterben a Secrets típusú objektumokban tárolt hitelesítési adatokhoz kapcsolódnak. Ezek a felhasználók (Szolgáltatásfiókok) elsősorban a Kubernetes API-hoz való hozzáférési jogok kezelésére szolgálnak a Kubernetes klaszterben futó folyamatok számára.

A normál Felhasználók nem rendelkeznek bejegyzésekkel a Kubernetes API-ban: kezelésüket külső mechanizmusoknak kell végezniük. Ők az emberek vagy folyamatok számára készültek, akik a klaszteren kívül tartózkodnak.

Minden API-kérelem vagy Szolgáltatásfiókhoz, vagy Felhasználóhoz kapcsolódik, vagy névtelennek számít.

A felhasználó hitelesítési adatai a következőket foglalják magukban:

  • Felhasználónév — felhasználónév (az érzékeny a kis- és nagybetűkre!);
  • UID — a felhasználó azonosításának gépileg olvasható karakterlánca, amely „konzisztensebb és egyedibb, mint a felhasználónév”;
  • Csoportok — a felhasználóhoz tartozó csoportok listája;
  • További — olyan extra mezők, amelyeket a jogosultságkezelő mechanizmus használhat.

A Kubernetes számos hitelesítési mechanizmust használhat: X509 tanúsítványokat, Bearer-tokeneket, hitelesítő proxyt, HTTP Basic Auth-ot. Ezekkel a mechanizmusokkal számos jogosultságkezelési sémát megvalósíthatunk: a statikus fájloktól a jelszavakkal egészen az OpenID OAuth2-ig.

Továbbá, több jogosultságkezelési séma egyidejű használata is megengedett. Alapértelmezés szerint a klaszterben a következők használatosak:

  • a szolgáltatásfiók tokenek — Szolgáltatásfiókok számára;
  • X509 — a Felhasználók számára.

A ServiceAccount-kezeléssel kapcsolatos kérdések túllépnek ennek a cikknek a keretein, és azoknak, akik részletesebben szeretnének megismerkedni ezzel a kérdéssel, javaslom, hogy kezdjék el a hivatalos dokumentáció oldalával.Most részletesebben megvizsgáljuk az X509 tanúsítványok működését.

Tanúsítványok a felhasználók számára (X.509)

A tanúsítványokkal való klasszikus munka közé tartozik:

  • a kulcs generálása:
    mkdir -p ~/mynewuser/.certs/
    openssl genrsa -out ~/certs/mynewuser.key 2048
  • tanúsítványkérelem generálása:
    openssl req -new -key ~/certs/mynewuser.key -out ~/certs/mynewuser.csr -subj "/CN=mynewuser/O=company"
  • a tanúsítványkérelem feldolgozása a Kubernetes klaszter CA kulcsaival, a felhasználói tanúsítvány beszerzése (a tanúsítvány megszerzéséhez egy olyan fiókot kell használni, amely hozzáféréssel rendelkezik a Kubernetes klaszter tanúsítványkezelő kulcsához, amely alapértelmezés szerint található /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
  • konfigurációs fájl létrehozása:
    • a klaszter leírása (adja meg a CA tanúsítvány fájl címét és elérhetőségét a klaszter adott telepítése esetén):
      kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.100.200:6443
    • vagy — a javasolt lehetőség — nem szükséges megadni a gyökér tanúsítványt (ebben az esetben a kubectl nem ellenőrzi a klaszter api-serverének pontosságát): nemkubectl config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://192.168.100.200:6443
      felhasználó hozzáadása a konfigurációs fájlhoz:
    • kubectl config set-credentials mynewuser --client-certificate=.certs/mynewuser.crt --client-key=.certs/mynewuser.key
      kontextus hozzáadása:
    • kubectl config set-context mynewuser-context --cluster=kubernetes --namespace=target-namespace --user=mynewuser
      a kezdő kontextus megadása:
    • kubectl config use-context mynewuser-context
      A fent említett műveletek után a fájlban

.kube/config konfigurációs forma jön létre: 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

A konfiguráció átvitelének megkönnyítése érdekében különböző fiókok és szerverek között érdemes módosítani a következő kulcsok értékeit:

certificate-authority

  • client-certificate
  • client-key
  • Ehhez a megadott fájlokat base64 kódolással átkonvertálhatjuk, és beleírhatjuk a konfigurációba, hozzáadva a kulcsok nevéhez a -data suffixet

, így kapva certificate-authority-dataTanúsítványok kubeadm-mel A Kubernetes 1.15-ös verzióval. és így tovább.

Kubernetes 1.15 kiadásával

A Kubernetes 1.15 verzióval Kubernetes 1.15 kiadása A tanúsítványok kezelése jelentősen egyszerűbbé vált a támogatás alfa verziója révén a kubeadm eszközben.Például, így nézhet ki a felhasználói kulcsokkal rendelkező konfigurációs fájl generálása:

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

NB: Szükséges advertise address megtekinthető az api-server konfigurációjában, amely alapértelmezés szerint itt található: /etc/kubernetes/manifests/kube-apiserver.yaml.

A létrejövő konfiguráció a stdout-ba kerül kiírásra. Ezt el kell menteni a ~/.kube/config felhasználói fiókba vagy a környezeti változóban megadott fájlba. KUBECONFIG.

További részletekért

az érdeklődők számára:

Engedélyezés

Az alapértelmezett felhasználói fiók nem rendelkezik jogokkal a klaszterben végzett műveletekhez. Az engedélyek biztosítására a Kubernetes-ben engedélyezési mechanizmust alkalmaztak.

1.6 verzió előtt a Kubernetes egy engedélyezési típust használt, amelyet ABAC (Attribútum alapú hozzáférés-vezérlés) néven ismerünk. A részleteket itt találhatja: hivatalos dokumentációban. Jelenleg ez a megközelítés elavultnak (legacy) számít, azonban még mindig használhatja más engedélyezési típusok mellett.

A legaktuálisabb (és rugalmasabb) módja a hozzáférési jogok klaszteren belüli elkülönítésének az RBAC (Szerepkör alapú hozzáférés-vezérlés). Ezt a verziót a Kubernetes 1.8tette stabilvá.
Az RBAC végrehajt egy olyan jogi modellt, amelyben minden tilos, amit kifejezetten nem engedélyeztek.Az RBAC engedélyezéséhez , el kell indítania a Kubernetes api-servert a--authorization-mode=RBAC /etc/kubernetes/manifests/kube-apiserver.yamlparaméterrel. A paraméterek az api-server konfigurációs manifestjében vannak beállítva, amely alapértelmezett helye itt található: command. Egyébként alapértelmezés szerint az RBAC már be van kapcsolva, így valószínűleg nem kell ezzel foglalkoznia: ezt a authorization-mode értéke alapján ellenőrizheti (amely az említett kube-apiserver.yaml). Megjegyzés, hogy az értékei között más engedélyezési típusok is szerepelhetnek (node, webhook, mindig engedélyezve), de ezeknek a részletezését hagyjuk ki a cikk keretein belül.

Megjegyzés, hogy már publikáltunk cikket amely elég részletesen beszél a RBAC működésének alapelveiről és sajátosságairól, ezért innentől kezdve csak az alapokat és példákat említem meg.

A Kubernetes-ben az RBAC-n keresztüli hozzáférés kezelésére a következő API entitásokat használják:

  • Szerep és ClusterRole — szerepek, amelyek a hozzáférési jogok leírására szolgálnak:
  • Szerep lehetővé teszi a jogok leírását a névtér keretein belül;
  • ClusterRole — a klaszteren belül, beleértve a klaszter-specifikus objektumokat, mint például a csomópontokat, non-resources urls-t (azaz nem a Kubernetes erőforrásaival kapcsolatosakat — például, /version, /logs, /api*);
  • RoleBinding és ClusterRoleBinding — a felhasználó, felhasználói csoport vagy ServiceAccount összekapcsolására szolgál. Szerep és ClusterRole A Role és RoleBinding entitások névtérre korlátozottak, azaz egy adott névtéren belül kell lenniük. A RoleBinding azonban hivatkozhat ClusterRole-ra, lehetővé téve ezzel egy szabványos engedélykészlet létrehozását és a hozzáférés kezelését.

A szerepek a jogokat szabálykészletek segítségével írják le, amelyek a következőket tartalmazzák:

API csoportok — lásd

  • a hivatalos dokumentációt az apiGroups-ról és a kimenetről kubectl api-resources erőforrások (;
  • podresources: deployment, namespace, stb.); igazság szerint.
  • igék (verbs: set, update stb.).
  • erőforrásnevek (resourceNames) — amikor hozzáférést kell biztosítani egy adott erőforráshoz, nem pedig az összes ezen erőforrás típushoz.

A Kubernetes-hez kapcsolódó hitelesítési leírást a következő oldalon találja: hivatalos dokumentációban. Ehelyett (pontosabban — e mellett) példákat adok, amelyek illusztrálják a működését.

RBAC entitások példái

Egyszerű Szerep, amelyek lehetővé teszik a podok listájának és állapotának megtekintését és figyelését a névtérben 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"]

támadásra ClusterRole, amely lehetővé teszi a podok listájának és állapotának megtekintését és figyelését az egész klaszterben:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # nincs "namespace" szekció, mivel a ClusterRole az egész klasztert használja
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

támadásra RoleBinding, ez lehetővé teszi a felhasználónak mynewuser a podok "olvasását" a névtérben my-namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: target-namespace
subjects:
- kind: User
  name: mynewuser # a felhasználóneve kis- és nagybetűérzékeny!
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role # itt "Role" vagy "ClusterRole" kell legyen
  name: pod-reader # a névtérben lévő Role neve,
                   # vagy a ClusterRole neve, amelynek használatát
                   # szeretnénk engedélyezni a felhasználónak
  apiGroup: rbac.authorization.k8s.io

Események auditálása

A Kubernetes architektúrája sémásan a következőképpen ábrázolható:

Biztonsági ABC a Kubernetesben: hitelesítés, jogosultságkezelés, auditálás

A Kubernetes kulcsfontosságú összetevője, amely a lekérdezések kezeléséért felelős, — api-server. Minden művelet a klaszteren keresztül zajlik. Az ezekről a belső mechanizmusokról további információkat találhat a „Mi történik a Kubernetesben a kubectl run parancs futtatásakor?».

A rendszer auditja - egy érdekes funkció a Kubernetesben, amely alapértelmezés szerint ki van kapcsolva. Lehetővé teszi a Kubernetes API-hoz intézett összes kérés naplózását. Ahogy könnyen kitalálható, ezen az API-n keresztül történnek az összes olyan művelet, amelyek a klaszter állapotának ellenőrzésével és megváltoztatásával kapcsolatosak. A lehetőségeiről részletes leírást találhat (mint általában) a hivatalos dokumentációban K8s. Most megpróbálom leegyszerűsítve kifejteni a témát.

Tehát, az audit engedélyezéséhez, három kötelező paramétert kell átadnunk a konténernek az api-server számára, amelyeket alább részletesebben ismertetünk:

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

Ezeken a három kötelező paraméteren kívül számos egyéb beállítás is létezik, amelyek az auditra vonatkoznak: a naplók forgatásától kezdve a webhook leírásokig. A naplók forgatásának példaparaméterei:

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

De most nem fogunk részletesebben megállni rajtuk - minden részletet megtalálhat a kube-apiserver dokumentációjában.

Ahogy már említettük, minden paraméter a api-server konfigurációs manifestjében van beállítva (alapértelmezés szerint /etc/kubernetes/manifests/kube-apiserver.yaml), a commandszekcióban. Térjünk vissza a három kötelező paraméterhez és nézzük meg őket:

  1. audit-policy-file — az audit politika YAML fájl elérési útja. A tartalmára még visszatérünk, de először is megjegyzem, hogy a fájlnak olvashatónak kell lennie az api-server folyamata számára. Ezért be kell montálnunk a konténer belsejében, amit a következő kód hozzáadásával tehetünk meg a megfelelő konfigurációs szekciókhoz:
      volumeMounts:
        - mountPath: \/etc\/kubernetes\/policies
          name: policies
          readOnly: true
      volumes:
      - hostPath:
          path: \/etc\/kubernetes\/policies
          type: DirectoryOrCreate
        name: policies
  2. audit-log-path — a naplófájl elérési útja. Az elérési útnak szintén elérhetőnek kell lennie az api-server folyamata számára, ezért hasonlóan leírom a montálását:
      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 — az audit napló formátuma. Alapértelmezés szerint ez json, de elérhető egy elavult szöveges formátum is (legacy).

Audit politika

Most a megemlített naplózási politika leíró fájlról. Az audit politika első fogalma - ez a szint, a naplózási szint. Különböző típusai léteznek:

  • None — nem naplózni;
  • Metadata — a kérés metaadatait naplózók: felhasználó, kérés ideje, célforrás (pod, névtér stb.), művelet típusa (ige) stb.;
  • Kérés — a kérés metaadatait és törzsét naplózók;
  • KérésVálasz — a kérés metaadatait, a kérés törzsét és a válasz törzsét naplózók.

Az utolsó két szint (Kérés és KérésVálasz) nem naplózzák azokat a kéréseket, amelyek nem értek el forrásokat (az úgynevezett nem-forrás URL-ekhez való hozzáférések).

Emellett minden kérés áthalad több szakaszon:

  • KérésKapott — a szakasz, amikor a kérés megérkezik a kezelőhöz, és még nem lett továbbítva a kezelők láncán;
  • VálaszKezdődött — a válasz fejlécét elküldték, de a válasz törzsének elküldése előtt. Hosszan elhúzódó kérések esetén generálódik (például, figyelés);
  • VálaszTeljes — a válasz törzse elküldve, további információ már nem lesz elküldve;
  • Pánik — eseményeket generál, amikor rendellenességet észlelnek.

Bármely szakasz kihagyásához használhatjuk kihagyásSzakaszok.

A szabályzat fájlban több szakaszt is megadhatunk eltérő naplózási szintekkel. Az első megfelelő szabály fog alkalmazásra kerülni, amely a policy leírásában szerepel.

A kubelet démon nyomon követi az api-server konfigurációs manifestjének változásait, és ha ilyet észlel, újraindítja az api-server konténert. De van egy fontos részlet: a policy fájlban végzett változtatásokat figyelmen kívül hagyja. A policy fájlba történő módosítások után kézzel újra kell indítani az api-servert. Mivel az api-server statikus podként fut, statikus pod, a parancs kubectl törlés nem indítja újra. Kézzel kell végrehajtani docker megállítás a kube-mastereken, ahol módosult az audit politika:

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

Az audit engedélyezésekor fontos figyelembe venni, hogy a kube-apiserveren nő a terhelés. Különösen a memóriafogyasztás növekszik a kérések kontextusának tárolásakor. A naplózás akkor kezdődik, amikor a válasz fejlécét elküldték. A terhelés a naplózási politika konfigurációjától is függ.

Példa politikák

Nézzük meg a policy fájlok struktúráját példákon keresztül.

Itt van egy egyszerű fájl szabályzat, hogy mindent naplózzon a szinten Metadata:

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

A policy-ban megadhatunk felhasználók (Felhasználók és ServiceAccounts) és felhasználói csoportok listáját. Például, így figyelmen kívül hagyhatjuk a rendszerfelhasználókat, de minden mást naplózunk a szinten Kérés:

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

Van lehetőség van a célzottak leírására:

  • névterek (namespace-ek);
  • igék (verbs: get, update, törlés és egyéb);
  • podresources, nevezetesen: deployment, configmap-ek és így tovább) és erőforrás csoportok (apiGroup-ok).

Felhívjuk a figyelmet! Az erőforrások és erőforrás csoportok (API csoportok, azaz apiGroup-ok), valamint a klaszterben telepített verziók a következő parancsokkal érhetők el:

kubectl api-resources
kubectl api-versions

A következő audit policy a legjobb gyakorlatok példájaként szerepel a Alibaba Cloud dokumentációjában:

apiVersion: audit.k8s.io/v1beta1
kind: Policy
# Ne naplózd a RequestReceived szakaszt
omitStages:
  - "RequestReceived"
rules:
  # Ne naplózd az apró, nem veszélyes eseményeket:
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
      - group: "" # ez az api group üres névvel, amelyhez tartozik
                  # a Kubernetes alap erőforrásai, az úgynevezett “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"]
  # Ne naplózd a read-only URL-eket:
  - level: None
    nonResourceURLs:
      - /healthz*
      - /version
      - /swagger*
  # Ne naplózd a “events” típusú erőforrásokra vonatkozó üzeneteket:
  - level: None
    resources:
      - group: "" # core
        resources: ["events"]
  # A Secret, ConfigMap és TokenReview típusú erőforrások titkos adatokat tartalmazhatnak,
  # ezért csak a hozzátartozó kérések metadatáit naplózzuk
  - level: Metadata
    resources:
      - group: "" # core
        resources: ["secrets", "configmaps"]
      - group: authentication.k8s.io
        resources: ["tokenreviews"]
  # A get, list és watch típusú műveletek erőforrást igényelhetnek; ne naplózd azokat
  - 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"
  # Az alapértelmezett naplózási szint a standard API erőforrásokhoz
  - 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"
  # Az alapértelmezett naplózási szint minden más kéréshez
  - level: Metadata

Egy másik jó példa az audit policy-ra — profil, amelyet a GCE-ben használnak.

Az audit eseményekre való gyors reagálás érdekében lehetőség van webhook leírására. Ez a kérdés részletesen ki van fejtve hivatalos dokumentációban, ezt a cikk keretein kívül hagyom.

Összegzés

A cikk áttekinti a Kubernetes klaszterekben a biztonsági alapmechanizmusokat, amelyek lehetővé teszik az egyéni felhasználói fiókok létrehozását, jogok megosztását és a felhasználói tevékenységek naplózását. Remélem, hasznos lesz azok számára, akik ilyen kérdésekkel találkoztak elméletben vagy már a gyakorlatban. Javaslom, hogy ismerkedjen meg a Kubernetes biztonságával kapcsolatos további anyagok listájával, amelyet a „P.S.” részben talál, talán köztük megtalálja az Ön számára releváns problémák részleteit.

P.S.

Olvasson további információkat a blogunkban:

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster