Isolare i carichi di lavoro in pool di nodi dedicati

Questa pagina mostra come ridurre il rischio di attacchi di escalation dei privilegi nel cluster configurando GKE su AWS per pianificare i workload in un pool di nodi separato e dedicato, lontano dai workload gestiti con privilegi.

Panoramica

I cluster GKE su AWS utilizzano workload privilegiati che gestiamo per abilitare funzionalità specifiche del cluster, come la raccolta delle metriche. A questi carichi di lavoro vengono concesse autorizzazioni speciali per essere eseguiti correttamente nel cluster.

I carichi di lavoro di cui esegui il deployment sui nodi potrebbero essere compromessi da un'entità dannosa. L'esecuzione di questi carichi di lavoro insieme a carichi di lavoro di sistema con privilegi significa che un malintenzionato che esce da un container compromesso può utilizzare le credenziali del carico di lavoro con privilegi sul nodo per aumentare i privilegi nel cluster.

Prevenzione delle interruzioni del container

La tua difesa principale dovrebbero essere le applicazioni. GKE su AWS offre diverse funzionalità che puoi utilizzare per proteggere i tuoi cluster e pod. Nella maggior parte dei casi, consigliamo vivamente di utilizzare Policy Controller e le funzionalità di sicurezza del kernel per proteggere i tuoi carichi di lavoro. Per ulteriori consigli sulla sicurezza, consulta la Panoramica della sicurezza.

Evitare attacchi di escalation dei privilegi

Se vuoi un ulteriore livello di isolamento oltre ad altre misure di hardening, puoi utilizzare taint dei nodi e affinità dei nodi per pianificare i tuoi carichi di lavoro su un pool di nodi dedicato.

Un taint del nodo indica a GKE su AWS di evitare di pianificare i workload senza una tolleranza corrispondente (come i workload gestiti da GKE su AWS) su questi nodi. L'affinità dei nodi nei tuoi workload indica a GKE su AWS di pianificare i pod sui nodi dedicati.

Limitazioni dell'isolamento dei nodi

  • Gli autori degli attacchi possono comunque avviare attacchi denial of service (DoS) dal nodo compromesso.
  • I nodi compromessi possono comunque leggere molte risorse, inclusi tutti i pod e gli spazi dei nomi nel cluster.
  • I nodi compromessi possono accedere ai secret e alle credenziali utilizzati da ogni pod in esecuzione su quel nodo.
  • L'utilizzo di un pool di nodi separato per isolare i carichi di lavoro può influire sull'efficienza dei costi, sulla scalabilità automatica e sull'utilizzo delle risorse.
  • I nodi compromessi possono comunque ignorare i criteri di rete in uscita.
  • Alcuni carichi di lavoro gestiti da GKE su AWS devono essere eseguiti su ogni nodo del cluster e sono configurati per tollerare tutte le contaminazioni.
  • Se esegui il deployment di DaemonSet con autorizzazioni elevate e che possono tollerare qualsiasi taint, questi pod potrebbero essere un percorso per l'escalation dei privilegi da un nodo compromesso.

Come funziona l'isolamento dei nodi

Per implementare l'isolamento dei nodi per i tuoi workload, devi:

  1. Applica incompatibilità ed etichetta un pool di nodi per i tuoi carichi di lavoro.
  2. Aggiorna i tuoi carichi di lavoro con la regola di tolleranza e affinità del nodo corrispondente.

Questa guida presuppone che tu inizi con un pool di nodi nel cluster. L'utilizzo dell'affinità dei nodi in aggiunta ai taint dei nodi non è obbligatorio, ma lo consigliamo perché ti consente di avere un maggiore controllo sulla pianificazione.

Prima di iniziare

Per eseguire i passaggi descritti in questa pagina, completa prima le seguenti operazioni:

Contaminare ed etichettare un pool di nodi per i tuoi workload

Crea un nuovo pool di nodi per i tuoi workload e applica una taint del nodo e un'etichetta nodo. Quando applichi un taint o un'etichetta a livello di pool di nodi, tutti i nuovi nodi, ad esempio quelli creati tramite la scalabilità automatica, riceveranno automaticamente i taint e le etichette specificati.

