Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come proteggere l'accesso ai contenitori alle risorse per i carichi di lavoro del servizio Azure Kubernetes usando gli spazi dei nomi utente, AppArmor e le funzionalità di sicurezza Linux predefinite di Seccomp .
Panoramica della sicurezza dell'accesso ai contenitori
Allo stesso modo in cui è necessario concedere agli utenti o ai gruppi i privilegi minimi necessari, è anche necessario limitare i contenitori solo alle azioni e ai processi necessari. Per ridurre al minimo il rischio di attacco, evitare di configurare applicazioni e contenitori che richiedono privilegi di escalation o accesso radice.
È possibile usare contesti di sicurezza dei pod Kubernetes integrati per definire altre autorizzazioni, ad esempio utente o gruppo da eseguire, le funzionalità Linux da esporre o impostare allowPrivilegeEscalation: false nel manifesto del pod. Per altre procedure consigliate, vedere Proteggere l'accesso dei pod alle risorse.
Per migliorare l'isolamento dell'host e ridurre lo spostamento laterale in Linux, è possibile usare gli spazi dei nomi utente. Per un controllo ancora più granulare delle azioni dei contenitori, è possibile usare funzionalità di sicurezza predefinite di Linux, come AppArmor e seccomp. Queste funzionalità consentono di limitare le azioni che i contenitori possono eseguire definendo le funzionalità di sicurezza linux a livello di nodo e implementandole tramite un manifesto del pod.
Le funzionalità di sicurezza Linux predefinite sono disponibili solo nei nodi e nei pod Linux.
Note
Attualmente, gli ambienti Kubernetes non sono sicuri per l'utilizzo multi-tenant ostile. Altre funzionalità di sicurezza, ad esempio Microsoft Defender per contenitori, AppArmor, seccomp, spazi dei nomi utente, ammissione di sicurezza dei pod o Kubernetes Role-Based controllo di accesso (RBAC) per i nodi, bloccano in modo efficiente gli exploit.
Per una vera sicurezza quando si eseguono carichi di lavoro multi-tenant ostili, considerare attendibile solo un hypervisor. Il dominio di sicurezza per Kubernetes diventa l'intero cluster, non un singolo nodo.
Per questi tipi di carichi di lavoro multi-tenant ostili è consigliabile usare cluster fisicamente isolati.
Prerequisiti per gli spazi dei nomi utente
- Un cluster del servizio Azure Kubernetes pre-esistente. Se non si ha un cluster, crearne uno usando l'interfaccia della riga di comando di Azure, Azure PowerShello il portale di Azure.
- Versione minima di Kubernetes 1.33 per il piano di controllo e i nodi di lavoro. Se non si usa Kubernetes versione 1.33 o successiva, è necessario aggiornare la versione di Kubernetes.
- Nodi di lavoro che eseguono Azure Linux 3.0 o Ubuntu 24.04 per assicurarsi di soddisfare i requisiti di stack minimi per abilitare gli spazi dei nomi utente. Se è necessario aggiornare la versione del sistema operativo, vedere Aggiornare la versione del sistema operativo.
Limitazioni per gli spazi dei nomi utente
- La funzionalità degli spazi dei nomi utente è per il kernel Linux e non è supportata per i pool di nodi Windows.
- Per eventuali altre limitazioni, vedere la documentazione di Kubernetes per gli spazi dei nomi utente .
Panoramica dei namespace utente
Per impostazione predefinita, i pod Linux vengono eseguiti usando diversi spazi dei nomi: uno spazio dei nomi di rete per isolare l'identità di rete e uno spazio dei nomi PID per isolare i processi. Uno spazio dei nomi utente (user_namespace) isola gli utenti all'interno del contenitore dagli utenti dell'host. Limita anche l'ambito delle funzionalità e le interazioni del pod con il resto del sistema.
Gli UID e i GID all'interno del contenitore vengono mappati negli utenti senza privilegi sull'host, quindi tutte le interazioni con il resto dell'host avvengono come quelle UID e GID senza privilegi. Ad esempio, la radice all'interno del contenitore (UID 0) può essere mappata nell'utente 65536 sull'host. Kubernetes crea il mapping per garantire che non si sovrapponga ad altri pod usando spazi dei nomi utente nel sistema.
L'implementazione di Kubernetes presenta alcuni vantaggi chiave. Per altre informazioni, vedere la documentazione relativa agli spazi dei nomi utente di Kubernetes.
Abilitare gli spazi dei nomi utente
Creare un file denominato
mypod.yamle copiarlo nel manifesto seguente. Per usare gli spazi dei nomi utente, YAML deve avere il campohostUsers: false.apiVersion: v1 kind: Pod metadata: name: userns spec: hostUsers: false containers: - name: shell command: ["sleep", "infinity"] image: debianDistribuire l'applicazione usando il comando
kubectl applye specificare il nome del manifesto YAML.kubectl apply -f mypod.yamlControllare lo stato dei pod distribuiti usando il comando
kubectl get pods.kubectl get podsAccedere al pod usando il comando
kubectl exec.kubectl exec -ti userns -- bashAll'interno del pod, controllare
/proc/self/uid_maputilizzando il comando seguente:cat /proc/self/uid_mapL'output deve avere 65536 nell'ultima colonna. Per esempio:
0 833617920 65536Questo output indica che l'utente root all'interno del contenitore (UID 0) è mappato all'utente 65536 sul host.
Vulnerabilità ed esposizioni comuni (CVE) attenuate dagli spazi dei nomi degli utenti
La tabella seguente illustra alcune vulnerabilità ed esposizioni comuni (CVE) parzialmente o completamente attenuate tramite user_namespaces:
| CVE | Punteggio di gravità | Livello di gravità |
|---|---|---|
| CVE-2019-5736 | 8.6 | High |
| CVE 2024-21262 | 8.6 | High |
| CVE 2022-0492 | 7,8 | High |
| CVE-2021-25741 | 8.1 / 8.8 | Alto/Alto |
| CVE-2017-1002101 | 9.6 / 8.8 | Critico/Alto |
Tenere presente che questo elenco non è esaustivo. Per altre informazioni, vedere Kubernetes v1.33: spazi dei nomi utente abilitati per impostazione predefinita.
Prerequisiti di AppArmor
- Un cluster del servizio Azure Kubernetes pre-esistente. Se non si ha un cluster, crearne uno usando l'interfaccia della riga di comando di Azure, Azure PowerShello il portale di Azure.
Note
Azure Linux 3.0 supporta AppArmor a partire dal rilascio VHD del 7 novembre 2025.
Panoramica di AppArmor
Per limitare le azioni del contenitore, è possibile usare il modulo di sicurezza del kernel AppArmor Linux. AppArmor è disponibile come parte del sistema operativo (OS) del nodo AKS sottostante di Azure Kubernetes Service ed è abilitato di default. È possibile creare profili AppArmor che limitano le azioni di lettura, scrittura o esecuzione o funzioni di sistema come il montaggio di file system. I profili AppArmor predefiniti limitano l'accesso a vari percorsi /proc e /sys e consentono di isolare logicamente i contenitori dal nodo sottostante. AppArmor funziona non solo per i pod Kubernetes ma per qualsiasi applicazione in esecuzione su Linux.
Note
Prima di Kubernetes v1.30, AppArmor è stato specificato tramite annotazioni. A partire dalla versione 1.30, il campo securityContext viene utilizzato per specificare AppArmor nella specifica del pod. Per altre informazioni, vedere la documentazione di Kubernetes AppArmor.
Proteggere i pod con AppArmor
È possibile specificare i profili AppArmor a livello di pod o contenitore. Il profilo AppArmor del contenitore ha la precedenza sul profilo AppArmor del pod. In assenza di parametri specificati, il contenitore viene eseguito senza restrizioni. Per altre informazioni sui profili AppArmor, vedere la documentazione relativa alla protezione di un pod con AppArmor Kubernetes.
Configurare un profilo AppArmor personalizzato
Nell'esempio seguente viene creato un profilo che impedisce la scrittura nei file all'interno di un contenitore.
Connettersi tramite SSH a un nodo del servizio Azure Kubernetes.
Creare un file denominato deny-write.profile e incollarlo nel contenuto seguente:
#include <tunables/global> profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { #include <abstractions/base> file, # Deny all file writes. deny /** w, }Caricare il profilo AppArmor nel nodo.
# This example assumes that node names match host names, and are reachable via SSH. NODES=($( kubectl get node -o jsonpath='{.items[*].status.addresses[?(.type == "Hostname")].address}' )) for NODE in ${NODES[*]}; do ssh $NODE 'sudo apparmor_parser -q <<EOF #include <tunables/global> profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { #include <abstractions/base> file, # Deny all file writes. deny /** w, } EOF' done
Distribuire un pod con il profilo AppArmor personalizzato
Distribuire un pod "Hello AppArmor" con il profilo deny-write.
apiVersion: v1 kind: Pod metadata: name: hello-apparmor spec: securityContext: appArmorProfile: type: Localhost localhostProfile: k8s-apparmor-example-deny-write containers: - name: hello image: busybox:1.28 command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]Applicare il manifesto del pod usando il
kubectl applycomando .kubectl apply -f hello-apparmor.yamlAccedere al pod e verificare che il contenitore sia in esecuzione con il profilo AppArmor.
kubectl exec hello-apparmor -- cat /proc/1/attr/currentL'output dovrebbe mostrare il profilo AppArmor in uso. Per esempio:
k8s-apparmor-example-deny-write (enforce)
Prerequisiti di Seccomp
- Un cluster del servizio Azure Kubernetes pre-esistente. Se non si ha un cluster, crearne uno usando l'interfaccia della riga di comando di Azure, Azure PowerShello il portale di Azure.
- È necessario registrare il
KubeletDefaultSeccompProfilePreviewflag di funzionalità per usare i profili seccomp predefiniti nei pool di nodi.
Registrare il flag di funzionalità KubeletDefaultSeccompProfilePreview
Importante
Le funzionalità di anteprima del servizio Azure Kubernetes sono disponibili in modalità self-service e con consenso esplicito. Le anteprime vengono fornite "così come sono" e "come disponibili" e sono escluse dai contratti di servizio e dalla garanzia limitata. Le anteprime del servizio Azure Kubernetes sono parzialmente coperte dal supporto clienti con la massima diligenza possibile. Di conseguenza, queste funzionalità non sono destinate all'uso in ambienti di produzione. Per altre informazioni, vedere gli articoli di supporto seguenti:
Registrare il flag della funzionalità
KubeletDefaultSeccompProfilePreviewusando il comandoaz feature register.az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"Sono necessari alcuni minuti per visualizzare lo stato Registered.
Verificare lo stato della registrazione usando il comando
az feature show.az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"Quando lo stato riflette Registrato, aggiornare la registrazione del provider di risorse Microsoft.ContainerService usando il comando
az provider register.az provider register --namespace Microsoft.ContainerService
Limitazioni di Seccomp
- AKS supporta solo i profili seccomp predefiniti (
RuntimeDefaulteUnconfined). I profili seccomp personalizzati non sono supportati. -
SeccompDefaultnon è un parametro supportato per i pool di nodi Windows.
Panoramica dei profili seccomp predefiniti (anteprima)
Mentre AppArmor funziona per qualsiasi applicazione Linux, seccomp (o secure computing) funziona a livello di processo. Seccomp è anche un modulo di sicurezza kernel Linux. Il containerd runtime usato dai nodi del servizio Azure Kubernetes fornisce il supporto nativo per seccomp. Con seccomp, è possibile limitare le chiamate di sistema di un contenitore. Seccomp stabilisce un ulteriore livello di protezione da vulnerabilità comuni delle chiamate di sistema sfruttate da attori malintenzionati e consente di specificare un profilo predefinito per tutti i carichi di lavoro nel nodo.
È possibile applicare profili seccomp predefiniti usando configurazioni di nodo personalizzate durante la creazione di un nuovo pool di nodi Linux. AKS supporta i valori RuntimeDefault e Unconfined. Alcuni carichi di lavoro potrebbero richiedere un numero inferiore di restrizioni per le chiamate di sistema rispetto ad altri. Ciò significa che possono ritrovarsi in errore durante il runtime con il profilo RuntimeDefault. Per attenuare un errore di questo tipo, è possibile specificare il profilo Unconfined. Se il carico di lavoro richiede un profilo personalizzato, vedere Configurare un profilo seccomp personalizzato.
Limitare le chiamate di sistema dei contenitori con seccomp
-
Seguire la procedura per applicare un profilo seccomp nella configurazione di kubelet specificando
"seccompDefault": "RuntimeDefault". - Connettersi all'host.
- Verificare che la configurazione sia stata applicata ai nodi.
Risolvere gli errori del carico di lavoro con seccomp
Quando SeccompDefault è abilitata, il profilo seccomp predefinito del runtime del contenitore viene usato per tutti i carichi di lavoro pianificati nel nodo, il che può causare errori nei carichi di lavoro a causa di chiamate di sistema bloccate. Se si verifica un errore del carico di lavoro, è possibile che vengano visualizzati errori come:
- Il carico di lavoro si interrompe in modo imprevisto dopo l'abilitazione della funzionalità, con l'errore "autorizzazione negata".
- I messaggi di errore seccomp possono essere visualizzati anche in auditd o syslog sostituendo SCMP_ACT_ERRNO con SCMP_ACT_LOG nel profilo predefinito.
Se si verificano questi errori, è consigliabile modificare il profilo seccomp in Unconfined.
Unconfined non applica restrizioni alle chiamate di sistema, consentendo l'esecuzione di tutte le chiamate di sistema.
Panoramica dei profili seccomp personalizzati
Con un profilo seccomp personalizzato, è possibile avere un controllo più granulare sulle chiamate di sistema limitate per i contenitori. È possibile creare profili seccomp personalizzati in base a:
- Uso dei filtri per specificare le azioni da consentire o negare.
- Annotazione all'interno di un manifesto YAML del pod da associare al filtro seccomp.
Note
Per informazioni sulla risoluzione dei problemi del profilo seccomp, vedere Risolvere i problemi di configurazione del profilo seccomp nel servizio Azure Kubernetes.
Configurare un profilo seccomp personalizzato
Per una dimostrazione di seccomp in azione, creare un filtro che impedisce di cambiare le autorizzazioni su un file.
Connettersi tramite SSH a un nodo del servizio Azure Kubernetes.
Creare un filtro seccomp denominato /var/lib/kubelet/seccomp/prevent-chmod.
Copiare e incollare il contenuto seguente:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "chmod", "action": "SCMP_ACT_ERRNO" }, { "name": "fchmodat", "action": "SCMP_ACT_ERRNO" }, { "name": "chmodat", "action": "SCMP_ACT_ERRNO" } ] }Nella versione 1.19 e successive è necessario configurare:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "names": ["chmod","fchmodat","chmodat"], "action": "SCMP_ACT_ERRNO" } ] }Dal computer locale creare un manifesto pod denominato aks-seccomp.yaml e incollare il contenuto seguente. Questo manifesto definisce un'annotazione per
seccomp.security.alpha.kubernetes.ioe fa riferimento al filtro prevent-chmod esistente.apiVersion: v1 kind: Pod metadata: name: chmod-prevented annotations: seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod spec: containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: NeverNella versione 1.19 e successive è necessario configurare:
apiVersion: v1 kind: Pod metadata: name: chmod-prevented spec: securityContext: seccompProfile: type: Localhost localhostProfile: prevent-chmod containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: NeverDistribuire il pod di esempio usando il
kubectl applycomando :kubectl apply -f ./aks-seccomp.yamlVisualizzare lo stato del pod usando il
kubectl get podscomando .kubectl get podsNell'output, dovresti vedere che il pod segnala un errore. Come illustrato nell'output di esempio, il filtro seccomp impedisce l'esecuzione del comando
chmod:NAME READY STATUS RESTARTS AGE chmod-prevented 0/1 Error 0 7s
Opzioni del profilo di sicurezza Seccomp
I profili di sicurezza Seccomp sono un set consentito o limitato di syscall definite. La maggior parte dei runtime di contenitori ha un profilo seccomp predefinito simile se non uguale a quello usato da Docker. Per ulteriori informazioni sui profili disponibili, consultare i profili seccomp predefiniti di Docker o containerd.
AKS utilizza il profilo seccomp predefinito di containerd per RuntimeDefault quando configuri seccomp usando la configurazione del nodo personalizzata.
Syscall significativi bloccati dal profilo predefinito
Sia Docker che containerd gestiscono gli elenchi di chiamate di sistema (syscall) sicure. Quando vengono apportate modifiche a Docker e containerd, AKS aggiorna la configurazione predefinita in modo che corrisponda. Gli aggiornamenti a questo elenco potrebbero causare un errore del carico di lavoro. Per gli aggiornamenti delle versioni, vedere Note sulla versione del servizio Azure Kubernetes.
La tabella seguente elenca le chiamate di sistema significative effettivamente bloccate perché non incluse nella lista di autorizzazione. Questo elenco non è esaustivo. Se il carico di lavoro richiede una delle chiamate di sistema bloccate, non usare il profilo seccomp RuntimeDefault.
| Syscall bloccato | Descrizione |
|---|---|
acct |
Chiamata di sistema di contabilità, che potrebbe consentire ai contenitori di disabilitare i propri limiti di risorse o i conteggi processi. Gestito anche da CAP_SYS_PACCT. |
add_key |
Impedire ai contenitori di usare il keyring del kernel, che non è spazio dei nomi. |
bpf |
Negare il caricamento di programmi bpf potenzialmente persistenti nel kernel, già controllato da CAP_SYS_ADMIN. |
clock_adjtime |
L'ora e la data non sono spazi dei nomi. Gestito anche da CAP_SYS_TIME. |
clock_settime |
L'ora e la data non sono spazi dei nomi. Gestito anche da CAP_SYS_TIME. |
clone |
Negare la clonazione di nuovi spazi dei nomi. Anche gestito da flag CAP_SYS_ADMIN for CLONE_*, ad eccezione di CLONE_NEWUSER. |
create_module |
Nega manipolazione e funzioni sui moduli del kernel. Obsoleto. Gestito anche da CAP_SYS_MODULE. |
delete_module |
Nega manipolazione e funzioni sui moduli del kernel. Gestito anche da CAP_SYS_MODULE. |
finit_module |
Nega manipolazione e funzioni sui moduli del kernel. Gestito anche da CAP_SYS_MODULE. |
get_kernel_syms |
Nega il recupero dei simboli del kernel e del modulo esportati. Obsoleto. |
get_mempolicy |
Syscall che modifica le impostazioni di memoria del kernel e NUMA. Già controllato da CAP_SYS_NICE. |
init_module |
Nega manipolazione e funzioni sui moduli del kernel. Gestito anche da CAP_SYS_MODULE. |
ioperm |
Impedire ai contenitori di modificare i livelli dei privilegi di I/O del kernel. Già controllato da CAP_SYS_RAWIO. |
iopl |
Impedire ai contenitori di modificare i livelli dei privilegi di I/O del kernel. Già controllato da CAP_SYS_RAWIO. |
kcmp |
Limitare le funzionalità di ispezione dei processi, già bloccate eliminando CAP_SYS_PTRACE. |
kexec_file_load |
Famiglia syscall di kexec_load che fa la stessa cosa, argomenti leggermente diversi. Gestito anche da CAP_SYS_BOOT. |
kexec_load |
Negare il caricamento di un nuovo kernel per un'esecuzione successiva. Gestito anche da CAP_SYS_BOOT. |
keyctl |
Impedire ai contenitori di usare il keyring del kernel, che non è spazio dei nomi. |
lookup_dcookie |
Traccia/profilatura syscall, che potrebbe causare perdite di informazioni sull'host. Gestito anche da CAP_SYS_ADMIN. |
mbind |
Syscall che modifica le impostazioni di memoria del kernel e NUMA. Già controllato da CAP_SYS_NICE. |
mount |
Negare montaggio, già gestito da CAP_SYS_ADMIN. |
move_pages |
Syscall che modifica le impostazioni di memoria del kernel e NUMA. |
nfsservctl |
Negare l'interazione con il daemon nfs del kernel. Obsoleto a partire da Linux 3.1. |
open_by_handle_at |
Causa di un'interruzione del contenitore precedente. Gestito anche da CAP_DAC_READ_SEARCH. |
perf_event_open |
Traccia/profilatura syscall, che potrebbe causare perdite di informazioni sull'host. |
personality |
Impedire al contenitore di abilitare l'emulazione BSD. Non intrinsecamente pericoloso, ma scarsamente testato, potenziale per vulns del kernel. |
pivot_root |
Negare pivot_root, deve essere un'operazione con privilegi. |
process_vm_readv |
Limitare le funzionalità di ispezione dei processi, già bloccate eliminando CAP_SYS_PTRACE. |
process_vm_writev |
Limitare le funzionalità di ispezione dei processi, già bloccate eliminando CAP_SYS_PTRACE. |
ptrace |
Traccia/profilatura syscall. Bloccato nelle versioni del kernel Linux precedenti a 4.8 per evitare il bypass seccomp. La traccia o la profilatura di processi arbitrari è già bloccata rimuovendo CAP_SYS_PTRACE, perché potrebbe causare la perdita di informazioni sull'host. |
query_module |
Nega manipolazione e funzioni sui moduli del kernel. Obsoleto. |
quotactl |
Chiamata di sistema quota, che potrebbe consentire ai contenitori di disabilitare i propri limiti di risorse o i conteggi processi. Gestito anche da CAP_SYS_ADMIN. |
reboot |
Non consentire ai contenitori di riavviare l'host. Gestito anche da CAP_SYS_BOOT. |
request_key |
Impedire ai contenitori di usare il keyring del kernel, che non è spazio dei nomi. |
set_mempolicy |
Syscall che modifica le impostazioni di memoria del kernel e NUMA. Già controllato da CAP_SYS_NICE. |
setns |
Negare l'associazione di un thread a uno spazio dei nomi. Gestito anche da CAP_SYS_ADMIN. |
settimeofday |
L'ora e la data non sono spazi dei nomi. Gestito anche da CAP_SYS_TIME. |
stime |
L'ora e la data non sono spazi dei nomi. Gestito anche da CAP_SYS_TIME. |
swapon |
Negare avvio/arresto dello scambio in file/dispositivo. Gestito anche da CAP_SYS_ADMIN. |
swapoff |
Negare avvio/arresto dello scambio in file/dispositivo. Gestito anche da CAP_SYS_ADMIN. |
sysfs |
Syscall obsoleto. |
_sysctl |
Obsoleto, sostituito da /proc/sys. |
umount |
Deve essere un'operazione con privilegi. Gestito anche da CAP_SYS_ADMIN. |
umount2 |
Deve essere un'operazione con privilegi. Gestito anche da CAP_SYS_ADMIN. |
unshare |
Negare la clonazione di nuovi spazi dei nomi per i processi. Anch'esso controllato da CAP_SYS_ADMIN (tranne unshare --user). |
uselib |
Syscall precedente correlata alle librerie condivise, non utilizzata per molto tempo. |
userfaultfd |
Gestione dell’errore di pagina nello spazio utente, in gran parte necessaria per la migrazione dei processi. |
ustat |
Syscall obsoleto. |
vm86 |
Nella macchina virtuale in modalità reale x86 del kernel. Gestito anche da CAP_SYS_ADMIN. |
vm86old |
Nella macchina virtuale in modalità reale x86 del kernel. Gestito anche da CAP_SYS_ADMIN. |
Contenuti correlati
Per altre informazioni sulla protezione del cluster del servizio Azure Kubernetes, vedere gli articoli seguenti: