Docker Security
Last updated
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Usa Trickest per costruire e automatizzare flussi di lavoro alimentati dagli strumenti della comunità più avanzati al mondo. Ottieni accesso oggi:
Il motore Docker utilizza i Namespaces e i Cgroups del kernel Linux per isolare i contenitori, offrendo un livello base di sicurezza. Ulteriore protezione è fornita tramite il Capabilities dropping, Seccomp e SELinux/AppArmor, migliorando l'isolamento dei contenitori. Un plugin di autenticazione può ulteriormente limitare le azioni degli utenti.
Il motore Docker può essere accessibile localmente tramite un socket Unix o remotamente utilizzando HTTP. Per l'accesso remoto, è essenziale utilizzare HTTPS e TLS per garantire riservatezza, integrità e autenticazione.
Il motore Docker, per impostazione predefinita, ascolta sul socket Unix a unix:///var/run/docker.sock
. Nei sistemi Ubuntu, le opzioni di avvio di Docker sono definite in /etc/default/docker
. Per abilitare l'accesso remoto all'API e al client Docker, esponi il demone Docker su un socket HTTP aggiungendo le seguenti impostazioni:
Tuttavia, esporre il demone Docker su HTTP non è raccomandato a causa di preoccupazioni di sicurezza. È consigliabile proteggere le connessioni utilizzando HTTPS. Ci sono due approcci principali per garantire la connessione:
Il client verifica l'identità del server.
Sia il client che il server si autenticano reciprocamente l'identità.
I certificati vengono utilizzati per confermare l'identità di un server. Per esempi dettagliati di entrambi i metodi, fare riferimento a questa guida.
Le immagini dei container possono essere memorizzate in repository privati o pubblici. Docker offre diverse opzioni di archiviazione per le immagini dei container:
Docker Hub: Un servizio di registry pubblico di Docker.
Docker Registry: Un progetto open-source che consente agli utenti di ospitare il proprio registry.
Docker Trusted Registry: L'offerta commerciale di registry di Docker, con autenticazione utente basata su ruoli e integrazione con i servizi di directory LDAP.
I container possono avere vulnerabilità di sicurezza sia a causa dell'immagine di base che a causa del software installato sopra l'immagine di base. Docker sta lavorando a un progetto chiamato Nautilus che esegue la scansione di sicurezza dei container e elenca le vulnerabilità. Nautilus funziona confrontando ogni layer dell'immagine del container con il repository delle vulnerabilità per identificare le falle di sicurezza.
Per ulteriori informazioni leggi questo.
docker scan
Il comando docker scan
consente di eseguire la scansione delle immagini Docker esistenti utilizzando il nome o l'ID dell'immagine. Ad esempio, eseguire il seguente comando per scansionare l'immagine hello-world:
La firma delle immagini Docker garantisce la sicurezza e l'integrità delle immagini utilizzate nei container. Ecco una spiegazione condensata:
Per attivare la fiducia nei contenuti Docker, impostare export DOCKER_CONTENT_TRUST=1
. Questa funzione è disattivata per impostazione predefinita nelle versioni di Docker 1.10 e successive.
Con questa funzione attivata, possono essere scaricate solo immagini firmate. La prima spinta dell'immagine richiede l'impostazione delle frasi di accesso per le chiavi root e di tagging, con Docker che supporta anche Yubikey per una maggiore sicurezza. Maggiori dettagli possono essere trovati qui.
Tentare di scaricare un'immagine non firmata con la fiducia nei contenuti attivata risulta in un errore "No trust data for latest".
Per le spinte delle immagini dopo la prima, Docker richiede la frase di accesso della chiave del repository per firmare l'immagine.
Per eseguire il backup delle tue chiavi private, usa il comando:
Quando si cambia host Docker, è necessario spostare le chiavi root e repository per mantenere le operazioni.
Usa Trickest per costruire e automatizzare flussi di lavoro alimentati dagli strumenti della comunità più avanzati al mondo. Accedi oggi:
Namespaces sono una funzionalità del kernel Linux che partiziona le risorse del kernel in modo tale che un insieme di processi vede un insieme di risorse mentre un altro insieme di processi vede un insieme diverso di risorse. La funzionalità funziona avendo lo stesso namespace per un insieme di risorse e processi, ma quegli namespace si riferiscono a risorse distinte. Le risorse possono esistere in più spazi.
Docker utilizza i seguenti Namespaces del kernel Linux per ottenere l'isolamento dei Container:
pid namespace
mount namespace
network namespace
ipc namespace
UTS namespace
Per maggiori informazioni sui namespaces controlla la seguente pagina:
La funzionalità del kernel Linux cgroups fornisce la capacità di ristretto risorse come cpu, memoria, io, larghezza di banda di rete tra un insieme di processi. Docker consente di creare Container utilizzando la funzionalità cgroup che consente il controllo delle risorse per il Container specifico. Di seguito è riportato un Container creato con la memoria dello spazio utente limitata a 500m, la memoria del kernel limitata a 50m, la condivisione della cpu a 512, il blkioweight a 400. La condivisione della CPU è un rapporto che controlla l'uso della CPU del Container. Ha un valore predefinito di 1024 e un intervallo tra 0 e 1024. Se tre Container hanno la stessa condivisione della CPU di 1024, ciascun Container può utilizzare fino al 33% della CPU in caso di contesa delle risorse CPU. Il blkio-weight è un rapporto che controlla l'IO del Container. Ha un valore predefinito di 500 e un intervallo tra 10 e 1000.
Per ottenere il cgroup di un container puoi fare:
Per ulteriori informazioni controlla:
Le capacità consentono un controllo più fine sulle capacità che possono essere consentite per l'utente root. Docker utilizza la funzionalità di capacità del kernel Linux per limitare le operazioni che possono essere eseguite all'interno di un Container indipendentemente dal tipo di utente.
Quando un container docker viene eseguito, il processo abbandona capacità sensibili che il processo potrebbe utilizzare per sfuggire all'isolamento. Questo cerca di garantire che il processo non sarà in grado di eseguire azioni sensibili e fuggire:
Questa è una funzionalità di sicurezza che consente a Docker di limitare le syscalls che possono essere utilizzate all'interno del container:
AppArmor è un miglioramento del kernel per confinare i container a un insieme limitato di risorse con profili per programma.:
Sistema di Etichettatura: SELinux assegna un'etichetta unica a ogni processo e oggetto del filesystem.
Applicazione delle Politiche: Applica politiche di sicurezza che definiscono quali azioni un'etichetta di processo può eseguire su altre etichette all'interno del sistema.
Etichette dei Processi del Container: Quando i motori dei container avviano processi del container, di solito viene assegnata un'etichetta SELinux confinata, comunemente container_t
.
Etichettatura dei File all'interno dei Container: I file all'interno del container sono solitamente etichettati come container_file_t
.
Regole di Politica: La politica SELinux garantisce principalmente che i processi con l'etichetta container_t
possano interagire solo (leggere, scrivere, eseguire) con file etichettati come container_file_t
.
Questo meccanismo garantisce che anche se un processo all'interno di un container viene compromesso, è confinato a interagire solo con oggetti che hanno le etichette corrispondenti, limitando significativamente il potenziale danno derivante da tali compromessi.
In Docker, un plugin di autorizzazione gioca un ruolo cruciale nella sicurezza decidendo se consentire o bloccare le richieste al demone Docker. Questa decisione viene presa esaminando due contesti chiave:
Contesto di Autenticazione: Questo include informazioni complete sull'utente, come chi sono e come si sono autenticati.
Contesto del Comando: Questo comprende tutti i dati pertinenti relativi alla richiesta effettuata.
Questi contesti aiutano a garantire che solo le richieste legittime da parte di utenti autenticati vengano elaborate, migliorando la sicurezza delle operazioni Docker.
Se non limiti correttamente le risorse che un container può utilizzare, un container compromesso potrebbe causare un DoS all'host su cui è in esecuzione.
CPU DoS
Attacco DoS di larghezza di banda
Nella pagina seguente puoi imparare cosa implica il flag --privileged
:
Se stai eseguendo un container in cui un attaccante riesce ad accedere come utente a basso privilegio. Se hai un binary suid mal configurato, l'attaccante potrebbe abusarne e escalare i privilegi all'interno del container. Questo potrebbe permettergli di fuggire da esso.
Eseguire il container con l'opzione no-new-privileges
abilitata prevenirà questo tipo di escalation dei privilegi.
Per ulteriori opzioni --security-opt
controlla: https://docs.docker.com/engine/reference/run/#security-configuration
È fondamentale evitare di incorporare segreti direttamente nelle immagini Docker o di utilizzare variabili d'ambiente, poiché questi metodi espongono le tue informazioni sensibili a chiunque abbia accesso al container tramite comandi come docker inspect
o exec
.
I volumi Docker sono un'alternativa più sicura, raccomandata per accedere a informazioni sensibili. Possono essere utilizzati come un filesystem temporaneo in memoria, mitigando i rischi associati a docker inspect
e al logging. Tuttavia, gli utenti root e coloro che hanno accesso exec
al container potrebbero comunque accedere ai segreti.
I segreti Docker offrono un metodo ancora più sicuro per gestire informazioni sensibili. Per le istanze che richiedono segreti durante la fase di costruzione dell'immagine, BuildKit presenta una soluzione efficiente con supporto per segreti a tempo di costruzione, migliorando la velocità di costruzione e fornendo funzionalità aggiuntive.
Per sfruttare BuildKit, può essere attivato in tre modi:
Tramite una variabile d'ambiente: export DOCKER_BUILDKIT=1
Prefissando i comandi: DOCKER_BUILDKIT=1 docker build .
Abilitandolo per impostazione predefinita nella configurazione di Docker: { "features": { "buildkit": true } }
, seguito da un riavvio di Docker.
BuildKit consente l'uso di segreti a tempo di costruzione con l'opzione --secret
, assicurando che questi segreti non siano inclusi nella cache di costruzione dell'immagine o nell'immagine finale, utilizzando un comando come:
Per i segreti necessari in un container in esecuzione, Docker Compose e Kubernetes offrono soluzioni robuste. Docker Compose utilizza una chiave secrets
nella definizione del servizio per specificare i file segreti, come mostrato in un esempio di docker-compose.yml
:
Questa configurazione consente l'uso di segreti durante l'avvio dei servizi con Docker Compose.
Negli ambienti Kubernetes, i segreti sono supportati nativamente e possono essere ulteriormente gestiti con strumenti come Helm-Secrets. I controlli di accesso basati sui ruoli (RBAC) di Kubernetes migliorano la sicurezza nella gestione dei segreti, simile a Docker Enterprise.
gVisor è un kernel applicativo, scritto in Go, che implementa una parte sostanziale della superficie di sistema Linux. Include un runtime Open Container Initiative (OCI) chiamato runsc
che fornisce un confine di isolamento tra l'applicazione e il kernel host. Il runtime runsc
si integra con Docker e Kubernetes, rendendo semplice l'esecuzione di container sandboxed.
Kata Containers è una comunità open source che lavora per costruire un runtime di container sicuro con macchine virtuali leggere che si comportano e funzionano come container, ma forniscono un isolamento del carico di lavoro più forte utilizzando la tecnologia di virtualizzazione hardware come secondo strato di difesa.
Non utilizzare il flag --privileged
o montare un socket Docker all'interno del container. Lo socket Docker consente di avviare container, quindi è un modo semplice per prendere il controllo completo dell'host, ad esempio, eseguendo un altro container con il flag --privileged
.
Non eseguire come root all'interno del container. Usa un utente diverso e namespace utente. L'utente root nel container è lo stesso dell'host a meno che non venga rimappato con i namespace utente. È solo leggermente limitato da, principalmente, i namespace Linux, le capacità e i cgroups.
Elimina tutte le capacità (--cap-drop=all
) e abilita solo quelle necessarie (--cap-add=...
). Molti carichi di lavoro non necessitano di capacità e aggiungerle aumenta l'ambito di un potenziale attacco.
Usa l'opzione di sicurezza “no-new-privileges” per impedire ai processi di acquisire più privilegi, ad esempio tramite binari suid.
Limita le risorse disponibili per il container. I limiti delle risorse possono proteggere la macchina da attacchi di denial of service.
Usa immagini docker ufficiali e richiedi firme o costruisci le tue basate su di esse. Non ereditare o utilizzare immagini backdoored. Inoltre, conserva le chiavi root e le frasi di accesso in un luogo sicuro. Docker ha in programma di gestire le chiavi con UCP.
Ricostruisci regolarmente le tue immagini per applicare patch di sicurezza all'host e alle immagini.
Gestisci i tuoi segreti con saggezza in modo che sia difficile per l'attaccante accedervi.
Se esponi il demone docker usa HTTPS con autenticazione client e server.
Nel tuo Dockerfile, preferisci COPY invece di ADD. ADD estrae automaticamente i file compressi e può copiare file da URL. COPY non ha queste capacità. Ogni volta che è possibile, evita di usare ADD per non essere suscettibile ad attacchi tramite URL remoti e file Zip.
Avere container separati per ogni micro-servizio
Non mettere ssh all'interno del container, “docker exec” può essere usato per ssh nel Container.
Avere immagini di container più piccole
Se sei all'interno di un container docker o hai accesso a un utente nel gruppo docker, potresti provare a fuggire e aumentare i privilegi:
Se hai accesso allo socket docker o hai accesso a un utente nel gruppo docker ma le tue azioni sono limitate da un plugin di autenticazione docker, controlla se puoi bypassarlo:
Lo strumento docker-bench-security è uno script che controlla dozzine di best practices comuni per il deployment di container Docker in produzione. I test sono tutti automatizzati e si basano sul CIS Docker Benchmark v1.3.1. Devi eseguire lo strumento dall'host che esegue docker o da un container con privilegi sufficienti. Scopri come eseguirlo nel README: https://github.com/docker/docker-bench-security.
Usa Trickest per costruire e automatizzare facilmente i flussi di lavoro alimentati dagli strumenti comunitari più avanzati del mondo. Ottieni accesso oggi:
Impara e pratica Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)