
Anksčiau ar vėliau bet kurios sistemos veikimo metu iškyla saugumo klausimas: autentifikavimo užtikrinimas, teisių atskyrimas, auditas ir kitos užduotys. Jau sukurta Kubernetes , kurios leidžia pasiekti standartų laikymąsi net ir labai reiklioje aplinkoje... Ta pati medžiaga skirta pagrindiniams saugumo aspektams, įgyvendinamiems K8s integruotuose mechanizmuose. Visų pirma, tai bus naudinga pradedantiesiems susipažinti su Kubernetes – kaip atspirties tašku nagrinėjant su saugumu susijusias problemas.
Autentifikavimas
„Kubernetes“ yra dviejų tipų vartotojai:
- Paslaugų sąskaitos — Kubernetes API valdomos paskyros;
- vartotojai — „paprasti“ vartotojai, valdomi išorinių, nepriklausomų paslaugų.
Pagrindinis skirtumas tarp šių tipų yra tas, kad paslaugų paskyroms Kubernetes API yra specialūs objektai (jie vadinami taip - ServiceAccounts), kurios yra susietos su vardų erdve ir prieigos duomenų rinkiniu, saugomu klasteryje paslapčių tipo objektuose. Tokie vartotojai (paslaugų abonementai) pirmiausia skirti valdyti Kubernetes klasteryje veikiančių procesų prieigos teises prie Kubernetes API.
Paprasti vartotojai neturi įrašų Kubernetes API: juos turi valdyti išoriniai mechanizmai. Jie skirti žmonėms ar procesams, gyvenantiems už klasterio ribų.
Kiekviena API užklausa susieta su paslaugos paskyra, vartotoju arba laikoma anonimiška.
Vartotojo autentifikavimo duomenys apima:
- Vartotojo vardas — vartotojo vardas (skiriamos didžiosios ir mažosios raidės!);
- UID - mašininiu būdu nuskaitoma vartotojo identifikavimo eilutė, kuri yra „nuoseklesnė ir unikalesnė nei vartotojo vardas“;
- Grupės — grupių, kurioms priklauso vartotojas, sąrašas;
- papildomai — papildomi laukai, kuriuos gali naudoti autorizacijos mechanizmas.
„Kubernetes“ gali naudoti daugybę autentifikavimo mechanizmų: X509 sertifikatus, nešiklio prieigos raktus, autentifikavimo tarpinį serverį, HTTP pagrindinį autentifikavimą. Naudodamiesi šiais mechanizmais galite įdiegti daugybę autorizacijos schemų: nuo statinio failo su slaptažodžiais iki OpenID OAuth2.
Be to, vienu metu galima naudoti kelias autorizavimo schemas. Pagal numatytuosius nustatymus klasteris naudoja:
- paslaugų sąskaitų žetonai – paslaugų sąskaitoms;
- X509 – vartotojams.
Klausimas apie „ServiceAccounts“ valdymą nepatenka į šio straipsnio taikymo sritį, tačiau tiems, kurie nori išsamiau susipažinti su šia problema, rekomenduoju pradėti nuo . Mes atidžiau pažvelgsime į klausimą, kaip veikia X509 sertifikatai.
Sertifikatai naudotojams (X.509)
Klasikinis darbo su sertifikatais būdas apima:
- raktų generavimas:
mkdir -p ~/mynewuser/.certs/ openssl genrsa -out ~/.certs/mynewuser.key 2048 - sugeneruoti sertifikato užklausą:
openssl req -new -key ~/.certs/mynewuser.key -out ~/.certs/mynewuser.csr -subj "/CN=mynewuser/O=company" - sertifikato užklausos apdorojimas naudojant Kubernetes klasterio CA raktus, vartotojo sertifikato gavimas (norėdami gauti sertifikatą, turite naudoti paskyrą, turinčią prieigą prie Kubernetes klasterio CA rakto, kuris pagal numatytuosius nustatymus yra
/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 - sukurti konfigūracijos failą:
- klasterio aprašas (nurodykite konkretaus klasterio diegimo CA sertifikato failo adresą ir vietą):
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.100.200:6443 - arba kaip nerekomenduojama parinktis - jums nereikia nurodyti šakninio sertifikato (tada kubectl nepatikrins klasterio api serverio teisingumo):
kubectl config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://192.168.100.200:6443 - pridėti vartotoją prie konfigūracijos failo:
kubectl config set-credentials mynewuser --client-certificate=.certs/mynewuser.crt --client-key=.certs/mynewuser.key - pridėti kontekstą:
kubectl config set-context mynewuser-context --cluster=kubernetes --namespace=target-namespace --user=mynewuser - numatytasis konteksto priskyrimas:
kubectl config use-context mynewuser-context
- klasterio aprašas (nurodykite konkretaus klasterio diegimo CA sertifikato failo adresą ir vietą):
Po pirmiau minėtų manipuliacijų, faile .kube/config bus sukurta tokia konfigūracija:
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.keyKad būtų lengviau perkelti konfigūraciją tarp paskyrų ir serverių, naudinga redaguoti šių raktų reikšmes:
-
certificate-authority -
client-certificate -
client-key
Norėdami tai padaryti, galite užkoduoti juose nurodytus failus naudodami base64 ir užregistruoti juos konfigūracijoje, pridėdami priesagą prie raktų pavadinimo -data, t.y. gavęs certificate-authority-data ir tt
Sertifikatai su kubeadm
Su išleidimu dirbti su sertifikatais tapo daug lengviau dėl jo palaikymo alfa versijos . Pavyzdžiui, taip dabar gali atrodyti konfigūracijos failo su vartotojo raktais generavimas:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200 NB: Reikalingas reklamuoti adresą galima rasti api-serverio konfigūracijoje, kuri pagal numatytuosius nustatymus yra /etc/kubernetes/manifests/kube-apiserver.yaml.
Gauta konfigūracija bus išvesta į stdout. Jį reikia išsaugoti ~/.kube/config vartotojo abonementą arba failą, nurodytą aplinkos kintamajame KUBECONFIG.
Įsigilinkite
Tiems, kurie nori išsamiau suprasti aprašytas problemas:
- apie darbą su sertifikatais oficialioje Kubernetes dokumentacijoje;
- , kuriame sertifikatų išdavimas paliečiamas iš praktinės perspektyvos.
- apie autentifikavimą „Kubernetes“.
Leidimas
Numatytoji įgaliotoji paskyra neturi teisių veikti klasteryje. Kad suteiktų leidimus, Kubernetes įdiegia autorizacijos mechanizmą.
Iki 1.6 versijos Kubernetes naudojo prieigos tipą, vadinamą ABAC (Prieigos valdymas atributais). Išsamią informaciją apie tai galite rasti . Šis metodas šiuo metu laikomas pasenusiu, tačiau vis tiek galite jį naudoti kartu su kitais autentifikavimo tipais.
Dabartinis (ir lankstesnis) prieigos teisių į klasterį padalijimo būdas vadinamas RBAC (). Jis paskelbtas stabiliu nuo versijos . RBAC įgyvendina teisių modelį, kuriame viskas, kas nėra aiškiai leidžiama, yra draudžiama.
Norėdami įjungti RBAC, turite paleisti Kubernetes api-server su parametru --authorization-mode=RBAC. Parametrai apraše nustatomi naudojant api serverio konfigūraciją, kuri pagal numatytuosius nustatymus yra kelyje /etc/kubernetes/manifests/kube-apiserver.yaml, skyriuje command. Tačiau RBAC jau įjungtas pagal numatytuosius nustatymus, todėl greičiausiai neturėtumėte dėl to jaudintis: galite tai patikrinti pagal vertę authorization-mode (jau minėtame kube-apiserver.yaml). Beje, tarp jo reikšmių gali būti ir kitų tipų įgaliojimų (node, webhook, always allow), tačiau jų svarstymą paliksime už medžiagos taikymo srities.
Beje, mes jau paskelbėme su gana išsamiu darbo su RBAC principų ir ypatybių aprašymu, todėl toliau apsiribosiu trumpu pagrindų ir pavyzdžių sąrašu.
Šie API objektai naudojami prieigai Kubernetes valdyti per RBAC:
-
RoleиClusterRole— vaidmenys, kuriais apibūdinamos prieigos teisės: -
Roleleidžia apibūdinti teises vardų erdvėje; -
ClusterRole– klasteryje, įskaitant konkrečiam klasteriui būdingus objektus, tokius kaip mazgai, ne išteklių URL (t. y. nesusiję su Kubernetes ištekliais, pvz.,/version,/logs,/api*); -
RoleBindingиClusterRoleBinding- naudojamas įrišimuiRoleиClusterRolevartotojui, vartotojų grupei arba ServiceAccount.
Role ir RoleBinding subjektai yra ribojami vardų erdvės, t.y. turi būti toje pačioje vardų erdvėje. Tačiau RoleBinding gali nurodyti ClusterRole, kuris leidžia sukurti bendrųjų leidimų rinkinį ir valdyti prieigą naudojant juos.
Vaidmenys apibūdina teises naudojant taisyklių rinkinius, kuriuose yra:
- API grupės – žr pagal apiGroups ir išvestį
kubectl api-resources; - ištekliai (ištekliai:
pod,namespace,deploymentir taip toliau.); - Veiksmažodžiai (veiksmažodžiai:
set,updateir pan.). - išteklių pavadinimai (
resourceNames) - tuo atveju, kai reikia suteikti prieigą prie konkretaus šaltinio, o ne prie visų tokio tipo išteklių.
Išsamesnę Kubernetes autorizavimo analizę galite rasti puslapyje . Vietoj to (tiksliau, be to), pateiksiu pavyzdžių, iliustruojančių jos darbą.
RBAC objektų pavyzdžiai
Paprasta Role, kuri leidžia gauti ankščių sąrašą ir būseną bei stebėti juos vardų erdvėje 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"] Pavyzdys ClusterRole, kuri leidžia gauti ankščių sąrašą ir būseną bei stebėti juos visame klasteryje:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# секции "namespace" нет, так как ClusterRole задействует весь кластер
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"] Pavyzdys RoleBinding, kuri leidžia vartotojui mynewuser „skaityti“ ankštis vardų erdvėje 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.ioRenginio auditas
Schematiškai Kubernetes architektūra gali būti pavaizduota taip:

Pagrindinis Kubernetes komponentas, atsakingas už užklausų apdorojimą, yra api serveris. Per jį atliekamos visos klasterio operacijos. Daugiau apie šiuos vidinius mechanizmus galite perskaityti straipsnyje “".
Sistemos auditas yra įdomi „Kubernetes“ funkcija, kuri pagal numatytuosius nustatymus yra išjungta. Tai leidžia registruoti visus Kubernetes API skambučius. Kaip jau galima spėti, visi veiksmai, susiję su klasterio būsenos stebėjimu ir keitimu, atliekami per šią API. Gerą jo galimybių aprašymą (kaip įprasta) galite rasti K8s. Toliau pabandysiu temą pateikti paprastesne kalba.
tokiu būdu, kad būtų galima atlikti auditą, turime perduoti tris būtinus parametrus į konteinerį api-serveryje, kurie išsamiau aprašyti toliau:
-
--audit-policy-file=/etc/kubernetes/policies/audit-policy.yaml -
--audit-log-path=/var/log/kube-audit/audit.log -
--audit-log-format=json
Be šių trijų būtinų parametrų, yra daug papildomų nustatymų, susijusių su auditu: nuo žurnalo pasukimo iki webhook aprašymų. Žurnalo sukimosi parametrų pavyzdys:
-
--audit-log-maxbackup=10 -
--audit-log-maxsize=100 -
--audit-log-maxage=7
Tačiau plačiau apie juos nesigilinsime – visą informaciją rasite čia .
Kaip jau minėta, visi parametrai apraše nustatomi naudojant api serverio konfigūraciją (pagal numatytuosius nustatymus /etc/kubernetes/manifests/kube-apiserver.yaml), skyriuje command. Grįžkime prie 3 būtinų parametrų ir išanalizuokime juos:
-
audit-policy-file— kelias į YAML failą, kuriame aprašoma audito politika. Prie jo turinio grįšime vėliau, tačiau kol kas pažymėsiu, kad failą turi nuskaityti api serverio procesas. Todėl būtina jį sumontuoti konteinerio viduje, kuriam galite pridėti šį kodą į atitinkamas konfigūracijos dalis:volumeMounts: - mountPath: /etc/kubernetes/policies name: policies readOnly: true volumes: - hostPath: path: /etc/kubernetes/policies type: DirectoryOrCreate name: policies -
audit-log-path- kelias į žurnalo failą. Kelias taip pat turi būti pasiekiamas api serverio procesui, todėl jo montavimą aprašome taip pat:volumeMounts: - mountPath: /var/log/kube-audit name: logs readOnly: false volumes: - hostPath: path: /var/log/kube-audit type: DirectoryOrCreate name: logs -
audit-log-format— audito žurnalo formatas. Numatytasis yrajson, bet galimas ir pasenęs teksto formatas (legacy).
Audito politika
Dabar apie minėtą failą, aprašantį registravimo politiką. Pirmoji audito politikos samprata yra level, registravimo lygis. Jie yra tokie:
-
None- neprisijungti; -
Metadata— žurnalo užklausos metaduomenys: vartotojas, užklausos laikas, tikslinis išteklius (pod, vardų erdvė ir kt.), veiksmo tipas (veiksmažodis) ir kt.; -
Request— žurnalo metaduomenys ir užklausos turinys; -
RequestResponse— žurnalo metaduomenys, užklausos turinys ir atsakymo turinys.
Paskutiniai du lygiai (Request и RequestResponse) neregistruokite užklausų, kurios nepasiekė išteklių (prieiga prie vadinamųjų ne išteklių URL).
Taip pat visi prašymai yra vykdomi keli etapai:
-
RequestReceived— etapas, kai užklausą gauna duomenų tvarkytojas ir ji dar nebuvo perduota toliau procesorių grandinėje; -
ResponseStarted— siunčiamos atsakymo antraštės, bet prieš siunčiant atsakymo turinį. Sukurta ilgai vykdomoms užklausoms (pvz.,watch); -
ResponseComplete— atsakymo institucija išsiųsta, daugiau informacijos nebus siunčiama; -
Panic— įvykiai generuojami, kai aptinkama neįprasta situacija.
Jei norite praleisti bet kokius veiksmus, kuriuos galite naudoti omitStages.
Politikos faile galime aprašyti keletą skyrių su skirtingais registravimo lygiais. Bus pritaikyta pirmoji politikos apraše rasta atitikties taisyklė.
Kubelet demonas stebi manifesto pakeitimus naudodamas api serverio konfigūraciją ir, jei tokių aptinkama, iš naujo paleidžia konteinerį su api serveriu. Tačiau yra svarbi detalė: Tai nepaisys politikos failo pakeitimų. Atlikę politikos failo pakeitimus, turėsite rankiniu būdu iš naujo paleisti api serverį. Kadangi api serveris paleistas kaip , komanda kubectl delete neprivers jo paleisti iš naujo. Turėsite tai padaryti rankiniu būdu docker stop kube-masters, kur buvo pakeista audito politika:
docker stop $(docker ps | grep k8s_kube-apiserver | awk '{print $1}')Įgalinant auditą, svarbu tai atsiminti kube-apiserver apkrova didėja. Visų pirma didėja atminties sąnaudos užklausos kontekstui saugoti. Registravimas pradedamas tik išsiuntus atsakymo antraštę. Apkrova taip pat priklauso nuo audito politikos konfigūracijos.
Politikos pavyzdžiai
Pažvelkime į politikos failų struktūrą naudodami pavyzdžius.
Čia yra paprastas failas policyregistruoti viską lygiu Metadata:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata Politikoje galite nurodyti vartotojų sąrašą (Users и ServiceAccounts) ir vartotojų grupės. Pavyzdžiui, taip ignoruosime sistemos vartotojus, o visa kita registruosime lygiu 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: RequestTaip pat galima apibūdinti tikslus:
- vardų erdvės (
namespaces); - Veiksmažodžiai (veiksmažodžiai:
get,update,deleteir kiti); - ištekliai (ištekliai, Išvardyta toliau:
pod,configmapsir tt) ir išteklių grupės (apiGroups).
Pastaba! Išteklius ir išteklių grupes (API grupes, t. y. apiGroups), taip pat jų versijas, įdiegtas klasteryje, galima gauti naudojant komandas:
kubectl api-resources
kubectl api-versionsŠi audito politika pateikiama kaip geriausios praktikos pavyzdys :
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: MetadataKitas geras audito politikos pavyzdys yra .
Greitai reaguoti į audito įvykius galima apibūdinti webhook. Šis klausimas aptariamas , paliksiu tai už šio straipsnio ribų.
rezultatai
Straipsnyje apžvelgiami pagrindiniai Kubernetes klasterių saugos mechanizmai, leidžiantys kurti personalizuotas vartotojų paskyras, atskirti jų teises ir fiksuoti jų veiksmus. Tikiuosi, kad tai bus naudinga tiems, kurie teoriškai ar praktiškai susiduria su tokiomis problemomis. Taip pat rekomenduoju perskaityti kitos medžiagos „Kubernetes“ saugumo tema sąrašą, pateiktą „PS“ - galbūt tarp jų rasite reikiamos informacijos apie jums aktualias problemas.
PS
Taip pat skaitykite mūsų tinklaraštyje:
- «»;
- «»;
- «»;
- «»;
- «".
Šaltinis: www.habr.com
