Questa pagina fornisce le best practice per la pianificazione dei criteri di controllo dell'accesso basato sui ruoli (RBAC). Per scoprire come implementare RBAC in Google Kubernetes Engine (GKE), consulta Configurare il controllo dell'accesso basato sui ruoli. RBAC è una funzionalità di sicurezza di base in Kubernetes che consente di creare autorizzazioni granulari per gestire le azioni che utenti e carichi di lavoro possono eseguire sulle risorse nei cluster. Crea ruoli RBAC e collega questi ruoli a soggetti, che sono utenti autenticati come service account o Gruppi Google.
Questa pagina è rivolta a specialisti e operatori della sicurezza che pianificano e implementano le norme RBAC per la propria organizzazione. Per scoprire di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei contenuti, consulta Ruoli e attività comuni degli utenti GKE. Trusted Cloud by S3NS
Prima di leggere questa pagina, assicurati di avere familiarità con i seguenti concetti:
Per un elenco di controllo di queste indicazioni, consulta Riepilogo dell'elenco di controllo.
Come funziona RBAC
RBAC supporta i seguenti tipi di ruoli e associazioni:
- ClusterRole:un insieme di autorizzazioni che possono essere applicate a qualsiasi spazio dei nomi o all'intero cluster.
- Ruolo: un insieme di autorizzazioni limitate a un singolo spazio dei nomi.
- ClusterRoleBinding:associa un
ClusterRole
a un utente o a un gruppo per tutti gli spazi dei nomi nel cluster. - RoleBinding:associa un
Role
o unClusterRole
a un utente o a un gruppo all'interno di uno spazio dei nomi specifico.
Definisci le autorizzazioni come rules
in un Role
o in un ClusterRole
. Ogni campo rules
di un ruolo è costituito da un gruppo di API, dalle risorse API all'interno di quel gruppo di API e dai verbi (azioni) consentiti su queste risorse. Se vuoi, puoi
limitare i verbi a istanze denominate di risorse API utilizzando il campo resourceNames
. Per un esempio, vedi
Limitare l'accesso a istanze di risorse specifiche.
Dopo aver definito un ruolo, utilizzi un RoleBinding
o un ClusterRoleBinding
per associare
il ruolo a un soggetto. Scegli il tipo di binding in base al fatto che tu voglia
concedere autorizzazioni in un singolo spazio dei nomi o in più spazi dei nomi.
Progettazione dei ruoli RBAC
Utilizzare il principio del privilegio minimo
Quando si assegnano le autorizzazioni in un ruolo RBAC, utilizza il principio del privilegio minimo e concedi le autorizzazioni minime necessarie per eseguire un'attività. Utilizza il principio del privilegio minimo per ridurre il rischio di escalation dei privilegi qualora il cluster venga compromesso, nonché per ridurre la probabilità che un accesso eccessivo causi un incidente di sicurezza.
Quando progetti i ruoli, valuta attentamente i rischi comuni di escalation dei privilegi,
come i verbi escalate
o bind
, l'accesso create
per PersistentVolume o
l'accesso create
per le richieste di firma dei certificati. Per un elenco dei rischi, consulta
Kubernetes RBAC -escalation dei privilegi risks.
Evitare ruoli e gruppi predefiniti
Kubernetes crea un insieme di ClusterRole e ClusterRoleBinding predefiniti che puoi utilizzare per il rilevamento delle API e per abilitare la funzionalità dei componenti gestiti. Le autorizzazioni concesse da questi ruoli predefiniti potrebbero essere estese a seconda del ruolo. Kubernetes ha anche
un insieme di utenti e gruppi di utenti predefiniti, identificati dal prefisso system:
.
Per impostazione predefinita, Kubernetes e GKE associano automaticamente questi ruoli
ai gruppi predefiniti e a vari soggetti. Per un elenco completo dei ruoli
e delle associazioni predefiniti creati da Kubernetes, consulta
Ruoli e associazioni di ruoli predefiniti.
La seguente tabella descrive alcuni ruoli, utenti e gruppi predefiniti. Ti consigliamo di evitare di interagire con questi ruoli, utenti e gruppi, a meno che non li abbia valutati attentamente, perché l'interazione con queste risorse può avere conseguenze indesiderate per la postura di sicurezza del tuo cluster.
Nome | Tipo | Descrizione |
---|---|---|
cluster-admin |
ClusterRole | Concede a un soggetto l'autorizzazione a eseguire qualsiasi operazione su qualsiasi risorsa nel cluster. |
system:anonymous |
Utente | Kubernetes assegna questo utente alle richieste del server API per le quali non sono state fornite informazioni di autenticazione. L'associazione di un ruolo a questo utente concede a qualsiasi utente non autenticato le autorizzazioni concesse da quel ruolo. |
system:unauthenticated |
Gruppo | Kubernetes assegna questo gruppo alle richieste del server API per le quali non sono state fornite informazioni di autenticazione. Il binding di un ruolo a questo gruppo concede a qualsiasi utente non autenticato le autorizzazioni concesse da quel ruolo. |
system:authenticated |
Gruppo | GKE assegna questo gruppo alle richieste del server API effettuate
da qualsiasi utente che ha eseguito l'accesso con un Account Google, inclusi tutti
gli account Gmail. In pratica, non è
significativamente diverso da Il binding di un ruolo a questo gruppo concede a qualsiasi utente con un Account Google, inclusi tutti gli account Gmail, le autorizzazioni concesse da quel ruolo. |
system:masters |
Gruppo | Kubernetes assegna il ClusterRole Se a questo gruppo aggiungi dei soggetti, questi possono eseguire qualsiasi azione sulle risorse nel cluster. |
Se possibile, evita di creare associazioni che coinvolgano utenti, ruoli e gruppi predefiniti. Ciò può avere conseguenze impreviste sulla postura di sicurezza del cluster. Ad esempio:
- L'associazione del ClusterRole
cluster-admin
predefinito al grupposystem:unauthenticated
concede a tutti gli utenti non autenticati l'accesso a tutte le risorse del cluster (inclusi i secret). Questi binding con privilegi elevati sono presi di mira attivamente da attacchi come le campagne malware di massa. - Il binding di un ruolo personalizzato al gruppo
system:unauthenticated
concede agli utenti non autenticati le autorizzazioni concesse da quel ruolo.
Se possibile, segui queste linee guida:
- Non aggiungere i tuoi soggetti al gruppo
system:masters
. - Non associare il gruppo
system:unauthenticated
ad alcun ruolo RBAC. - Non associare il gruppo
system:authenticated
ad alcun ruolo RBAC. - Non associare l'utente
system:anonymous
ad alcun ruolo RBAC. - Non associare il ClusterRole
cluster-admin
ai tuoi soggetti o a nessuno degli utenti e dei gruppi predefiniti. Se la tua applicazione richiede molte autorizzazioni, determina le autorizzazioni esatte richieste e crea un ruolo specifico a questo scopo. - Valuta le autorizzazioni concesse da altri ruoli predefiniti prima di associare i soggetti.
- Valuta i ruoli associati ai gruppi predefiniti prima di modificare i membri di questi gruppi.
Impedire l'utilizzo dei gruppi predefiniti
Puoi utilizzare gcloud CLI per disattivare i binding RBAC non predefiniti in un
cluster che fa riferimento ai gruppi system:unauthenticated
e system:authenticated
o all'utente system:anonymous
. Utilizza uno o entrambi i seguenti flag
quando crei un nuovo cluster GKE o aggiorni un cluster esistente.
L'utilizzo di questi flag non disattiva i binding Kubernetes predefiniti che fanno riferimento a questi gruppi. Questi flag richiedono GKE versione 1.30.1-gke.1283000
o successive.
--no-enable-insecure-binding-system-authenticated
: disattiva le associazioni non predefinite che fanno riferimento asystem:authenticated
.--no-enable-insecure-binding-system-unauthenticated
: disattiva le associazioni non predefinite che fanno riferimento asystem:unauthenticated
esystem:anonymous
.
Rilevare e rimuovere l'utilizzo di ruoli e gruppi predefiniti
Per verificare se i tuoi cluster fanno riferimento a questi utenti e gruppi nei binding RBAC, attiva il livello standard di analisi della postura di sicurezza di Kubernetes per i tuoi cluster o la tua flotta in modo che GKE possa mostrarti i risultati nella dashboard della postura di sicurezza nella console Trusted Cloud . Per le istruzioni, vedi Abilitare l'audit della configurazione dei workload.
Le sezioni seguenti mostrano come trovare i RoleBinding o i ClusterRoleBinding specifici che fanno riferimento a utenti e gruppi predefiniti e come eliminare queste risorse.
ClusterRoleBindings
Elenca i nomi di eventuali ClusterRoleBinding con il soggetto
system:anonymous
,system:unauthenticated
osystem:authenticated
: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'
L'output deve elencare solo i seguenti ClusterRoleBinding:
Name ---- "system:basic-user" "system:discovery" "system:public-info-viewer"
Se l'output contiene altri binding non predefiniti, esegui le seguenti operazioni per ogni binding aggiuntivo. Se l'output non contiene binding non predefiniti, salta i passaggi successivi.
Elenca le autorizzazioni del ruolo associato all'associazione:
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'
Sostituisci
CLUSTER_ROLE_BINDING_NAME
con il nome del ClusterRoleBinding non predefinito.L'output è simile al seguente:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Se determini che le autorizzazioni nell'output sono sicure da concedere agli utenti o ai gruppi predefiniti, non sono necessarie ulteriori azioni. Se determini che le autorizzazioni concesse dal binding non sono sicure, procedi al passaggio successivo.
Elimina un binding non sicuro dal cluster:
kubectl delete clusterrolebinding CLUSTER_ROLE_BINDING_NAME
Sostituisci
CLUSTER_ROLE_BINDING_NAME
con il nome del ClusterRoleBinding da eliminare.
RoleBindings
Elenca lo spazio dei nomi e il nome di eventuali RoleBinding con il soggetto
system:anonymous
,system:unauthenticated
osystem:authenticated
: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'
Se il cluster è configurato correttamente, l'output dovrebbe essere vuoto. Se l'output contiene associazioni non predefinite, segui i passaggi per ogni associazione aggiuntiva. Se l'output è vuoto, salta i passaggi successivi.
Se conosci solo il nome del RoleBinding, puoi utilizzare il seguente comando per trovare i RoleBinding corrispondenti in tutti gli spazi dei nomi:
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'
Sostituisci
ROLE_BINDING_NAME
con il nome del RoleBinding non predefinito.Elenca le autorizzazioni del ruolo associato all'associazione:
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'
Sostituisci quanto segue:
ROLE_BINDING_NAME
: il nome del RoleBinding non predefinito.ROLE_BINDING_NAMESPACE
: lo spazio dei nomi del RoleBinding non predefinito.
L'output è simile al seguente:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Se determini che le autorizzazioni nell'output sono sicure da concedere agli utenti o ai gruppi predefiniti, non sono necessarie ulteriori azioni. Se determini che le autorizzazioni concesse dal binding non sono sicure, procedi al passaggio successivo.
Elimina un binding non sicuro dal cluster:
kubectl delete rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE
Sostituisci quanto segue:
ROLE_BINDING_NAME
: il nome di RoleBinding da eliminare.ROLE_BINDING_NAMESPACE
: lo spazio dei nomi del RoleBinding da eliminare.
Limitare le autorizzazioni all'ambito a livello di spazio dei nomi
Utilizza i binding e i ruoli nel seguente modo, a seconda delle esigenze del tuo workload o utente:
- Per concedere l'accesso alle risorse in uno spazio dei nomi, utilizza un
Role
con unRoleBinding
. - Per concedere l'accesso alle risorse in più di uno spazio dei nomi, utilizza un
ClusterRole
con unRoleBinding
per ogni spazio dei nomi. - Per concedere l'accesso alle risorse in ogni spazio dei nomi, utilizza un
ClusterRole
con unClusterRoleBinding
.
Concedi le autorizzazioni nel minor numero possibile di spazi dei nomi.
Non utilizzare caratteri jolly
Il carattere *
è un carattere jolly che si applica a tutto. Evita di utilizzare
caratteri jolly nelle regole. Specifica esplicitamente gruppi di API, risorse e verbi nelle
regole RBAC. Ad esempio, se specifichi *
nel campo verbs
, concedi le autorizzazioni get
, list
, watch
, patch
, update
, deletecollection
e delete
sulle risorse. La tabella seguente mostra esempi di come evitare i caratteri jolly nelle regole:
Consigliato | Non consigliato |
---|---|
- rules: apiGroups: ["apps","extensions"] resources: ["deployments"] verbs: ["get","list","watch"] Concede i verbi |
- rules: apiGroups: ["*"] resources: ["deployments"] verbs: ["get","list","watch"] Concede i verbi a |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["get", "list", "watch"] Concede solo i verbi |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["*"] Concede tutti i verbi, inclusi |
Utilizza regole separate per concedere l'accesso con privilegio minimo a risorse specifiche
Quando pianifichi le regole, prova a seguire i seguenti passaggi di alto livello per una progettazione più efficiente delle regole con privilegi minimi in ogni ruolo:
- Crea regole RBAC separate per ogni verbo su ogni risorsa a cui un soggetto deve accedere.
- Dopo aver creato le regole, analizzale per verificare se più regole
hanno lo stesso elenco
verbs
. Combina queste regole in un'unica regola. - Mantieni tutte le regole rimanenti separate tra loro.
Questo approccio consente di progettare regole più organizzate, in cui le regole che concedono gli stessi verbi a più risorse vengono combinate e le regole che concedono verbi diversi alle risorse sono separate.
Ad esempio, se il tuo carico di lavoro ha bisogno di autorizzazioni per la risorsa deployments
, ma ha bisogno di list
e watch
per le risorse daemonsets
, devi utilizzare regole separate quando crei un ruolo. Quando associ il ruolo RBAC al tuo
carico di lavoro, non potrà utilizzare watch
su deployments
.
Come altro esempio, se il tuo workload ha bisogno di get
e watch
sia sulla risorsa pods
sia sulla risorsa daemonsets
, puoi combinarli in un'unica
regola, perché il workload ha bisogno degli stessi verbi su entrambe le risorse.
Nella tabella seguente, entrambi i design delle regole funzionano, ma le regole suddivise limitano in modo più granulare l'accesso alle risorse in base alle tue esigenze:
Consigliato | Non consigliato |
---|---|
- rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["get"] - rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] Concede l'accesso |
- rules: apiGroups: ["apps"] resources: ["deployments", "daemonsets"] verbs: ["get","list","watch"] Concede i verbi sia ai deployment sia ai DaemonSet. Un soggetto
che potrebbe non richiedere l'accesso a |
- rules: apiGroups: ["apps"] resources: ["daemonsets", "deployments"] verbs: ["list", "watch"] Combina due regole perché il soggetto ha bisogno degli stessi verbi per
le risorse |
- rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] - rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["list", "watch"] Queste regole di suddivisione avrebbero lo stesso risultato della regola combinata, ma creerebbero un disordine non necessario nel manifest dei ruoli. |
Limitare l'accesso a istanze di risorse specifiche
RBAC ti consente di utilizzare il campo resourceNames
nelle regole per limitare l'accesso a un'istanza denominata specifica di una risorsa. Ad esempio, se stai scrivendo un ruolo RBAC
che deve update
il ConfigMap seccomp-high
e nient'altro, puoi
utilizzare resourceNames
per specificare solo quel ConfigMap. Utilizza resourceNames
quando possibile.
Consigliato | Non consigliato |
---|---|
- rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Limita l'oggetto all'aggiornamento del ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update"] Il soggetto può aggiornare il ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["list"] - rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Concede l'accesso |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update", "list"] Concede l'accesso |
Non consentire agli account di servizio di modificare le risorse RBAC
Non associare risorse Role
o ClusterRole
che dispongono di autorizzazioni bind
, escalate
,
create
, update
o patch
al gruppo di API rbac.authorization.k8s.io
agli account di servizio in qualsiasi spazio dei nomi. escalate
e bind
in
particolare possono consentire a un malintenzionato di bypassare i
meccanismi di prevenzione dell'escalation integrati in RBAC.
Service account Kubernetes
Crea un account di servizio Kubernetes per ogni workload
Crea un account di servizio Kubernetes separato per ogni workload. Associa un
Role
o ClusterRole
con privilegi minimi a questo account di servizio.
Non utilizzare il account di servizio predefinito
Kubernetes crea un account di servizio denominato default
in ogni spazio dei nomi. Il account di servizio
default
viene assegnato automaticamente ai pod che non
specificano esplicitamente un account di servizio nel manifest. Evita di associare un Role
o
ClusterRole
alaccount di serviziot default
. Kubernetes potrebbe assegnare il account di servizio default
a un pod che non ha bisogno dell'accesso concesso in questi ruoli.
Non montare automaticamente i token del account di servizio
Il campo automountServiceAccountToken
nella specifica del pod indica
a Kubernetes di inserire un token delle credenziali per unaccount di serviziot Kubernetes nel
pod. Il pod può utilizzare questo token per effettuare richieste autenticate al server API Kubernetes. Il valore predefinito di questo campo è true
.
In tutte le versioni di GKE, imposta automountServiceAccountToken=false
nella specifica del pod se i pod non devono comunicare con il server API.
Preferisci i token temporanei ai token basati su secret
Per impostazione predefinita, il processo kubelet sul nodo recupera un token dell'account di servizio a breve durata e a rotazione automatica per ogni pod. kubelet monta
questo token sul pod come
volume proiettato
a meno che tu non imposti il campo automountServiceAccountToken
su false
nella specifica del pod. Tutte le chiamate all'API Kubernetes dal pod utilizzano questo token per
l'autenticazione al server API.
Se recuperi manualmente i token del account di servizio, evita di utilizzare i secret Kubernetes
per archiviare il token. I token del account di servizio basati su secret sono credenziali legacy
che non scadono e non vengono ruotate automaticamente. Se hai bisogno
di credenziali per i service account, utilizza l'API
TokenRequest
per ottenere token di breve durata che vengono ruotati automaticamente.
Rivedere continuamente le autorizzazioni RBAC
Rivedi regolarmente i ruoli e l'accesso RBAC per identificare potenziali percorsi di escalation e regole ridondanti. Ad esempio, considera una situazione in cui non
elimini un RoleBinding
che associa un Role
con privilegi speciali a un utente
eliminato. Se un malintenzionato crea un account utente in quello spazio dei nomi con lo stesso nome
dell'utente eliminato, l'account sarà associato a quel Role
e erediterà lo stesso
accesso. Le revisioni periodiche riducono al minimo questo rischio.