Questa pagina mostra come ridurre il rischio di attacchi di escalation dei privilegi nel cluster indicando a Google Kubernetes Engine (GKE) di pianificare i carichi di lavoro in un pool di nodi separato e dedicato, lontano dai carichi di lavoro con privilegi gestiti da GKE. Devi utilizzare questo approccio solo se non puoi utilizzare GKE Sandbox. GKE Sandbox è l'approccio consigliato per l'isolamento dei nodi. GKE Sandbox offre anche altri vantaggi di hardening per i tuoi carichi di lavoro.
Questa pagina è rivolta agli esperti di sicurezza che richiedono un livello di isolamento sui carichi di lavoro, ma non possono utilizzare GKE Sandbox. Per scoprire di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei contenuti di Google Cloud , consulta Ruoli utente e attività comuni di GKE Enterprise.
Questa pagina si applica ai cluster Standard senza il provisioning automatico dei nodi. Per separare i carichi di lavoro nei cluster Autopilot e nei cluster Standard con il provisioning automatico dei nodi abilitato, consulta Configurare la separazione dei carichi di lavoro in GKE.
Panoramica
I cluster GKE utilizzano workload con privilegi gestiti da GKE 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 privilegiati gestiti da GKE significa che un utente malintenzionato che esce da un container compromesso può utilizzare le credenziali del carico di lavoro privilegiato sul nodo per aumentare i privilegi nel cluster.
Impedire l'uscita dai container
La tua difesa principale dovrebbero essere le applicazioni. GKE offre diverse funzionalità che puoi utilizzare per proteggere i tuoi cluster e pod. Nella maggior parte dei casi, consigliamo vivamente di utilizzare GKE Sandbox per isolare i tuoi workload. GKE Sandbox si basa sul progetto open source gVisor e implementa l'API del kernel Linux nello spazio utente. Ogni pod viene eseguito su un kernel dedicato che esegue il sandboxing delle applicazioni per impedire l'accesso a chiamate di sistema privilegiate nel kernel host. I carichi di lavoro in esecuzione in GKE Sandbox vengono pianificati automaticamente su nodi separati, isolati dagli altri carichi di lavoro.
Devi anche seguire i consigli riportati in Rafforzamento della sicurezza del cluster.
Evitare attacchi di escalation dei privilegi
Se non puoi utilizzare GKE Sandbox e vuoi un ulteriore livello di isolamento oltre ad altre misure di hardening, puoi utilizzare i taint dei nodi e l'affinità dei nodi per pianificare i carichi di lavoro su un pool di nodi dedicato. Un taint del nodo indica a GKE di evitare di pianificare i workload senza una tolleranza corrispondente (come i workload gestiti da GKE) su questi nodi. L'affinità dei nodi sui tuoi workload indica a GKE 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 workload 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 devono essere eseguiti su ogni nodo del cluster e sono configurati per tollerare tutti i taint.
- Se esegui il deployment di DaemonSet con privilegi elevati 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 carichi di lavoro, devi:
- Applica taint ed etichette a un pool di nodi per i tuoi carichi di lavoro.
- 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
Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:
- Attiva l'API Google Kubernetes Engine. Attiva l'API Google Kubernetes Engine
- Se vuoi utilizzare Google Cloud CLI per questa attività,
installala e poi
inizializzala. Se hai già installato gcloud CLI, scarica l'ultima versione eseguendo
gcloud components update
.
- Scegli un nome specifico per il taint del nodo e l'etichetta del nodo che vuoi utilizzare per i pool di nodi dedicati.
Contaminare ed etichettare un pool di nodi per i tuoi workload
Crea un nuovo pool di nodi per i tuoi carichi di lavoro 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 espelle tutti i pod in esecuzione su questi
nodi che non hanno una tolleranza per il nuovo taint.
Per l'isolamento dei workload, utilizza sempre il prefisso node-restriction.kubernetes.io/
per le etichette dei nodi e per i selettori corrispondenti nei manifest dei pod.
Questo prefisso impedisce a un malintenzionato di utilizzare le credenziali del nodo per impostare o
modificare le etichette che utilizzano questo prefisso. Per saperne di più, consulta la sezione
Isolamento/limitazione dei nodi
nella documentazione di Kubernetes.
Per aggiungere un'incompatibilità e un'etichetta a un nuovo pool di nodi, esegui questo comando:
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--node-taints=TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
--node-labels=node-restriction.kubernetes.io/LABEL_KEY=LABEL_VALUE
Sostituisci quanto segue:
POOL_NAME
: il nome del nuovo pool di nodi per i tuoi carichi di lavoro.CLUSTER_NAME
: il nome del tuo cluster GKE.TAINT_KEY=TAINT_VALUE
: una coppia chiave-valore associata a una pianificazioneTAINT_EFFECT
. Ad esempioworkloadType=untrusted
.TAINT_EFFECT
: uno dei seguenti valori dell'effetto:NoSchedule
,PreferNoSchedule
oNoExecute
.NoExecute
offre una migliore garanzia di sfratto rispetto aNoSchedule
.node-restriction.kubernetes.io/LABEL_KEY
=LABEL_VALUE
: coppie chiave-valore per le etichette dei nodi, che corrispondono ai selettori che specifichi nei manifest dei workload. Il prefissonode-restriction.kubernetes.io/
impedisce l'utilizzo delle credenziali del nodo per impostare queste coppie chiave-valore sui nodi.
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 la pianificazione di questi pod 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 di pianificare i carichi di lavoro solo su quelpool di nodil.
L'esempio seguente aggiunge una tolleranza per l'taint
workloadType=untrusted:NoExecute
e una regola di affinità nodo per l'etichetta
workloadType=untrusted
del nodo.
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: node-restriction.kubernetes.io/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 dell'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
ricrea i pod interessati. La regola di affinità dei nodi forza i pod nel
pool di nodil 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 pool di nodi specifici ai carichi di lavoro gestiti da GKE 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 l'esecuzione della maggior parte dei carichi di lavoro gestiti da GKE su questi nodi aggiungendo la tua incompatibilità 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
- Scopri di più su GKE Sandbox.
- Scopri di più su GKE Autopilot, che implementa per impostazione predefinita molte funzionalità di sicurezza di GKE.