Questa pagina fornisce le best practice per la pianificazione dei criteri di controllo dell'accesso basato sui ruoli (RBAC). Per scoprire come implementare il RBAC in Google Kubernetes Engine (GKE), consulta Configurare il controllo dell'accesso basato sui ruoli.
RBAC è una funzionalità di sicurezza di base di Kubernetes che consente di creare autorizzazioni granulari per gestire le azioni che utenti e carichi di lavoro possono eseguire sulle risorse dei cluster. In qualità di amministratore della piattaforma, crei ruoli RBAC e li associ a soggetti, ovvero utenti autenticati come account di servizio o gruppi Google.
Prima di iniziare
Assicurati di conoscere 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 può essere applicato a qualsiasi spazio dei nomi o all'intero cluster.
- Ruolo:un insieme di autorizzazioni limitato a un singolo spazio dei nomi.
- ClusterRoleBinding: associa un
ClusterRole
a un utente o a un gruppo per tutti gli spazi dei nomi del 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 un ClusterRole
. Ogni campo rules
in 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, consulta
Limitare l'accesso a istanze di risorse specifiche.
Dopo aver definito un ruolo, utilizza un RoleBinding
o un ClusterRoleBinding
per associarlo a un soggetto. Scegli il tipo di associazione in base a se vuoi concedere autorizzazioni in un singolo spazio dei nomi o in più spazi dei nomi.
Progettazione dei ruoli RBAC
Utilizza 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à. L'utilizzo del principio del privilegio minimo riduce il rischio di escalation dei privilegi qualora il cluster venga compromesso, nonché 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 i PersistentVolume o l'accesso create
per le richieste di firma del certificato. Per un elenco dei rischi, consulta
Kubernetes RBAC -escalation dei privilegi risks.
Evitare ruoli e gruppi predefiniti
Kubernetes crea un insieme di ClusterRole e ClusterRoleBindings predefiniti che puoi utilizzare per il rilevamento delle API e per abilitare la funzionalità dei componenti gestiti. Le autorizzazioni concesse da questi ruoli predefiniti possono essere ampie 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 predefiniti
e delle associazioni che Kubernetes crea, consulta
Ruoli predefiniti e associazioni di ruoli.
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 sulla 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 dal ruolo. |
system:unauthenticated |
Gruppo | Kubernetes assegna questo gruppo alle richieste del server dell'API per le quali non sono state fornite informazioni di autenticazione. L'associazione di un ruolo a questo gruppo concede a qualsiasi utente non autenticato le autorizzazioni concesse dal 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 è
molto diverso da L'associazione di un ruolo a questo gruppo concede a qualsiasi utente con un Account Google, inclusi tutti gli account Gmail, le autorizzazioni concesse dal ruolo. |
system:masters |
Gruppo | Per impostazione predefinita, Kubernetes assegna il ruolo 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 situazione di sicurezza del cluster. Ad esempio:
- L'associazione del ClusterRole
cluster-admin
predefinito al grupposystem:unauthenticated
consente a tutti gli utenti non autenticati di accedere a tutte le risorse del cluster (inclusi i secret). Queste associazioni con privilegi elevati sono scelti come target da attacchi come le campagne di malware di massa. - L'associazione di un ruolo personalizzato al gruppo
system:unauthenticated
conferisce 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
a nessun ruolo RBAC. - Non associare il gruppo
system:authenticated
a nessun ruolo RBAC. - Non associare l'utente
system:anonymous
a nessun ruolo RBAC. - Non associare il ruolo ClusterRole
cluster-admin
ai tuoi soggetti o a uno 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 gli agenti.
- Valuta i ruoli associati ai gruppi predefiniti prima di modificare i membri di questi gruppi.
Impedire l'utilizzo dei gruppi predefiniti
Puoi utilizzare l'interfaccia alla gcloud CLI per disattivare le associazioni RBAC non predefinite in un
cluster che fanno 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 le associazioni Kubernetes predefinite che fanno riferimento a questi gruppi. Questi flag richiedono GKE versione 1.30.1-gke.1283000 o successiva.
--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 diverse da quelle predefinite che fanno riferimento asystem:unauthenticated
esystem:anonymous
.
Rileva e rimuovi l'utilizzo di gruppi e ruoli predefiniti
Per verificare se i tuoi cluster fanno riferimento a questi utenti e gruppi nelle associazioni RBAC, attiva il livello standard della scansione della posizione di sicurezza di Kubernetes per i tuoi cluster o il tuo parco risorse in modo che GKE possa mostrare i risultati nella dashboard della posizione di sicurezza nella console Google Cloud. Per le istruzioni, consulta Abilitare il controllo della configurazione del carico di lavoro.
Le sezioni seguenti mostrano come trovare i RoleBinding o i ClusterRoleBindings specifici che fanno riferimento a utenti e gruppi predefiniti e come eliminare queste risorse.
ClusterRoleBindings
Elenca i nomi di eventuali ClusterRoleBinding con l'oggetto
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 dovrebbe elencare solo i seguenti ClusterRoleBindings:
Name ---- "system:basic-user" "system:discovery" "system:public-info-viewer"
Se l'output contiene associazioni non predefinite aggiuntive, svolgi i passaggi riportati di seguito per ogni associazione aggiuntiva. Se l'output non contiene associazioni diverse da quelle predefinite, salta i passaggi che seguono.
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 ruolo 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 stabilisci che le autorizzazioni nell'output sono sicure da concedere agli utenti o ai gruppi predefiniti, non sono necessarie ulteriori azioni. Se stabilisci che le autorizzazioni concesse dal collegamento non sono sicure, vai al passaggio successivo.
Elimina un'associazione non sicura 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 associazioni dei ruoli con l'oggetto
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, svolgi i seguenti passaggi per ogni associazione aggiuntiva. Se l'output è vuoto, salta i passaggi seguenti.
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 ruolo RoleBinding non predefinito.ROLE_BINDING_NAMESPACE
: il namespace 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 stabilisci che le autorizzazioni nell'output sono sicure da concedere agli utenti o ai gruppi predefiniti, non sono necessarie ulteriori azioni. Se stabilisci che le autorizzazioni concesse dal collegamento non sono sicure, vai al passaggio successivo.
Elimina un'associazione non sicura dal cluster:
kubectl delete rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE
Sostituisci quanto segue:
ROLE_BINDING_NAME
: il nome dell'associazione dei ruoli da eliminare.ROLE_BINDING_NAMESPACE
: lo spazio dei nomi del ruolo assegnati da RoleBinding da eliminare.
Definire le autorizzazioni di ambito a livello di spazio dei nomi
Utilizza le associazioni e i ruoli come segue, a seconda delle esigenze del tuo carico di lavoro o dell'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, specificando *
nel campo verbs
verranno concesse le autorizzazioni get
,
list
, watch
, patch
, update
, deletecollection
e delete
sulle risorse. La tabella seguente mostra alcuni esempi di come evitare i caratteri jolly nelle regole:
Consigliato | Non consigliato |
---|---|
- rules: apiGroups: ["apps","extensions"] resources: ["deployments"] verbs: ["get","list","watch"] Concedi i verbi |
- rules: apiGroups: ["*"] resources: ["deployments"] verbs: ["get","list","watch"] Concedi i verbi a |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["get", "list", "watch"] Concedi solo i verbi |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["*"] Concedi tutti i verbi, inclusi |
Utilizza regole separate per concedere l'accesso con privilegio minimo a risorse specifiche
Quando pianifichi le regole, prova i seguenti passaggi di alto livello per un design più efficiente delle regole con privilegi minimi in ogni ruolo:
- Crea una bozza di regole RBAC separate per ogni verbo su ogni risorsa a cui un soggetto deve accedere.
- Dopo aver creato la bozza delle regole, analizzale per verificare se più regole hanno lo stesso elenco
verbs
. Combina queste regole in un'unica regola. - Mantieni separate tutte le regole rimanenti.
Questo approccio consente di progettare regole più organizzate, in cui le regole che concedono gli stessi verbi a più risorse sono combinate e quelle che concedono verbi diversi alle risorse sono separate.
Ad esempio, se il tuo carico di lavoro richiede autorizzazioni di accesso per la risorsa deployments
, ma richiede list
e watch
per le risorse daemonsets
, devi utilizzare regole separate quando crei un ruolo. Quando leghi il ruolo RBAC al tuo workload, non potrai utilizzare watch
su deployments
.
Come altro esempio, se il tuo carico di lavoro ha bisogno di get
e watch
sia nella risorsa pods
sia nella risorsa daemonsets
, puoi combinarli in un'unica regola, perché il carico di lavoro ha bisogno degli stessi verbi in entrambe le risorse.
Nella tabella seguente, entrambi i modelli di regole funzionano, ma le regole divise 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"] Concedi i verbi sia ai deployment che ai DaemonSet. Un soggetto
che potrebbe non richiedere l'accesso |
- rules: apiGroups: ["apps"] resources: ["daemonsets", "deployments"] verbs: ["list", "watch"] Combina due regole perché il soggetto ha bisogno degli stessi verbi per
entrambe le risorse |
- rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] - rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["list", "watch"] Queste regole divise avrebbero lo stesso risultato della regola combinata, ma creerebbero un ingombro non necessario nel manifest del ruolo |
Limitare l'accesso a istanze di risorse specifiche
RBAC ti consente di utilizzare il campo resourceNames
nelle regole per limitare l'accesso a
una specifica istanza denominata 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
se possibile.
Consigliato | Non consigliato |
---|---|
- rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Limita il soggetto ad aggiornare solo il ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update"] L'oggetto può aggiornare il ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["list"] - rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Concede a |
- 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
con autorizzazioni bind
, escalate
,
create
, update
o patch
al gruppo API rbac.authorization.k8s.io
a account di servizio in qualsiasi spazio dei nomi. In particolare, escalate
e bind
possono consentire a un malintenzionato di aggirare i meccanismi di prevenzione della riassegnazione integrati nel RBAC.
Account di servizio Kubernetes
Crea un account di servizio Kubernetes per ogni carico di lavoro
Crea un account di servizio Kubernetes separato per ogni carico di lavoro. Associa un ruolo Role
o ClusterRole
con il privilegio minimo a quell'account di servizio.
Non utilizzare l'account di servizio predefinito
Kubernetes crea un account di servizio denominato default
in ogni spazio dei nomi. L'account di serviziodefault
viene assegnato automaticamente ai pod che non specificano esplicitamente un account di servizio nel file manifest. Evita di associare un Role
o un
ClusterRole
all'account di servizio default
. Kubernetes potrebbe assegnare l'account di servizio default
a un pod che non ha bisogno dell'accesso concesso in questi ruoli.
Non montare automaticamente i token degli account di servizio
Il campo automountServiceAccountToken
nella specifica del pod indica a Kubernetes di iniettare un token delle credenziali per un account di servizio Kubernetes nel pod. Il pod può utilizzare questo token per inviare richieste autenticate al
server API Kubernetes. Il valore predefinito per questo campo è true
.
In tutte le versioni di GKE, imposta automountServiceAccountToken=false
nella specifica del pod se i pod non devono comunicare con l'API server.
Preferisci i token temporanei rispetto a quelli basati su secret
Per impostazione predefinita, il processo kubelet sul nodo recupera un token dell'account di servizio di breve durata e con rotazione automatica per ogni pod. Kubelet monta questo token sul pod come volume proiettato, a meno che non imposti il campo automountServiceAccountToken
su false
nella specifica del pod. Tutte le chiamate all'API Kubernetes dal pod utilizzano questo token per autenticarti sul server API.
Se recuperi manualmente i token dell'account di servizio, evita di utilizzare i secret Kubernetes per archiviare il token. I token degli account di servizio basati su secret sono credenziali legacy che non scadono e non vengono ruotate automaticamente. Se hai bisogno di credenziali per gli account di servizio, utilizza l'API TokenRequest
per ottenere token di breve durata che vengono ruotati automaticamente.
Controlla continuamente le autorizzazioni RBAC
Rivedi regolarmente i ruoli e l'accesso RBAC per identificare potenziali percorsi di riassegnazione e regole ridondanti. Ad esempio, immagina una situazione in cui non elimini un RoleBinding
che lega un Role
con privilegi speciali a un utente eliminato. Se un malintenzionato crea un account utente nello spazio dei nomi con lo stesso nome dell'utente eliminato, verrà associato a quel Role
e erediterà lo stesso accesso. Le revisioni periodiche riducono al minimo questo rischio.
Riepilogo elenco di controllo
Passaggi successivi
- Leggi i consigli per il rafforzamento di GKE.
- Leggi le best practice di Kubernetes RBAC.
- Scopri le altre nostre best practice.
- Visualizzare manifest di esempio per i ruoli comuni del cluster