ABC Sekirite nan Kubernetes: Otantifikasyon, Otorizasyon, Odit

ABC Sekirite nan Kubernetes: Otantifikasyon, Otorizasyon, Odit

Pi bonè oswa pita, nan operasyon an nan nenpòt ki sistèm, pwoblèm nan nan sekirite rive: asire otantifikasyon, separasyon nan dwa, odit ak lòt travay. Deja kreye pou Kubernetes anpil solisyon, ki pèmèt ou reyalize konfòmite ak estanda menm nan anviwònman ki trè egzijan... Se menm materyèl la konsakre nan aspè debaz yo nan sekirite aplike nan mekanis yo bati nan K8s yo. Premye a tout, li pral itil pou moun ki kòmanse fè konesans ak Kubernetes - kòm yon pwen depa pou etidye pwoblèm ki gen rapò ak sekirite.

Otantifikasyon

Gen de kalite itilizatè nan Kubernetes:

  • Kont sèvis yo — kont jere pa Kubernetes API a;
  • Itilizatè yo — itilizatè "nòmal" jere pa sèvis ekstèn, endepandan.

Diferans prensipal ant kalite sa yo se ke pou Kont Sèvis gen objè espesyal nan API Kubernetes (yo rele sa - ServiceAccounts), ki mare nan yon espas non ak yon seri done otorizasyon ki estoke nan gwoup la nan objè ki nan kalite Sekrè. Itilizatè sa yo (Kont Sèvis) yo prensipalman gen entansyon jere dwa aksè nan API Kubernetes nan pwosesis k ap kouri nan gwoup Kubernetes la.

Itilizatè òdinè yo pa gen antre nan API Kubernetes: yo dwe jere pa mekanis ekstèn. Yo fèt pou moun oswa pwosesis k ap viv deyò gwoup la.

Chak demann API asosye ak swa yon Kont Sèvis, yon Itilizatè, oswa yo konsidere kòm anonim.

Done otantifikasyon itilizatè yo enkli:

  • D ' - non itilizatè (sansib majiskil!);
  • UID - yon kòd idantifikasyon itilizatè lizib nan machin ki "pi konsistan ak inik pase non itilizatè a";
  • Gwoup — lis gwoup itilizatè a fè pati;
  • siplemantè — lòt jaden ki ka itilize pa mekanis otorizasyon an.

Kubernetes ka itilize yon gwo kantite mekanis otantifikasyon: sètifika X509, tokens Bearer, prokurasyon otantifikasyon, HTTP Basic Auth. Sèvi ak mekanis sa yo, ou ka aplike yon gwo kantite rapid otorizasyon: soti nan yon fichye estatik ak modpas nan OpenID OAuth2.

Anplis, li posib pou itilize plizyè plan otorizasyon ansanm. Pa default, gwoup la itilize:

  • jeton kont sèvis - pou Kont Sèvis;
  • X509 - pou Itilizatè yo.

Kesyon an sou jere ServiceAccounts pi lwen pase sijè ki abòde lan atik sa a, men pou moun ki vle familyarize tèt yo ak pwoblèm sa a an plis detay, mwen rekòmande kòmanse ak paj dokiman ofisyèl yo. Nou pral pran yon gade pi pre nan pwoblèm nan ki jan sètifika X509 travay.

Sètifika pou itilizatè (X.509)

