ABC за безбедност во Kubernetes: автентикација, овластување, ревизија
Порано или подоцна, во работењето на кој било систем, се поставува прашањето за безбедност: обезбедување автентикација, поделба на правата, ревизија и други задачи. Веќе создаден за Kubernetes многу решенија, кои ви овозможуваат да постигнете усогласеност со стандардите дури и во многу тешки средини... Истиот материјал е посветен на основните аспекти на безбедноста имплементирани во вградените механизми на K8s. Како прво, тоа ќе биде корисно за оние кои почнуваат да се запознаваат со Кубернетес - како почетна точка за проучување на прашања поврзани со безбедноста.
Автентикација
Постојат два типа на корисници во Kubernetes:
Сметки за услуги — сметки управувани од Kubernetes API;
Корисници — „нормални“ корисници управувани од надворешни, независни сервиси.
Главната разлика помеѓу овие типови е тоа што за сервисни сметки има специјални објекти во Kubernetes API (тие се нарекуваат така - ServiceAccounts), кои се врзани за именски простор и збир на податоци за авторизација складирани во кластерот во објекти од типот Secrets. Таквите корисници (Сметки на услуги) првенствено се наменети за управување со правата за пристап до Кубернетес API на процесите што се извршуваат во кластерот Кубернетес.
Обичните корисници немаат записи во Kubernetes API: тие мора да се управуваат со надворешни механизми. Тие се наменети за луѓе или процеси кои живеат надвор од кластерот.
Секое барање за API е поврзано или со сметка за услуга, со корисник или се смета за анонимно.
Податоците за автентикација на корисникот вклучуваат:
Корисничко име — корисничко име (чувствително на големи букви!);
UID - низа за идентификација на корисникот читлива од машина, која е „поконзистентна и единствена од корисничкото име“;
групи — список на групи на кои припаѓа корисникот;
дополнителен — дополнителни полиња што може да ги користи механизмот за овластување.
Kubernetes може да користи голем број механизми за автентикација: сертификати X509, токени на носител, прокси за автентикација, основна автентичност на HTTP. Користејќи ги овие механизми, можете да имплементирате голем број шеми за авторизација: од статична датотека со лозинки до OpenID OAuth2.
Покрај тоа, можно е да се користат неколку шеми за авторизација истовремено. Стандардно, кластерот користи:
токени за сервисни сметки - за сметки за услуги;
X509 - за корисници.
Прашањето за управување со сервисни сметки е надвор од опсегот на овој напис, но за оние кои сакаат подетално да се запознаат со ова прашање, препорачувам да започнете со официјални страници со документација. Ќе го разгледаме подетално прашањето како функционираат сертификатите X509.
Сертификати за корисници (X.509)
Класичниот начин на работа со сертификати вклучува:
обработка на барање за сертификат користејќи ги клучевите CA кластерот Kubernetes, добивање кориснички сертификат (за да добиете сертификат, мора да користите сметка што има пристап до клучот CA од кластерот Kubernetes, кој стандардно се наоѓа во /etc/kubernetes/pki/ca.key):
или како Немапрепорачана опција - не мора да го наведете root сертификатот (тогаш kubectl нема да ја провери исправноста на api-серверот на кластерот):
За полесно пренесување на конфигурацијата помеѓу сметките и серверите, корисно е да ги уредувате вредностите на следните клучеви:
certificate-authority
client-certificate
client-key
За да го направите ова, можете да ги шифрирате датотеките наведени во нив користејќи base64 и да ги регистрирате во конфигурацијата, додавајќи ја наставката на името на копчињата -data, т.е. откако примиле certificate-authority-data итн
Сертификати со kubeadm
Со ослободувањето Кубернес 1.15 работата со сертификати стана многу полесна благодарение на алфа верзијата на нејзината поддршка во kubeadm алатка. На пример, вака сега може да изгледа генерирањето конфигурациска датотека со кориснички клучеви:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200
NB: Задолжително огласи адреса може да се најде во конфигурацијата на api-серверот, кој стандардно се наоѓа во /etc/kubernetes/manifests/kube-apiserver.yaml.
Добиената конфигурација ќе биде излезна на stdout. Треба да се зачува во ~/.kube/config корисничка сметка или до датотека наведена во променлива на околината KUBECONFIG.
Копај подлабоко
За оние кои сакаат да ги разберат потемелно опишаните прашања:
посебен напис за работа со сертификати во официјалната документација на Кубернетес;
добра статија од Битнами, во која прашањето на сертификатите е допрено од практична перспектива.
Стандардната овластена сметка нема права да работи на кластерот. За да даде дозволи, Kubernetes имплементира механизам за авторизација.
Пред верзијата 1.6, Kubernetes користеше тип на авторизација наречен ABAC (Контрола на пристап базирана на атрибути). Детали за тоа може да се најдат во официјална документација. Овој пристап во моментов се смета за наследен, но сепак можете да го користите заедно со другите типови на автентикација.
Тековниот (и пофлексибилен) начин на поделба на правата за пристап до кластерот се нарекува RBAC (Контрола на пристап заснована на улоги). Тој е прогласен за стабилен уште од верзијата Кубернес 1.8. RBAC имплементира модел на права во кој се што не е експлицитно дозволено е забрането. За да се овозможи RBAC, треба да го стартувате Kubernetes api-серверот со параметарот --authorization-mode=RBAC. Параметрите се поставени во манифестот со конфигурацијата на api-серверот, кој стандардно се наоѓа по патеката /etc/kubernetes/manifests/kube-apiserver.yaml, во делот command. Сепак, RBAC веќе е стандардно овозможено, па најверојатно не треба да се грижите за тоа: можете да го потврдите ова со вредноста authorization-mode (во веќе споменатото kube-apiserver.yaml). Патем, меѓу неговите значења може да има и други видови на овластување (node, webhook, always allow), но нивното разгледување ќе го оставиме надвор од опсегот на материјалот.
Инаку, веќе објавивме статью со прилично детален опис на принципите и карактеристиките на работа со RBAC, па понатаму ќе се ограничам на краток список на основите и примерите.
Следниве API ентитети се користат за контрола на пристапот во Kubernetes преку RBAC:
Role и ClusterRole — улоги кои служат за опишување на правата за пристап:
Role ви овозможува да ги опишете правата во именскиот простор;
ClusterRole - во кластерот, вклучително и објекти специфични за кластерот, како што се јазли, адреси кои не се ресурси (т.е. не се поврзани со ресурсите на Кубернетес - на пример, /version, /logs, /api*);
RoleBinding и ClusterRoleBinding - се користи за врзување Role и ClusterRole на корисник, корисничка група или сервисна сметка.
Ентитетите Role и RoleBinding се ограничени со именски простор, т.е. мора да биде во истиот именски простор. Сепак, RoleBinding може да упатува на ClusterRole, што ви овозможува да креирате збир на генерички дозволи и да го контролирате пристапот користејќи ги.
Улогите ги опишуваат правата користејќи множества правила кои содржат:
ресурси (ресурси: pod, namespace, deployment и така натаму.);
Глаголи (глаголи: set, update итн.).
имиња на ресурси (resourceNames) - за случај кога треба да обезбедите пристап до одреден ресурс, а не до сите ресурси од овој тип.
Подетална анализа на овластувањето во Kubernetes може да се најде на страницата официјална документација. Наместо тоа (или подобро, во прилог на ова), ќе дадам примери кои ја илустрираат нејзината работа.
Примери на RBAC ентитети
Едноставно Role, што ви овозможува да добиете листа и статус на подлоги и да ги следите во именскиот простор target-namespace:
Пример ClusterRole, што ви овозможува да добиете список и статус на мешунки и да ги следите низ кластерот:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# секции "namespace" нет, так как ClusterRole задействует весь кластер
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Пример RoleBinding, што му овозможува на корисникот mynewuser „читај“ мешунки во именскиот простор 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
Ревизија на настанот
Шематски, архитектурата Кубернетес може да се претстави на следниов начин:
Клучната компонента на Kubernetes одговорна за обработка на барањата е api-сервер. Сите операции на кластерот минуваат низ него. Можете да прочитате повеќе за овие внатрешни механизми во статијата “Што се случува во Kubernetes кога го извршувате kubectl run?".
Системската ревизија е интересна карактеристика во Kubernetes, која е стандардно оневозможена. Ви овозможува да ги најавувате сите повици до Kubernetes API. Како што може да претпоставите, сите дејства поврзани со следење и менување на состојбата на кластерот се вршат преку овој API. Добар опис на неговите способности може (како и обично) да се најде во официјална документација K8s. Следно, ќе се обидам да ја претставам темата на поедноставен јазик.
Значи, за да се овозможи ревизија, треба да пренесеме три потребни параметри на контејнерот во api-серверот, кои се подетално опишани подолу:
Покрај овие три неопходни параметри, има многу дополнителни поставки поврзани со ревизија: од ротација на дневници до описи на веб-куки. Пример за параметри за ротација на дневникот:
--audit-log-maxbackup=10
--audit-log-maxsize=100
--audit-log-maxage=7
Но, ние нема да се задржиме на нив подетално - можете да ги најдете сите детали во кубе-аписервер документација.
Како што веќе споменавме, сите параметри се поставени во манифестот со конфигурацијата на api-серверот (стандардно /etc/kubernetes/manifests/kube-apiserver.yaml), во делот command. Да се вратиме на 3-те потребни параметри и да ги анализираме:
audit-policy-file — патека до датотеката YAML која ја опишува политиката за ревизија. Подоцна ќе се вратиме на неговата содржина, но засега ќе забележам дека датотеката мора да биде читлива со процесот на api-сервер. Затоа, неопходно е да го монтирате во контејнерот, за што можете да го додадете следниов код во соодветните делови од конфигурацијата:
audit-log-path — патека до датотеката за евиденција. Патеката, исто така, мора да биде достапна за процесот на api-сервер, така што го опишуваме неговото монтирање на ист начин:
audit-log-format — Формат на дневникот за ревизија. Стандардно е json, но исто така достапен е и наследниот формат на текст (legacy).
Политика за ревизија
Сега за споменатата датотека што ја опишува политиката за логирање. Првиот концепт на ревизорската политика е level, ниво на сеча. Тие се како што следува:
None - не се најавувај;
Metadata — метаподатоци за барање за евиденција: корисник, време на барање, целен ресурс (под, именски простор, итн.), тип на дејство (глагол) итн.;
Request — метаподатоци за евиденција и тело за барање;
RequestResponse — метаподатоци од дневник, тело на барање и тело за одговор.
Последните две нивоа (Request и RequestResponse) не евидентирај ги барањата кои не пристапувале до ресурси (пристап до таканаречените url-ови без ресурси).
Исто така, сите барања поминуваат неколку фази:
RequestReceived — фазата кога барањето е примено од процесорот и сè уште не е пренесено понатаму по синџирот на процесори;
ResponseStarted — Заглавјата на одговорот се испраќаат, но пред да се испрати телото за одговор. Создадени за долготрајни прашања (на пример, watch);
ResponseComplete — телото за одговор е испратено, нема да се испраќаат повеќе информации;
Panic — настаните се генерираат кога ќе се открие абнормална ситуација.
За да ги прескокнете сите чекори што можете да ги користите omitStages.
Во датотека со политика, можеме да опишеме неколку секции со различни нивоа на логирање. Ќе се примени првото правило за совпаѓање пронајдено во описот на политиката.
Демонот kubelet ги следи промените во манифестот со конфигурацијата на api-серверот и, доколку се открие такви, го рестартира контејнерот со api-сервер. Но, има важен детал: промените во датотеката со политики ќе бидат игнорирани од него. Откако ќе направите промени во датотеката со политики, ќе треба рачно да го рестартирате api-серверот. Бидејќи api-серверот е стартуван како статичен под, тим kubectl delete нема да предизвика рестартирање. Ќе треба да го направите тоа рачно docker stop на kube-master, каде што е променета ревизорската политика:
Кога овозможувате ревизија, важно е да го запомните тоа оптоварувањето на kube-apiserver се зголемува. Особено, потрошувачката на меморија за складирање на контекстот на барањето се зголемува. Пријавувањето започнува само откако ќе се испрати заглавието на одговорот. Оптоварувањето зависи и од конфигурацијата на политиката за ревизија.
Примери на политики
Ајде да ја погледнеме структурата на датотеките со политики користејќи примери.
Еве едноставна датотека policyда логираш сè на ниво Metadata:
Во политиката можете да наведете листа на корисници (Users и ServiceAccounts) и кориснички групи. На пример, вака ќе ги игнорираме корисниците на системот, но ќе регистрираме сè друго на ниво Request:
ресурси (ресурси, Како што следува: pod, configmaps итн.) и групи на ресурси (apiGroups).
Обрни внимание! Ресурсите и групите на ресурси (API групи, т.е. apiGroups), како и нивните верзии инсталирани во кластерот, може да се добијат со помош на командите:
За брзо реагирање на ревизорските настани, можно е опишете веб-кука. Ова прашање е опфатено во официјална документација, ќе го оставам надвор од опсегот на оваа статија.
Резултатите од
Статијата дава преглед на основните безбедносни механизми во кластерите на Kubernetes, кои ви дозволуваат да креирате персонализирани кориснички сметки, да ги одделите нивните права и да ги снимите нивните дејства. Се надевам дека ќе биде корисно за оние кои се соочуваат со вакви прашања во теорија или во пракса. Исто така, препорачувам да го прочитате списокот со други материјали на тема безбедност во Кубернетес, кој е даден во „ПС“ - можеби меѓу нив ќе ги најдете потребните детали за проблемите што се релевантни за вас.