In diesem Dokument werden Best Practices für die Planung Ihrer rollenbasierten Zugriffssteuerungsrichtlinien (Role-Based Access Control, RBAC) beschrieben. Informationen zum Implementieren von RBAC in Google Kubernetes Engine (GKE) finden Sie unter Rollenbasierte Zugriffssteuerung konfigurieren.
RBAC ist ein zentrales Sicherheitsfeature in Kubernetes, mit dem Sie detaillierte Berechtigungen erstellen können, um zu verwalten, welche Aktionen Nutzer und Arbeitslasten für Ressourcen in Ihren Clustern ausführen können. Als Plattformadministrator erstellen Sie RBAC-Rollen und binden diese Rollen an Subjekte, die authentifizierte Nutzer wie Dienstkonten oder Google Groups-Gruppen sind.
Hinweise
Machen Sie sich vor dem Lesen dieses Dokuments mit den folgenden Konzepten vertraut:
Eine Checkliste dieser Anleitung finden Sie unter Zusammenfassung der Checkliste.
Funktionsweise von RBAC
RBAC unterstützt die folgenden Typen von Rollen und Bindungen:
- ClusterRole: Eine Reihe von Berechtigungen, die auf einen beliebigen Namespace oder auf den gesamten Cluster angewendet werden können.
- Role: Eine Reihe von Berechtigungen, die auf einen einzelnen Namespace beschränkt sind.
- ClusterRoleBinding: Binden Sie eine
ClusterRole
an einen Nutzer oder eine Gruppe für alle Namespaces im Cluster. - RoleBinding: Binden Sie eine
Role
oder eineClusterRole
an einen Nutzer oder eine Gruppe in einem bestimmten Namespace.
Sie definieren Berechtigungen als rules
in einer Role
oder einer ClusterRole
. Jedes rules
-Feld in einer Rolle besteht aus einer API-Gruppe, den API-Ressourcen innerhalb dieser API-Gruppe und den für diese Ressourcen zulässigen Verben (Aktionen). Optional können Sie Verben mithilfe des Felds resourceNames
auf benannte Instanzen von API-Ressourcen beschränken. Ein Beispiel finden Sie unter Zugriff auf bestimmte Ressourceninstanzen beschränken.
Nachdem Sie eine Rolle definiert haben, verwenden Sie ein RoleBinding
oder ein ClusterRoleBinding
, um die Rolle an ein Subjekt zu binden. Wählen Sie den Bindungstyp aus, je nachdem, ob Sie Berechtigungen in einem einzelnen Namespace oder in mehreren Namespaces gewähren möchten.
RBAC-Rollendesign
Prinzip der geringsten Berechtigung anwenden
Verwenden Sie beim Zuweisen von Berechtigungen in einer RBAC-Rolle das Prinzip der geringsten Berechtigung und gewähren Sie die Mindestberechtigungen, die zum Ausführen einer Aufgabe erforderlich sind. Das Prinzip der geringsten Berechtigung reduziert das Risiko einer Rechteausweitung, wenn Ihr Cluster manipuliert wurde, und verringert die Wahrscheinlichkeit, dass übermäßiger Zugriff zu einem Sicherheitsvorfall führt.
Berücksichtigen Sie beim Entwerfen Ihrer Rollen sorgfältig die gängigen Risiken der Rechteausweitung, z. B. bei escalate
- oder bind
-Verben, create
-Zugriff für PersistentVolumes oder create
-Zugriff für Anfragen für Zertifikatsignaturen. Eine Liste der Risiken finden Sie unter Kubernetes RBAC – Risiken der Rechteausweitung.
Standardrollen und -gruppen vermeiden
Kubernetes erstellt eine Reihe von Standard-ClusterRoles und -ClusterRoleBindings, die Sie für die API-Erkennung verwenden können und zum Aktivieren der Funktionalität für verwaltete Komponenten. Die durch diese Standardrollen gewährten Berechtigungen können umfassend sein, abhängig von der Rolle. Kubernetes verfügt auch über eine Reihe von Standardnutzern und -nutzergruppen, die durch das Präfix system:
identifiziert werden.
Standardmäßig binden Kubernetes und GKE diese Rollen automatisch an die Standardgruppen und an verschiedene Subjekte. Eine vollständige Liste der von Kubernetes erstellten Standardrollen und -bindungen finden Sie unter Standardrollen und -rollenbindungen.
In der folgenden Tabelle werden einige Standardrollen, Nutzer und Gruppen beschrieben. Wir empfehlen, nur mit diesen Rollen, Nutzern und Gruppen zu interagieren, wenn Sie sie sorgfältig geprüft haben, da die Interaktion mit diesen Ressourcen unbeabsichtigte Auswirkungen auf den Sicherheitsstatus Ihres Clusters haben kann.
Name | Typ | Beschreibung |
---|---|---|
cluster-admin |
ClusterRole | Gewährt einem Subjekt die Berechtigung, beliebige Aktionen mit einer Ressource im Cluster auszuführen. |
system:anonymous |
Nutzer | Kubernetes weist diesen Nutzer API-Serveranfragen zu, für die keine Authentifizierungsinformationen angegeben wurden. Wenn Sie eine Rolle an diesen Nutzer binden, erhält jeder nicht authentifizierte Nutzer die durch diese Rolle gewährten Berechtigungen. |
system:unauthenticated |
Gruppe | Kubernetes weist diese Gruppe API-Serveranfragen zu, für die keine Authentifizierungsinformationen angegeben wurden. Wenn Sie eine Rolle an diese Gruppe binden, erhält jeder nicht authentifizierte Nutzer die durch diese Rolle gewährten Berechtigungen. |
system:authenticated |
Gruppe | GKE weist diese Gruppe API-Serveranfragen zu, die von Nutzern gestellt werden, die mit einem Google-Konto angemeldet sind, einschließlich aller Gmail-Konten. In der Praxis unterscheidet sich das nicht wesentlich von Wenn Sie eine Rolle an diese Gruppe binden, erhalten alle Nutzer mit einem Google-Konto, einschließlich aller Gmail-Konten, die mit dieser Rolle verbundenen Berechtigungen. |
system:masters |
Gruppe | Kubernetes weist dieser Gruppe standardmäßig die ClusterRole Wenn Sie dieser Gruppe eigene Subjekte hinzufügen, erhalten diese Subjekte Zugriff auf alle Ressourcen in Ihrem Cluster und können mit diesen alles tun. |
Erstellen Sie nach Möglichkeit keine Bindungen, die die Standardnutzer, -rollen und -gruppen involvieren. Das kann unerwünschte Auswirkungen auf die Sicherheit Ihres Clusters haben. Beispiel:
- Wenn Sie die Standard-ClusterRole
cluster-admin
an die Gruppesystem:unauthenticated
binden, erhalten alle nicht authentifizierten Nutzer Zugriff auf alle Ressourcen im Cluster, einschließlich Secrets. Auf diese sehr umfangreichen Bindungen werden aktiv Angriffe wie Massen-Malware-Kampagnen ausgerichtet. - Wenn Sie eine benutzerdefinierte Rolle an die Gruppe
system:unauthenticated
binden, erhalten nicht authentifizierte Nutzer die mit dieser Rolle gewährten Berechtigungen.
Beachten Sie dabei nach Möglichkeit die folgenden Richtlinien:
- Fügen Sie der Gruppe
system:masters
keine eigenen Subjekte hinzu. - Binden Sie die Gruppe
system:unauthenticated
nicht an RBAC-Rollen. - Binden Sie die Gruppe
system:authenticated
nicht an RBAC-Rollen. - Binden Sie den Nutzer
system:anonymous
nicht an RBAC-Rollen. - Binden Sie die ClusterRole
cluster-admin
nicht an Ihre eigenen Subjekte oder an einen der Standardnutzer und -gruppen. Wenn Ihre Anwendung viele Berechtigungen erfordert, ermitteln Sie die erforderlichen Berechtigungen und erstellen Sie eine spezifische Rolle für diesen Zweck. - Bewerten Sie die Berechtigungen anderer Standardrollen, bevor Sie Subjekte binden.
- Prüfen Sie die Rollen, die an Standardgruppen gebunden sind, bevor Sie die Mitglieder dieser Gruppen ändern.
Nutzung von Standardrollen und -gruppen erkennen und verhindern
Sie sollten Ihre Cluster evaluieren, um festzustellen, ob Sie den Nutzer system:anonymous
oder die Gruppen system:unauthenticated
oder system:authenticated
mithilfe von ClusterRoleBindings und RoleBindings gebunden haben.
ClusterRoleBindings
Liste der Namen aller ClusterRoleBindings mit dem Subjekt
system:anonymous
,system:unauthenticated
odersystem:authenticated
auflisten:kubectl get clusterrolebindings -o json \ | jq -r '["Name"], ["-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
Die Ausgabe sollte nur die folgenden ClusterRoleBindings auflisten:
Name ---- "system:basic-user" "system:discovery" "system:public-info-viewer"
Wenn die Ausgabe zusätzliche nicht standardmäßige Bindungen enthält, gehen Sie für jede zusätzliche Bindung so vor: Wenn Ihre Ausgabe keine nicht standardmäßigen Bindungen enthält, überspringen Sie die folgenden Schritte.
Listen Sie die Berechtigungen der Rolle auf, die mit der Bindung verknüpft ist:
kubectl get clusterrolebinding CLUSTER_ROLE_BINDING_NAME -o json \ | jq ' .roleRef.name +" " + .roleRef.kind' \ | sed -e 's/"//g' \ | xargs -l bash -c 'kubectl get $1 $0 -o yaml'
Ersetzen Sie
CLUSTER_ROLE_BINDING_NAME
durch den Namen des nicht standardmäßigen ClusterRoleBinding.Die Ausgabe sieht in etwa so aus:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Wenn Sie feststellen, dass die Berechtigungen in der Ausgabe den Standardnutzern oder -gruppen sicher erteilt werden können, sind keine weiteren Maßnahmen erforderlich. Wenn Sie feststellen, dass die durch die Bindung gewährten Berechtigungen nicht sicher sind, fahren Sie mit dem nächsten Schritt fort.
Löschen Sie eine unsichere Bindung aus Ihrem Cluster:
kubectl delete clusterrolebinding CLUSTER_ROLE_BINDING_NAME
Ersetzen Sie
CLUSTER_ROLE_BINDING_NAME
durch den Namen der zu löschenden ClusterRoleBinding.
RoleBindings
Geben Sie den Namespace und den Namen aller RoleBindings mit einem der Subjekte
system:anonymous
,system:unauthenticated
odersystem:authenticated
an:kubectl get rolebindings -A -o json \ | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
Wenn Ihr Cluster richtig konfiguriert ist, sollte die Ausgabe leer sein. Wenn die Ausgabe nicht standardmäßige Bindungen enthält, führen Sie für jede zusätzliche Bindung die folgenden Schritte aus. Wenn Ihre Ausgabe leer ist, überspringen Sie die folgenden Schritte.
Wenn Sie nur den Namen des RoleBinding kennen, können Sie mit dem folgenden Befehl übereinstimmende RoleBindings in den anderen Namespaces finden:
kubectl get rolebindings -A -o json \ | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(.metadata.name == "ROLE_BINDING_NAME") | [.metadata.namespace, .metadata.name]) | @tsv'
Ersetzen Sie
ROLE_BINDING_NAME
durch den Namen des nicht standardmäßigen RoleBinding.Listen Sie die Berechtigungen der Rolle auf, die mit der Bindung verknüpft ist:
kubectl get rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE -o json \ | jq ' .roleRef.name +" " + .roleRef.kind' \ | sed -e 's/"//g' \ | xargs -l bash -c 'kubectl get $1 $0 -o yaml --namespace ROLE_BINDING_NAMESPACE'
Ersetzen Sie Folgendes:
ROLE_BINDING_NAME
: Name der nicht standardmäßigen RoleBinding.ROLE_BINDING_NAMESPACE
: Namespace des nicht standardmäßigen RoleBinding.
Die Ausgabe sieht in etwa so aus:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Wenn Sie feststellen, dass die Berechtigungen in der Ausgabe den Standardnutzern oder -gruppen sicher erteilt werden können, sind keine weiteren Maßnahmen erforderlich. Wenn Sie feststellen, dass die durch die Bindung gewährten Berechtigungen nicht sicher sind, fahren Sie mit dem nächsten Schritt fort.
Löschen Sie eine unsichere Bindung aus Ihrem Cluster:
kubectl delete rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE
Ersetzen Sie Folgendes:
ROLE_BINDING_NAME
: Name des zu löschenden RoleBinding.ROLE_BINDING_NAMESPACE
: Namespace des zu löschenden RoleBinding.
Berechtigungen auf die Namespace-Ebene beschränken
Verwenden Sie Bindungen und Rollen je nach den Anforderungen Ihrer Arbeitslast oder Ihres Nutzers:
- Um Zugriff auf Ressourcen in einem Namespace zu gewähren, verwenden Sie eine
Role
mit einemRoleBinding
. - Um Zugriff auf Ressourcen in mehr als einem Namespace zu gewähren, verwenden Sie eine
ClusterRole
mit einemRoleBinding
für jeden Namespace. - Wenn Sie Zugriff auf Ressourcen in jedem Namespace gewähren möchten, verwenden Sie eine
ClusterRole
mit einemClusterRoleBinding
.
Gewähren Sie Berechtigungen in so wenigen Namespaces wie möglich.
Keine Platzhalter verwenden
Das Zeichen *
ist ein Platzhalter, der für alles gilt. Vermeiden Sie Platzhalter in den Regeln. Geben Sie in API-Regeln explizit API-Gruppen, Ressourcen und Verben an. Wenn Sie beispielsweise *
im Feld verbs
angeben, werden die Berechtigungen get
, list
, watch
, patch
, update
, deletecollection
und delete
für die Ressourcen gewährt. Die folgende Tabelle zeigt Beispiele für die Vermeidung von Platzhaltern in Ihren Regeln:
Empfohlen | Nicht empfohlen |
---|---|
- rules: apiGroups: ["apps","extensions"] resources: ["deployments"] verbs: ["get","list","watch"] Gewährt die Verben |
- rules: apiGroups: ["*"] resources: ["deployments"] verbs: ["get","list","watch"] Gewährt |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["get", "list", "watch"] Gewährt nur die Verben |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["*"] Gewährt alle Verben, einschließlich |
Separate Regeln verwenden, um Zugriff mit den geringstmöglichen Berechtigungen auf bestimmte Ressourcen zu gewähren
Führen Sie bei der Planung Ihrer Regeln die folgenden allgemeinen Schritte aus, um in jeder Rolle ein effizienteres Regeldesign mit den geringstmöglichen Berechtigungen zu erhalten:
- Entwerfen Sie separate RBAC-Regeln für jedes Verb für jede Ressource, auf die ein Subjekt zugreifen muss.
- Nachdem Sie die Regeln erstellt haben, analysieren Sie die Regeln, um zu prüfen, ob mehrere Regeln dieselbe
verbs
-Liste haben. Kombinieren Sie diese Regeln zu einer einzigen Regel. - Halten Sie alle übrigen Regeln voneinander getrennt.
Dieser Ansatz führt zu einem organisierteren Regeldesign, bei dem Regeln, die mehreren Ressourcen dieselben Verben zuweisen, kombiniert werden und Regeln, die Ressourcen verschiedene Verben zuweisen, getrennt werden.
Wenn Ihre Arbeitslast beispielsweise Berechtigungen für die Ressource deployments
benötigt, aber list
und watch
für die daemonsets
-Ressourcen benötigt, sollten Sie beim Erstellen einer Rolle separate Regeln verwenden. Wenn Sie die RBAC-Rolle an Ihre Arbeitslast binden, kann watch
nicht für deployments
verwendet werden.
Ein weiteres Beispiel: Wenn Ihre Arbeitslast get
und watch
für die Ressource pods
und die Ressource daemonsets
benötigt, können Sie diese in einer einzigen Regel kombinieren, da die Arbeitslast für beide Ressourcen die gleichen Verben benötigt.
In der folgenden Tabelle funktionieren beide Regeldesigns, aber die aufgeteilten Regeln beschränken den Ressourcenzugriff genauer entsprechend Ihren Anforderungen:
Empfohlen | Nicht empfohlen |
---|---|
- rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["get"] - rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] Gewährt |
- rules: apiGroups: ["apps"] resources: ["deployments", "daemonsets"] verbs: ["get","list","watch"] Gewährt die Verben sowohl für Deployments als auch für DaemonSets. Ein Subjekt, das möglicherweise keinen |
- rules: apiGroups: ["apps"] resources: ["daemonsets", "deployments"] verbs: ["list", "watch"] Kombiniert zwei Regeln, da das Subjekt dieselben Verben für die Ressourcen |
- rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] - rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["list", "watch"] Diese aufgeteilten Regeln haben dasselbe Ergebnis wie die kombinierte Regel, machen Ihr Rollenmanifest aber unnötig umständlich. |
Zugriff auf bestimmte Ressourceninstanzen beschränken
Mit RBAC können Sie das Feld resourceNames
in Ihren Regeln verwenden, um den Zugriff auf eine bestimmte benannte Instanz einer Ressource zu beschränken. Wenn Sie beispielsweise eine RBAC-Rolle schreiben, die ein update
für die ConfigMap seccomp-high
durchführen muss und nichts anderes benötigt, können Sie resourceNames
verwenden, um nur diese ConfigMap anzugeben. Verwenden Sie nach Möglichkeit immer resourceNames
.
Empfohlen | Nicht empfohlen |
---|---|
- rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Schränkt das Subjekt ein, sodass nur die ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update"] Das Subjekt kann die ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["list"] - rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Gewährt |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update", "list"] Gewährt |
Nicht zulassen, dass Dienstkonten RBAC-Ressourcen ändern
Binden Sie keine Role
- oder ClusterRole
-Ressourcen mit den Berechtigungen bind
, escalate
, create
, update
oder patch
für die API-Gruppe rbac.authorization.k8s.io
an Dienstkonten in einem beliebigen Namespace. Insbesondere escalate
und bind
können es einem Angreifer ermöglichen, die in RBAC integrierten Methoden zur Eskalationsverhinderung zu umgehen.
Kubernetes-Dienstkonten
Kubernetes-Dienstkonto für jede Arbeitslast erstellen
Erstellen Sie ein separates Kubernetes-Dienstkonto für jede Arbeitslast. Binden Sie eine Role
oder ClusterRole
mit geringstmöglichen Berechtigungen an dieses Dienstkonto.
Nicht das Standarddienstkonto verwenden
Kubernetes erstellt in jedem Namespace ein Dienstkonto mit dem Namen default
. Das Dienstkonto default
wird automatisch Pods zugewiesen, die im Manifest nicht explizit ein Dienstkonto angeben. Vermeiden Sie die Bindung einer Role
oder ClusterRole
an das Dienstkonto default
. Kubernetes weist das Dienstkonto default
möglicherweise einem Pod zu, der den Zugriff in diesen Rollen nicht benötigt.
Dienstkonto-Tokens nicht automatisch bereitstellen
Das Feld automountServiceAccountToken
in der Pod-Spezifikation weist Kubernetes an, ein Anmeldedatentoken für ein Kubernetes-Dienstkonto in den Pod einzufügen. Der Pod kann mit diesem Token authentifizierte Anfragen an den Kubernetes API-Server senden. Der Standardwert für dieses Feld ist true
.
Legen Sie in allen GKE-Versionen automountServiceAccountToken=false
in der Pod-Spezifikation fest, wenn Ihre Pods nicht mit dem API-Server kommunizieren müssen.
Sitzungsspezifische Tokens gegenüber secret-basierten Tokens bevorzugen
Standardmäßig ruft der Kubelet-Prozess auf dem Knoten pro Pod ein kurzlebiges, automatisch rotierendes Dienstkontotoken ab. Kubelet stellt dieses Token als projiziertes Volume auf dem Pod bereit, es sei denn, Sie legen das Feld automountServiceAccountToken
in der Pod-Spezifikation auf false
fest. Alle Aufrufe der Kubernetes API vom Pod aus verwenden dieses Token, um sich beim API-Server zu authentifizieren.
Wenn Sie Dienstkonto-Tokens manuell abrufen, sollten Sie keine Kubernetes-Secrets zum Speichern des Tokens verwenden. Secret-basierte Dienstkonto-Tokens sind Legacy-Anmeldedaten, die nicht ablaufen und nicht automatisch rotiert werden. Wenn Sie Anmeldedaten für Dienstkonten benötigen, verwenden Sie die TokenRequest
API, um kurzlebige Tokens abzurufen, die automatisch rotiert werden.
RBAC-Berechtigungen kontinuierlich prüfen
Prüfen Sie Ihre RBAC-Rollen und den Zugriff regelmäßig, um potenzielle Eskalationspfade und redundante Regeln zu identifizieren. Beispiel: Sie löschen nicht das RoleBinding
, das eine Role
mit speziellen Berechtigungen an einen gelöschten Nutzer bindet. Wenn ein Angreifer nun in diesem Namespace ein Nutzerkonto mit dem Namen des gelöschten Nutzers erstellt, ist er an diese Role
gebunden und übernimmt ihren Zugriff. Regelmäßige Überprüfungen minimieren dieses Risiko.
Zusammenfassung der Checkliste
Nächste Schritte
- Hinweis zum Härten von Google Kubernetes Engine
- Good Practices für Kubernetes RBAC
- Weitere Best Practices
- Beispielmanifeste für gängige Clusterrollen ansehen