Fason klasik pou travay ak sètifika enplike:

  • jenerasyon kle:
    mkdir -p ~/mynewuser/.certs/
    openssl genrsa -out ~/.certs/mynewuser.key 2048
  • jenere yon demann sètifika:
    openssl req -new -key ~/.certs/mynewuser.key -out ~/.certs/mynewuser.csr -subj "/CN=mynewuser/O=company"
  • trete yon demann sètifika lè l sèvi avèk kle Kubernetes cluster CA, jwenn yon sètifika itilizatè (pou jwenn yon sètifika, ou dwe sèvi ak yon kont ki gen aksè a kle nan gwoup Kubernetes CA, ki pa default sitiye nan /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
  • kreye yon dosye konfigirasyon:
    • deskripsyon gwoup (presize adrès ak kote dosye sètifika CA a pou yon enstalasyon gwoup espesifik):
      kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.100.200:6443
    • oswa ki jan pa gen okennopsyon rekòmande - ou pa bezwen presize sètifika rasin lan (Lè sa a, kubectl pa pral tcheke kòrèkteman nan api-sèvè gwoup la):
      kubectl config set-cluster kubernetes  --insecure-skip-tls-verify=true --server=https://192.168.100.200:6443
    • ajoute yon itilizatè nan dosye konfigirasyon an:
      kubectl config set-credentials mynewuser --client-certificate=.certs/mynewuser.crt  --client-key=.certs/mynewuser.key
    • ajoute kontèks:
      kubectl config set-context mynewuser-context --cluster=kubernetes --namespace=target-namespace --user=mynewuser
    • plasman kontèks default:
      kubectl config use-context mynewuser-context

Apre manipilasyon ki anwo yo, nan dosye a .kube/config yon konfigirasyon tankou sa a pral kreye:

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

Pou fè li pi fasil transfere konfigirasyon an ant kont ak sèvè, li itil pou modifye valè kle sa yo:

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

Pou fè sa, ou ka kode dosye yo espesifye nan yo lè l sèvi avèk base64 epi anrejistre yo nan konfigirasyon an, ajoute sifiks nan non kle yo. -data, i.e. li te resevwa certificate-authority-data elatriye

Sètifika ak kubeadm

Avèk liberasyon an Kubernetes 1.15 travay ak sètifika vin pi fasil gras a vèsyon alfa sipò li yo nan kubeadm sèvis piblik. Pou egzanp, sa a se sa ki jenere yon dosye konfigirasyon ak kle itilizatè yo ta ka kounye a sanble:

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

NB: Obligatwa fè piblisite adrès ka jwenn nan api-sèvè konfigirasyon an, ki pa default sitiye nan /etc/kubernetes/manifests/kube-apiserver.yaml.

Konfigirasyon ki kapab lakòz la pral soti nan stdout. Li bezwen sove nan ~/.kube/config kont itilizatè oswa nan yon dosye ki espesifye nan yon varyab anviwònman an KUBECONFIG.

Fouye pi fon

Pou moun ki vle konprann pwoblèm yo dekri pi byen:

Otorizasyon

Kont otorize default la pa gen dwa pou opere sou gwoup la. Pou bay otorizasyon, Kubernetes aplike yon mekanis otorizasyon.

Anvan vèsyon 1.6, Kubernetes te itilize yon kalite otorizasyon ki rele ABAC (Kontwòl aksè ki baze sou atribi). Ou ka jwenn detay sou li nan dokiman ofisyèl yo. Apwòch sa a kounye a konsidere kòm eritaj, men ou ka toujou itilize li ansanm ak lòt kalite otantifikasyon.

Yo rele fason aktyèl (ak pi fleksib) pou divize dwa aksè nan yon gwoup RBAC (Wòl ki baze sou kontwòl aksè). Li te deklare stab depi vèsyon Kubernetes 1.8. RBAC aplike yon modèl dwa kote tout bagay ki pa klèman pèmèt yo entèdi.
Pou pèmèt RBAC, ou bezwen kòmanse Kubernetes api-sèvè ak paramèt la --authorization-mode=RBAC. Paramèt yo mete nan manifest la ak konfigirasyon api-sèvè a, ki pa default sitiye sou chemen an /etc/kubernetes/manifests/kube-apiserver.yaml, nan seksyon command. Sepandan, RBAC deja aktive pa default, kidonk gen plis chans ou pa ta dwe enkyete sou li: ou ka verifye sa a pa valè a. authorization-mode (nan deja mansyone kube-apiserver.yaml). By wout la, pami siyifikasyon li yo ka gen lòt kalite otorizasyon (node, webhook, always allow), men nou pral kite konsiderasyon yo deyò sijè ki abòde lan materyèl la.

By wout la, nou te deja pibliye yon atik ak yon deskripsyon jistis detaye sou prensip yo ak karakteristik nan travay ak RBAC, kidonk pi lwen mwen pral limite tèt mwen nan yon lis tou kout de baz yo ak egzanp.

Yo itilize antite API sa yo pou kontwole aksè nan Kubernetes atravè RBAC:

  • Role и ClusterRole — wòl ki sèvi pou dekri dwa aksè:
  • Role pèmèt ou dekri dwa nan yon espas non;
  • ClusterRole - nan gwoup la, ki gen ladan objè espesifik gwoup tankou nœuds, URL ki pa resous (sa vle di pa gen rapò ak resous Kubernetes - pou egzanp, /version, /logs, /api*);
  • RoleBinding и ClusterRoleBinding - itilize pou obligatwa Role и ClusterRole nan yon itilizatè, gwoup itilizatè oswa ServiceAccount.

Antite Wòl ak RoleBinding yo limite pa espas non, sa vle di. dwe nan menm espas non an. Sepandan, yon RoleBinding ka fè referans a yon ClusterRole, ki pèmèt ou kreye yon seri otorizasyon jenerik ak kontwole aksè lè l sèvi avèk yo.

Wòl yo dekri dwa lè l sèvi avèk seri règ ki genyen:

  • Gwoup API - gade dokiman ofisyèl yo pa apiGroups ak pwodiksyon kubectl api-resources;
  • resous (resous: pod, namespace, deployment ak sou sa.);
  • Vèb (vèb: set, update elatriye).
  • non resous (resourceNames) - pou ka a lè ou bezwen bay aksè a yon resous espesifik, epi yo pa nan tout resous nan kalite sa a.

Ou ka jwenn yon analiz pi detaye sou otorizasyon nan Kubernetes sou paj la dokiman ofisyèl yo. Olye de sa (oswa pito, anplis sa a), mwen pral bay egzanp ki ilistre travay li.

Egzanp antite RBAC

Senp Role, ki pèmèt ou jwenn yon lis ak estati gous epi kontwole yo nan espas non an 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"]

Egzanp ClusterRole, ki pèmèt ou jwenn yon lis ak estati gous yo epi kontwole yo nan tout gwoup la:

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

Egzanp RoleBinding, ki pèmèt itilizatè a mynewuser "li" gous nan namespace 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

Odit evènman

Schématikman, achitekti Kubernetes ka reprezante jan sa a:

ABC Sekirite nan Kubernetes: Otantifikasyon, Otorizasyon, Odit

Eleman kle Kubernetes ki responsab pou trete demann lan se api-sèvè. Tout operasyon sou gwoup la pase ladan l. Ou ka li plis sou mekanis entèn sa yo nan atik la "Kisa k ap pase nan Kubernetes lè ou kouri kubectl kouri?'.

Odit sistèm se yon karakteristik enteresan nan Kubernetes, ki enfim pa default. Li pèmèt ou konekte tout apèl nan API Kubernetes. Kòm ou ta ka devine, tout aksyon ki gen rapò ak siveyans ak chanje eta a nan gwoup la fèt atravè API sa a. Ou ka jwenn yon bon deskripsyon kapasite li yo (tankou nòmal) nan dokiman ofisyèl yo K8s. Apre sa, mwen pral eseye prezante sijè a nan lang ki pi senp.

Se konsa, pou pèmèt odit, nou bezwen pase twa paramèt obligatwa nan veso a nan api-sèvè, ki dekri an plis detay anba a:

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

Anplis twa paramèt nesesè sa yo, gen anpil lòt paramèt ki gen rapò ak odit: soti nan wotasyon boutèy demi lit rive nan deskripsyon webhook. Egzanp paramèt wotasyon boutèy demi lit:

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

Men, nou pa pral rete sou yo an plis detay - ou ka jwenn tout detay yo nan dokiman kube-apiserver.

Kòm deja mansyone, tout paramèt yo mete nan manifest la ak konfigirasyon api-sèvè a (pa default /etc/kubernetes/manifests/kube-apiserver.yaml), nan seksyon command. Ann retounen nan 3 paramèt obligatwa yo epi analize yo:

  1. audit-policy-file — chemen nan dosye YAML ki dekri règleman kontwòl kontab la. Nou pral retounen nan kontni li yo pita, men pou kounye a mwen pral sonje ke dosye a dwe lizib pa pwosesis la api-sèvè. Se poutèt sa, li nesesè pou monte li andedan veso a, pou sa ou ka ajoute kòd sa a nan seksyon ki apwopriye yo nan konfigirasyon an:
      volumeMounts:
        - mountPath: /etc/kubernetes/policies
          name: policies
          readOnly: true
      volumes:
      - hostPath:
          path: /etc/kubernetes/policies
          type: DirectoryOrCreate
        name: policies
  2. audit-log-path - chemen nan dosye a boutèy demi lit. Chemen an dwe aksesib tou nan pwosesis api-sèvè a, kidonk nou dekri aliye li nan menm fason an:
      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 - fòma jounal kontwòl kontab. Defo a se json, men fòma tèks eritaj la disponib tou (legacy).

Politik odit

Koulye a, sou dosye a mansyone ki dekri politik la antre. Premye konsèp nan politik kontwòl kontab se level, nivo antre. Yo jan sa a:

  • None - pa konekte;
  • Metadata — metadata demann log: itilizatè, tan demann, resous sib (gous, espas non, elatriye), kalite aksyon (vèb), elatriye;
  • Request — ouvri metadata ak kò demann;
  • RequestResponse — ouvri metadata, kò demann ak kò repons.

De dènye nivo yo (Request и RequestResponse) pa konekte demann ki pa t gen aksè a resous (aksè nan sa yo rele urls ki pa resous).

Epitou tout demann pase plizyè etap:

  • RequestReceived — etap la lè demann lan resevwa pa processeur a epi li poko transmèt plis sou chèn nan processeurs;
  • ResponseStarted — Tèt repons yo voye, men anvan yo voye kò repons lan. Jenere pou demann ki dire lontan (pa egzanp, watch);
  • ResponseComplete — yo te voye kò repons lan, yo pap voye plis enfòmasyon;
  • Panic — evènman yo pwodwi lè yo detekte yon sitiyasyon nòmal.

Pou sote nenpòt etap ou ka itilize omitStages.

Nan yon dosye politik, nou ka dekri plizyè seksyon ak diferan nivo anrejistreman. Premye règ matche yo jwenn nan deskripsyon politik la pral aplike.

Daemon kubelet la kontwole chanjman ki fèt nan manifest la ak konfigirasyon api-sèvè a epi, si yo detekte genyen, rekòmanse veso a ak api-sèvè. Men, gen yon detay enpòtan: chanjman nan dosye politik la pral inyore pa li. Apre w fin fè chanjman nan dosye politik la, w ap bezwen rekòmanse api-sèvè a manyèlman. Depi api-sèvè kòmanse kòm gous estatik, ekip kubectl delete pa pral lakòz li rekòmanse. Ou pral oblije fè li manyèlman docker stop sou kube-masters, kote yo te chanje règleman kontwòl kontab la:

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

Lè pèmèt odit, li enpòtan sonje sa chaj la sou kube-apiserver ogmante. An patikilye, konsomasyon memwa pou estoke kontèks demann ogmante. Logging kòmanse sèlman apre yo fin voye header repons lan. Chaj la tou depann de konfigirasyon politik kontwòl kontab la.

Egzanp politik yo

Ann gade nan estrikti a nan dosye politik lè l sèvi avèk egzanp.

Isit la se yon dosye senp policykonekte tout bagay nan nivo a Metadata:

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

Nan politik ou ka presize yon lis itilizatè yo (Users и ServiceAccounts) ak gwoup itilizatè yo. Pou egzanp, sa a se ki jan nou pral inyore itilizatè sistèm, men konekte tout lòt bagay nan nivo a 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

Li posib tou dekri objektif yo:

  • espas non (namespaces);
  • Vèb (vèb: get, update, delete ak lòt moun);
  • resous (resous, sètadi: pod, configmaps elatriye) ak gwoup resous (apiGroups).

Peye atansyon! Resous ak gwoup resous (gwoup API, sa vle di apiGroups), osi byen ke vèsyon yo enstale nan gwoup la, ka jwenn lè l sèvi avèk kòmandman yo:

kubectl api-resources
kubectl api-versions

Yo bay règleman kontwòl kontab sa yo kòm yon demonstrasyon de meyè pratik nan Alibaba Cloud dokiman:

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

Yon lòt bon egzanp politik odit se pwofil yo itilize nan GCE.

Pou byen vit reponn a evènman odit, li posib dekri webhook. Pwoblèm sa a kouvri nan dokiman ofisyèl yo, Mwen pral kite li deyò sijè ki abòde lan atik sa a.

Rezilta

Atik la bay yon apèsi sou mekanis sekirite debaz nan gwoup Kubernetes, ki pèmèt ou kreye kont itilizatè pèsonalize, separe dwa yo, epi anrejistre aksyon yo. Mwen espere ke li pral itil pou moun ki fè fas ak pwoblèm sa yo nan teyori oswa nan pratik. Mwen rekòmande tou pou li lis lòt materyèl sou sijè sekirite nan Kubernetes, ki bay nan "PS" - petèt nan mitan yo ou pral jwenn detay ki nesesè sou pwoblèm ki gen rapò ak ou.

PS

Li tou sou blog nou an:

Sous: www.habr.com

Add nouvo kòmantè