Isola i carichi di lavoro in pool di nodi dedicati
Questa pagina mostra come ridurre il rischio di attacchi di escalation dei privilegi nel tuo cluster configurando GKE su Azure per pianificare i carichi di lavoro su un pool di nodi dedicato separato dai carichi di lavoro gestiti con privilegi.
Panoramica
GKE sui cluster Azure utilizza carichi di lavoro con privilegi che gestiamo per abilitare funzionalità e caratteristiche specifiche di cluster, come la raccolta di metriche. A questi carichi di lavoro vengono concesse autorizzazioni speciali per essere eseguite correttamente nel cluster.
I carichi di lavoro di cui esegui il deployment nei tuoi 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 utente malintenzionato che esce da un container compromesso può utilizzare le credenziali del carico di lavoro con privilegi sul nodo per riassegnare i privilegi nel cluster.
Prevenzione dei gruppi di lavoro
La tua difesa principale dovrebbe essere le tue applicazioni. GKE su Azure offre varie funzionalità per proteggere i cluster e i pod. Nella maggior parte dei casi, consigliamo vivamente di utilizzare Policy Controller e le funzionalità di sicurezza del kernel per proteggere i carichi di lavoro. Per ulteriori consigli sulla sicurezza, consulta la Panoramica sulla sicurezza.
Evitare attacchi di escalation dei privilegi
Se vuoi un ulteriore livello di isolamento oltre ad altre misure di protezione, puoi utilizzare le incompatibilità dei nodi e l'affinità dei nodi per pianificare i tuoi carichi di lavoro su un pool di nodi dedicato.
Un'incompatibilità dei nodi indica a GKE su Azure di evitare la pianificazione dei carichi di lavoro senza una tolleranza corrispondente (come GKE sui carichi di lavoro gestiti da Azure) su quei nodi. L'affinità dei nodi sui tuoi carichi di lavoro indica a GKE su Azure di pianificare i pod sui nodi dedicati.
Limitazioni dell'isolamento dei nodi
- Gli aggressori possono comunque avviare attacchi DoS (Denial of Service) dal nodo compromesso.
- I nodi compromessi possono ancora leggere molte risorse, inclusi tutti i pod e gli spazi dei nomi nel cluster.
- I nodi compromessi possono accedere ai secret e alle credenziali utilizzate 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 bypassare i criteri di rete in uscita.
- Alcuni carichi di lavoro gestiti da GKE su Azure devono essere eseguiti su ogni nodo del cluster e sono configurati per tollerare tutte le incompatibilità.
- Se esegui il deployment di DaemonSet che hanno autorizzazioni elevate e possono tollerare qualsiasi incompatibilità, 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 carichi di lavoro:
- Controlla ed etichetta un pool di nodi per i tuoi carichi di lavoro.
- Aggiorna i carichi di lavoro con la tolleranza e la regola di affinità dei nodi corrispondenti.
Questa guida presuppone di iniziare con un pool di nodi nel tuo cluster. L'utilizzo dell'affinità dei nodi oltre alle incompatibilità dei nodi non è obbligatorio, ma lo consigliamo perché puoi beneficiare di un maggiore controllo sulla pianificazione.
Prima di iniziare
Per seguire i passaggi descritti in questa pagina, devi prima completare le seguenti operazioni:
- Crea un cluster.
- Crea un pool di nodi.
Scegli un nome per l'incompatibilità dei nodi e l'etichetta del nodo che vuoi utilizzare per i pool di nodi dedicati. In questo esempio utilizziamo
workloadType=untrusted
.
Controlla ed etichetta un pool di nodi per i carichi di lavoro
Crea un nuovo pool di nodi per i tuoi carichi di lavoro e applica un'incompatibilità dei nodi e un'etichetta dei nodi. Quando applichi un'incompatibilità o un'etichetta a livello di pool di nodi, tutti i nuovi nodi, come quelli creati con la scalabilità automatica, riceveranno automaticamente le incompatibilità e le etichette specificate.
Puoi anche aggiungere incompatibilità dei nodi ed etichette dei nodi ai pool di nodi esistenti. Se utilizzi l'effetto NoExecute
, GKE su Azure rimuove tutti i pod in esecuzione su quei nodi che non tollerano la nuova incompatibilità.
Per aggiungere un'incompatibilità e un'etichetta a un nuovo pool di nodi, esegui questo comando:
gcloud container azure 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 carichi di lavoro.CLUSTER_NAME
: il nome del tuo GKE sul cluster Azure.TAINT_KEY=TAINT_VALUE
: una coppia chiave-valore associata a unaTAINT_EFFECT
di pianificazione. Ad esempio,workloadType=untrusted
.TAINT_EFFECT
: uno dei seguenti valori effetto:NoSchedule
,PreferNoSchedule
oNoExecute
.NoExecute
offre una garanzia di rimozione migliore rispetto aNoSchedule
.LABEL_KEY
=LABEL_VALUE
: coppie chiave-valore per le etichette dei nodi, che corrispondono ai selettori specificati nei manifest del carico di lavoro.
Aggiungi una tolleranza e una regola di affinità dei nodi ai tuoi carichi di lavoro
Dopo l'incompatibilità con il pool di nodi dedicato, nessun carico di lavoro può eseguire la pianificazione su di esso a meno che non abbia una tolleranza corrispondente all'incompatibilità aggiunta. Aggiungi la tolleranza alla specifica per i carichi di lavoro per consentire la programmazione dei pod sul pool di nodi incompatibile.
Se hai etichettato il pool di nodi dedicato, puoi anche aggiungere una regola di affinità dei nodi per indicare a GKE su Azure di pianificare i tuoi carichi di lavoro solo su quel pool di nodi.
L'esempio seguente aggiunge una tolleranza per l'incompatibilità 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 incompatibilità che hai applicato al pool di nodi dedicato.TAINT_VALUE
: il valore di incompatibilità applicato al pool di nodi dedicato.LABEL_KEY
: la chiave di etichetta del nodo che hai applicato al pool di nodi dedicato.LABEL_VALUE
: il valore dell'etichetta del nodo che hai applicato al pool di nodi dedicato.
Quando aggiorni il deployment con kubectl apply
, GKE su Azure ricrea i pod interessati. La regola di affinità dei nodi forza i pod a collegarsi al pool di nodi dedicato che hai creato. La tolleranza consente di posizionare
solo i pod sui nodi.
Verificare che la separazione funzioni
Per verificare che la pianificazione funzioni correttamente, esegui il comando seguente 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 pool di nodi specifici a GKE sui carichi di lavoro gestiti da Azure solo aggiungendo l'incompatibilità
components.gke.io/gke-managed-components
. L'aggiunta di questa incompatibilità impedisce ai tuoi pod di pianificare su quei nodi, migliorando l'isolamento. - Quando crei nuovi pool di nodi, puoi impedire che la maggior parte di GKE su carichi di lavoro gestiti da Azure venga eseguito su quei nodi aggiungendo la tua incompatibilità a questi pool di nodi.
- Ogni volta che esegui il deployment di nuovi carichi di lavoro nel tuo cluster, ad esempio durante l'installazione di strumenti di terze parti, controlla le autorizzazioni richieste dai pod. Ove possibile, evita di eseguire il deployment di carichi di lavoro che usano autorizzazioni elevate per i nodi condivisi.