ProHoster > Blog > Adminisztráció > A biztonság ABC-je a Kubernetesben: hitelesítés, engedélyezés, auditálás
A biztonság ABC-je a Kubernetesben: hitelesítés, engedélyezés, auditálás
Előbb-utóbb minden rendszer működése során felmerül a biztonság kérdése: a hitelesítés biztosítása, a jogok szétválasztása, az auditálás és egyéb feladatok. Már létrehozva a Kubernetes számára sok megoldás, amelyek lehetővé teszik a szabványoknak való megfelelést még nagyon igényes környezetben is... Ugyanezt az anyagot szenteljük a K8-ak beépített mechanizmusain belül megvalósított biztonság alapvető szempontjainak. Mindenekelőtt azoknak lesz hasznos, akik kezdik ismerkedni a Kubernetes-szel - kiindulópontként a biztonsággal kapcsolatos kérdések tanulmányozásához.
Hitelesítés
A Kubernetesben kétféle felhasználó létezik:
Szolgáltatási fiókok — a Kubernetes API által kezelt fiókok;
felhasználók — külső, független szolgáltatások által kezelt „normál” felhasználók.
A fő különbség ezen típusok között az, hogy a szolgáltatásfiókokhoz speciális objektumok vannak a Kubernetes API-ban (ezeket így hívják - ServiceAccounts), amelyek egy névtérhez és a Titkok típusú objektumokban a fürtben tárolt jogosultsági adatok halmazához vannak kötve. Az ilyen felhasználók (szolgáltatásfiókok) elsősorban a Kubernetes-fürtben futó folyamatok Kubernetes API-jához való hozzáférési jogok kezelésére szolgálnak.
Az átlagos felhasználóknak nincsenek bejegyzései a Kubernetes API-ban: ezeket külső mechanizmusoknak kell kezelniük. A klaszteren kívül élő emberek vagy folyamatok számára készültek.
Minden API-kérelem vagy szolgáltatásfiókhoz, vagy felhasználóhoz van társítva, vagy névtelennek minősül.
A felhasználói hitelesítési adatok a következőket tartalmazzák:
Felhasználónév — felhasználónév (a kis- és nagybetűk megkülönböztetése!);
UID - géppel olvasható felhasználóazonosító karakterlánc, amely „konzisztensebb és egyedibb, mint a felhasználónév”;
Csoportok — azon csoportok listája, amelyekhez a felhasználó tartozik;
külön — további mezők, amelyeket az engedélyezési mechanizmus használhat.
A Kubernetes számos hitelesítési mechanizmust használhat: X509-tanúsítványok, hordozójogkivonatok, hitelesítő proxy, HTTP Basic Auth. Ezekkel a mechanizmusokkal számos engedélyezési sémát valósíthat meg: a jelszavas statikus fájloktól az OpenID OAuth2-ig.
Ezenkívül lehetőség van több engedélyezési séma egyidejű használatára is. Alapértelmezés szerint a fürt a következőket használja:
A ServiceAccounts kezelésével kapcsolatos kérdés túlmutat e cikk keretein, de azoknak, akik szeretnének részletesebben megismerkedni ezzel a kérdéssel, javasoljuk, hogy kezdje hivatalos dokumentációs oldalakon. Részletesebben megvizsgáljuk az X509 tanúsítványok működésének kérdését.
Tanúsítványok felhasználóknak (X.509)
A tanúsítványokkal való munka klasszikus módja a következőket tartalmazza:
tanúsítványkérés feldolgozása a Kubernetes-fürt CA-kulcsok használatával, felhasználói tanúsítvány beszerzése (tanúsítvány megszerzéséhez olyan fiókot kell használnia, amely hozzáfér a Kubernetes-fürt CA-kulcsához, amely alapértelmezés szerint /etc/kubernetes/pki/ca.key):
A konfigurációk fiókok és szerverek közötti átvitelének megkönnyítése érdekében érdemes szerkeszteni a következő kulcsok értékeit:
certificate-authority
client-certificate
client-key
Ehhez a bennük megadott fájlokat a base64 segítségével kódolhatja és regisztrálhatja a konfigurációban, hozzáadva az utótagot a kulcsok nevéhez -data, azaz miután megkapta certificate-authority-data stb
Tanúsítványok kubeadm-mel
A kiadással Kubernetes 1.15 A tanúsítványokkal való munka sokkal könnyebbé vált a támogatás alfa verziójának köszönhetően kubeadm segédprogram. Például így nézhet ki egy konfigurációs fájl létrehozása felhasználói kulcsokkal:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200
NB: Kötelező hirdetési címet megtalálható az api-server konfigurációjában, amely alapértelmezés szerint itt található /etc/kubernetes/manifests/kube-apiserver.yaml.
Az eredményül kapott konfiguráció az stdout-ba kerül. Be kell menteni ~/.kube/config felhasználói fiókba vagy egy környezeti változóban megadott fájlba KUBECONFIG.
Mélyebbre ásni
Azoknak, akik szeretnék alaposabban megérteni a leírt problémákat:
külön cikk a hivatalos Kubernetes dokumentációban található tanúsítványokkal való munkavégzésről;
jó cikk a Bitnamitól, amelyben a tanúsítványok kiadását gyakorlati szempontból érintik.
Az alapértelmezett jogosult fióknak nincs joga a fürtön való működéshez. Az engedélyek megadásához a Kubernetes engedélyezési mechanizmust valósít meg.
Az 1.6-os verzió előtt a Kubernetes az elnevezésű engedélyezési típust használta ABAC (Attribútum alapú hozzáférés-vezérlés). Részletek az oldalon találhatók hivatalos dokumentáció. Ez a megközelítés jelenleg örököltnek számít, de továbbra is használhatja más hitelesítési típusokkal együtt.
A fürthöz való hozzáférési jogok felosztásának jelenlegi (és rugalmasabb) módját ún RBAC (Szerepalapú hozzáférés-vezérlés). A verzió óta stabilnak nyilvánították Kubernetes 1.8. Az RBAC olyan jogmodellt valósít meg, amelyben minden, ami nem kifejezetten engedélyezett, tiltott. Az RBAC engedélyezéséhez, el kell indítania a Kubernetes api-servert a paraméterrel --authorization-mode=RBAC. A paraméterek a jegyzékben az api-szerver konfigurációjával vannak beállítva, amely alapértelmezés szerint az útvonal mentén található /etc/kubernetes/manifests/kube-apiserver.yaml, szakaszban command. Az RBAC azonban már alapértelmezés szerint engedélyezve van, ezért valószínűleg nem kell aggódnia: ezt az értékkel ellenőrizheti authorization-mode (a már említettben kube-apiserver.yaml). A jelentései között egyébként más típusú felhatalmazások is szerepelhetnek (node, webhook, always allow), de ezek megfontolását az anyag keretein kívül hagyjuk.
Egyébként már publikáltunk статью az RBAC-val végzett munka alapelveinek és jellemzőinek meglehetősen részletes leírásával, így a továbbiakban az alapok és a példák rövid felsorolására szorítkozom.
A következő API-entitások használatosak a Kubernetes hozzáférésének szabályozására RBAC-n keresztül:
Role и ClusterRole — a hozzáférési jogok leírására szolgáló szerepek:
Role lehetővé teszi a jogok leírását egy névtéren belül;
ClusterRole - a fürtön belül, beleértve a fürtspecifikus objektumokat, például csomópontokat, nem erőforrás-url-eket (azaz nem Kubernetes-erőforrásokhoz kapcsolódnak - pl. /version, /logs, /api*);
RoleBinding и ClusterRoleBinding - kötéshez használják Role и ClusterRole felhasználóhoz, felhasználói csoporthoz vagy ServiceAccounthoz.
A Role és RoleBinding entitásokat névtér korlátozza, pl. ugyanabban a névtérben kell lennie. A RoleBinding azonban hivatkozhat egy ClusterRole-ra, amely lehetővé teszi általános engedélyek készletének létrehozását és a hozzáférés szabályozását ezek segítségével.
A szerepkörök a következőket tartalmazó szabályokkal írják le a jogokat:
API csoportok – lásd hivatalos dokumentáció az apiGroups és a kimenet által kubectl api-resources;
erőforrás nevek (resourceNames) - arra az esetre, ha hozzáférést kell biztosítania egy adott erőforráshoz, és nem az összes ilyen típusú erőforráshoz.
A Kubernetes engedélyezésének részletesebb elemzése a oldalon található hivatalos dokumentáció. Ehelyett (vagy inkább e mellett) példákat hozok, amelyek illusztrálják munkásságát.
Példák RBAC entitásokra
egyszerű Role, amely lehetővé teszi, hogy megkapja a pod-ok listáját és állapotát, és figyelje azokat a névtérben target-namespace:
Példa ClusterRole, amely lehetővé teszi a tömbök listájának és állapotának lekérését, valamint azok nyomon követését a fürtben:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# секции "namespace" нет, так как ClusterRole задействует весь кластер
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Példa RoleBinding, amely lehetővé teszi a felhasználó számára mynewuser "olvasni" sorokat 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 # имя пользователя зависимо от регистра!
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # здесь должно быть “Role” или “ClusterRole”
name: pod-reader # имя Role, что находится в том же namespace,
# или имя ClusterRole, использование которой
# хотим разрешить пользователю
apiGroup: rbac.authorization.k8s.io
Rendezvény audit
Sematikusan a Kubernetes architektúra a következőképpen ábrázolható:
A kérések feldolgozásáért felelős Kubernetes kulcsfontosságú összetevője api-szerver. A fürt összes művelete ezen megy keresztül. Ezekről a belső mechanizmusokról bővebben a " cikkben olvashatMi történik a Kubernetesben a kubectl run futtatásakor?".
A rendszernaplózás egy érdekes funkció a Kubernetesben, amely alapértelmezés szerint le van tiltva. Lehetővé teszi a Kubernetes API összes hívásának naplózását. Ahogy sejtheti, a fürt állapotának figyelésével és módosításával kapcsolatos összes művelet ezen az API-n keresztül történik. Képességeinek jó leírása (szokás szerint) a következő helyen található hivatalos dokumentáció K8s. A továbbiakban megpróbálom egyszerűbb nyelven bemutatni a témát.
Így hogy lehetővé tegye az auditálást, három szükséges paramétert kell átadnunk a konténernek az api-szerverben, amelyeket az alábbiakban részletesebben ismertetünk:
Ezen a három szükséges paraméteren kívül számos további beállítás is kapcsolódik az auditáláshoz: a naplóforgatástól a webhook leírásokig. Példa a napló forgatási paramétereire:
Mint már említettük, az összes paraméter a jegyzékben az api-szerver konfigurációjával van beállítva (alapértelmezés szerint /etc/kubernetes/manifests/kube-apiserver.yaml), a szakaszban command. Térjünk vissza a 3 kötelező paraméterhez, és elemezzük őket:
audit-policy-file — az ellenőrzési szabályzatot leíró YAML-fájl elérési útja. Tartalmára később visszatérünk, de egyelőre megjegyzem, hogy a fájlnak olvashatónak kell lennie az api-server folyamatnak. Ezért szükséges a konténer belsejébe illeszteni, amelyhez a következő kódot adhatja hozzá a konfiguráció megfelelő részeihez:
audit-log-path — a naplófájl elérési útja. Az elérési útnak az api-szerver folyamat számára is elérhetőnek kell lennie, ezért a beszerelését ugyanúgy írjuk le:
RequestResponse — naplózza a metaadatokat, a kérelem törzsét és a válasz törzsét.
Az utolsó két szint (Request и RequestResponse) ne naplózza azokat a kéréseket, amelyek nem fértek hozzá az erőforrásokhoz (az úgynevezett nem erőforrás-url-ekhez való hozzáférés).
Ezenkívül minden kérés átmegy több szakaszban:
RequestReceived — az a szakasz, amikor a kérelmet a feldolgozó megkapja, és még nem továbbították a feldolgozók láncán;
ResponseStarted — a válaszfejlécek elküldésre kerülnek, de a választörzs elküldése előtt. Hosszan futó lekérdezésekhez generálva (pl. watch);
ResponseComplete — a válaszadó szervet elküldték, több információt nem küldenek;
Panic — események generálódnak, ha rendellenes helyzetet észlelnek.
Bármely lépés kihagyásához használhatja omitStages.
Egy házirendfájlban több szakaszt is leírhatunk különböző naplózási szintekkel. Az irányelv leírásában található első egyező szabály kerül alkalmazásra.
A kubelet démon az api-szerver konfigurációjával figyeli a jegyzékben bekövetkezett változásokat, és ha ilyeneket észlel, újraindítja a tárolót az api-szerverrel. De van egy fontos részlet: a házirend-fájl módosításait figyelmen kívül hagyja. A házirendfájl módosítása után manuálisan újra kell indítania az api-kiszolgálót. Mivel az api-szerver a következővel indul statikus pod, csapat kubectl delete nem indítja újra. Ezt manuálisan kell megtennie docker stop a kube-masters-en, ahol az ellenőrzési szabályzat megváltozott:
Az auditálás engedélyezésekor fontos emlékezni erre a kube-apiserver terhelése nő. Különösen a kéréskörnyezet tárolására szolgáló memóriafelhasználás növekszik. A naplózás csak a válaszfejléc elküldése után kezdődik. A terhelés az ellenőrzési házirend konfigurációjától is függ.
Példák irányelvekre
Nézzük meg a házirend-fájlok szerkezetét példák segítségével.
Itt van egy egyszerű fájl policyszinten naplózni mindent Metadata:
A szabályzatban megadhatja a felhasználók listáját (Users и ServiceAccounts) és felhasználói csoportok. Például így figyelmen kívül hagyjuk a rendszerfelhasználókat, de minden mást szinten naplózunk Request:
erőforrások (erőforrás, nevezetesen: pod, configmaps stb.) és erőforráscsoportok (apiGroups).
Figyelj! Az erőforrások és erőforráscsoportok (API csoportok, azaz apiGroupok), valamint a fürtbe telepített verzióik a következő parancsokkal érhetők el:
kubectl api-resources
kubectl api-versions
Az alábbi könyvvizsgálati politika a legjobb gyakorlatok bemutatásaként szolgál Alibaba Cloud dokumentáció:
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
Az audit eseményekre való gyors reagálás lehetséges írja le a webhookot. Ezzel a kérdéssel foglalkozik hivatalos dokumentáció, ezt a cikk keretein kívül hagyom.
Eredményei
A cikk áttekintést nyújt a Kubernetes-fürtök alapvető biztonsági mechanizmusairól, amelyek lehetővé teszik személyre szabott felhasználói fiókok létrehozását, jogaik elkülönítését és tevékenységeik rögzítését. Remélem, hasznos lesz azoknak, akik elméletben vagy a gyakorlatban ilyen problémákkal szembesülnek. Azt is javaslom, hogy olvassa el a Kubernetes biztonsági témájával kapcsolatos egyéb anyagok listáját, amely a „PS”-ben található - talán ezek között megtalálja az Ön számára releváns problémákra vonatkozó szükséges részleteket.