Best practice per RBAC in GKE


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 un ClusterRole 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 system:unauthenticated perché chiunque può creare un Account Google.

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 cluster-admin a questo gruppo per impostazione predefinita per abilitare la funzionalità di sistema.

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 gruppo system: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.

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
  1. Elenca i nomi di eventuali ClusterRoleBinding con il soggetto system:anonymous, system:unauthenticated o system: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.

  2. 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.

  3. 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
  1. Elenca lo spazio dei nomi e il nome di eventuali RoleBinding con il soggetto system:anonymous, system:unauthenticated o system: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.

  2. 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.

  3. 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 un RoleBinding.
  • Per concedere l'accesso alle risorse in più di uno spazio dei nomi, utilizza un ClusterRole con un RoleBinding per ogni spazio dei nomi.
  • Per concedere l'accesso alle risorse in ogni spazio dei nomi, utilizza un ClusterRole con un ClusterRoleBinding.

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 get, list e watch specificamente ai gruppi di API apps e extensions.

- rules:
    apiGroups: ["*"]
    resources: ["deployments"]
    verbs: ["get","list","watch"]

Concede i verbi a deployments in qualsiasi gruppo API.

- rules:
    apiGroups: ["apps", "extensions"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch"]

Concede solo i verbi get, list e watch ai deployment nei gruppi API apps e extensions.

- rules:
    apiGroups: ["apps", "extensions"]
    resources: ["deployments"]
    verbs: ["*"]

Concede tutti i verbi, inclusi patch o delete.

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:

  1. Crea regole RBAC separate per ogni verbo su ogni risorsa a cui un soggetto deve accedere.
  2. Dopo aver creato le regole, analizzale per verificare se più regole hanno lo stesso elenco verbs. Combina queste regole in un'unica regola.
  3. 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 get per i deployment e l'accesso watch e list per i DaemonSet. I soggetti non possono elencare i deployment.

- 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 list sugli oggetti deployments otterrebbe comunque l'accesso.

- rules:
    apiGroups: ["apps"]
    resources: ["daemonsets", "deployments"]
    verbs: ["list", "watch"]

Combina due regole perché il soggetto ha bisogno degli stessi verbi per le risorse daemonsets e deployments.

- 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 seccomp-high. Il soggetto non può aggiornare altri oggetti ConfigMap nello spazio dei nomi.

- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["update"]

Il soggetto può aggiornare il ConfigMap seccomp-high e qualsiasi altro ConfigMap nello spazio dei nomi.

- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["list"]
- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["seccomp-high"]
    verbs: ["update"]

Concede l'accesso list a tutti i ConfigMap nello spazio dei nomi, incluso seccomp-high. Limita l'accesso di update solo a ConfigMap seccomp-high. Le regole sono suddivise perché non puoi concedere list per le risorse denominate.

- rules:
    apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["update", "list"]

Concede l'accesso update per tutti i ConfigMap, insieme all'accesso list.

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.

Elenco di controllo di riepilogo

Passaggi successivi