Puoi anche aggiungere taint e etichette dei nodi ai pool di nodi esistenti. Se utilizzi l'effetto NoExecute, GKE su AWS espelle tutti i pod in esecuzione su questi nodi che non hanno una tolleranza per il nuovo taint.

Per aggiungere un'incompatibilità e un'etichetta a un nuovo pool di nodi, esegui questo comando:

gcloud container aws node-pools create POOL_NAME \
    --cluster CLUSTER_NAME \
    --node-taints TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
    --node-labels LABEL_KEY=LABEL_VALUE

Sostituisci quanto segue:

  • POOL_NAME: il nome del nuovo pool di nodi per i tuoi workload.
  • CLUSTER_NAME: il nome del tuo cluster GKE su AWS.
  • TAINT_KEY=TAINT_VALUE: una coppia chiave-valore associata a una pianificazione TAINT_EFFECT. Ad esempio workloadType=untrusted.
  • TAINT_EFFECT: uno dei seguenti valori dell'effetto: NoSchedule, PreferNoSchedule o NoExecute. NoExecute offre una migliore garanzia di sfratto rispetto a NoSchedule.
  • LABEL_KEY=LABEL_VALUE: coppie chiave-valore per le etichette dei nodi, che corrispondono ai selettori che specifichi nei manifest dei workload.

Aggiungere una tolleranza e una regola di affinità dei nodi ai workload

Dopo aver applicato l'incompatibilità al pool di nodi dedicato, nessun workload può essere pianificato al suo interno, a meno che non abbia una tolleranza corrispondente all'incompatibilità che hai aggiunto. Aggiungi la tolleranza alla specifica dei tuoi workload per consentire a questi pod di essere pianificati nel tuo pool di nodi con incompatibilità.

Se hai etichettato il pool di nodi dedicato, puoi anche aggiungere una regola di affinità dei nodi per indicare a GKE su AWS di pianificare i carichi di lavoro solo su quel pool di nodi.

L'esempio seguente aggiunge una tolleranza per il taint workloadType=untrusted:NoExecute e una regola di affinità nodo per l'etichetta del nodo workloadType=untrusted.

kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-app
  namespace: default
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      tolerations:
      - key: TAINT_KEY
        operator: Equal
        value: TAINT_VALUE
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: LABEL_KEY
                operator: In
                values:
                - "LABEL_VALUE"
      containers:
      - name: sleep
        image: ubuntu
        command: ["/bin/sleep", "inf"]

Sostituisci quanto segue:

  • TAINT_KEY: la chiave di taint che hai applicato al tuo pool di nodi dedicato.
  • TAINT_VALUE: il valore di taint che hai applicato al tuo pool di nodi dedicato.
  • LABEL_KEY: la chiave di etichetta del nodo che hai applicato al tuo pool di nodi dedicato.
  • LABEL_VALUE: il valore dell'etichetta del nodo che hai applicato al tuo pool di nodi dedicato.

Quando aggiorni il deployment con kubectl apply, GKE su AWS ricrea i pod interessati. La regola di affinità dei nodi forza i pod nel pool di nodi dedicato che hai creato. La tolleranza consente solo il posizionamento di questi pod sui nodi.

Verificare che la separazione funzioni

Per verificare che la pianificazione funzioni correttamente, esegui questo comando e controlla se i tuoi carichi di lavoro si trovano nel pool di nodi dedicato:

kubectl get pods -o=wide

Consigli e best practice

Dopo aver configurato l'isolamento dei nodi, ti consigliamo di procedere come segue:

  • Limita node pool specifici ai carichi di lavoro gestiti da GKE su AWS solo aggiungendo il taint components.gke.io/gke-managed-components. L'aggiunta di questa incompatibilità impedisce la pianificazione dei tuoi pod su questi nodi, migliorando l'isolamento.
  • Quando crei nuovi node pool, impedisci alla maggior parte dei carichi di lavoro gestiti da GKE su AWS di essere eseguiti su questi nodi aggiungendo il tuo taint a questi node pool.
  • Ogni volta che esegui il deployment di nuovi carichi di lavoro nel cluster, ad esempio quando installi strumenti di terze parti, controlla le autorizzazioni richieste dai pod. Se possibile, evita di eseguire il deployment di workload che utilizzano autorizzazioni elevate nei nodi condivisi.

Passaggi successivi