- La sicurezza dei container Docker richiede il controllo simultaneo di immagini, host, rete e orchestrazione.
- L'utilizzo di immagini minimali, firmate e scansionate riduce drasticamente le vulnerabilità e la superficie di attacco.
- Il principio del minimo privilegio, la segmentazione della rete e la gestione sicura dei segreti sono pilastri essenziali.
- La combinazione di scansione continua, monitoraggio in tempo reale e cultura DevSecOps rafforza l'intero ciclo di vita.
I container hanno completamente rivoluzionato il modo in cui sviluppiamo e distribuiamo il software. Docker, da curiosità di nicchia, è diventato lo standard di fatto per il packaging di applicazioni, microservizi e persino database. Tutto è più veloce, più portatile e molto più facile da automatizzare; l'ottimizzazione dei container è fondamentale, ma se si abbassa la guardia in materia di sicurezza, si rischia di incorrere in spiacevoli sorprese.
Un singolo container configurato in modo errato o un'immagine con una vulnerabilità critica possono diffondersi in tutta l'infrastruttura in pochi secondi. La stessa agilità che utilizzi per il deployment in un ambiente CI/CD è ciò che un attaccante sfrutta per elevare i privilegi, spostarsi lateralmente all'interno della rete o estrarre dati sensibili. Ecco perché vale la pena fermarsi, rivedere le best practice e sviluppare una solida strategia di sicurezza per i container Docker.
Cos'è Docker e perché la sua sicurezza è così delicata?
Docker è una piattaforma di container che consente di impacchettare un'applicazione, insieme alle sue librerie, ai file binari e alle dipendenze, in un'unità standardizzata chiamata immagine container . Da questa immagine, è possibile avviare tutte le istanze desiderate; queste sono i container stessi.
Questi container vengono eseguiti come processi isolati su un sistema operativo condiviso. Non sono macchine virtuali complete : condividono il kernel dell'host, il che li rende molto leggeri e perfetti per architetture a microservizi, pipeline CI/CD e implementazioni cloud-native.
Le immagini vengono in genere definite tramite un Dockerfile, un file di testo che specifica l'ambiente di base, i pacchetti installati, le porte esposte, l'account utente e altri dettagli. Una volta creata, l'immagine viene salvata in un registro (Docker Hub, registro aziendale, ecc.) e da lì distribuita negli ambienti di sviluppo, pre-produzione o produzione.
Questo modello offre agilità e scalabilità, ma apre anche nuove porte agli attacchi. Qualsiasi falla nell'immagine, nell'host, nella rete o nell'orchestratore può compromettere qualsiasi cosa, da una singola applicazione a un intero cluster Kubernetes (ad esempio, Docker Swarm ).
Principali rischi e minacce nei container Docker
Prima di iniziare a proteggere il tuo ambiente, è importante capire cosa potrebbe accadere. Gli attacchi contro i container tendono a ruotare attorno ad alcuni vettori molto comuni.
Immagini vulnerabili o dannose
Ogni immagine Docker in genere include un sistema di base e un buon numero di pacchetti. Se anche solo una di queste dipendenze presenta una vulnerabilità nota , la superficie di attacco esploderà. L'utilizzo di immagini obsolete, non ufficiali o modificate da terze parti è una fonte costante di problemi.
Su registri come Docker Hub sono state trovate migliaia di immagini pubbliche contenenti malware, backdoor o configurazioni pericolose . Utilizzarle senza verificarne l'autenticità equivale a eseguire codice proveniente da fonti sconosciute sui propri server.
Fuga dal container
I container condividono il kernel dell'host; se qualcuno riesce a sfruttare un bug in quel kernel, nel runtime o nella configurazione dei privilegi, può passare dal container al sistema host o ad altri container . Questo fenomeno è noto come "camion escape".
Questo tipo di attacco è facilitato dall'esecuzione di container in modalità privilegiata, con funzionalità Linux eccessive o senza l'applicazione corretta di meccanismi come AppArmor, SELinux o seccomp.
Configurazioni di rete non sicure
Docker semplifica la creazione di reti bridge, overlay e port forwarding. Se si lascia tutto in modalità "predefinita", è facile ritrovarsi con servizi interni esposti a Internet , comunicazioni illimitate tra container o la possibilità di spostarsi lateralmente all'interno dell'intero ambiente.
Una segmentazione inadeguata, l'assenza di firewall a livello host o politiche di orchestrazione permissive possono consentire a un'intrusione in un singolo container di trasformarsi in una compromissione diffusa.
Daemon Docker scarsamente protetto
Il demone Docker (dockerd) è il cuore della piattaforma: controlla immagini, container e reti. Se un utente malintenzionato ottiene l'accesso al socket del demone, di fatto ha il controllo dell'intero host . Ciò include l'accesso a volumi, immagini, reti e altri container.
Tra le cattive pratiche più comuni si annoverano l'esposizione dell'API Docker senza TLS, la mancata richiesta di autenticazione per il socket remoto, l'esecuzione del demone con privilegi superiori al necessario o la mancata verifica della sua configurazione.
Segreti e variabili ambientali svelati
È molto comune trovare password, token API o chiavi private inserite forzatamente nei Dockerfile, nelle variabili d'ambiente o persino nel codice stesso . Questi segreti finiscono per essere visibili nei layer delle immagini, nei log o tramite un semplice comando `docker inspect`.
Quando queste immagini vengono caricate su un registro condiviso, chiunque abbia accesso al registro può recuperare le credenziali che potrà poi riutilizzare per accedere a database, code di messaggi o altri servizi interni.
Vulnerabilità del kernel e del sistema host
Poiché tutti i container si basano sullo stesso kernel, qualsiasi vulnerabilità di sicurezza a livello di sistema operativo influisce sull'intero cluster . Un host obsoleto con patch di sicurezza in sospeso è un regalo per chiunque sia alla ricerca di exploit noti.
Inoltre, se l'host esegue altri servizi oltre a Docker, un errore in uno di questi servizi può essere sfruttato come punto di ingresso per attaccare l'ambiente dei container.
Comunicazione illimitata tra i contenitori
Di default, molte implementazioni consentono a tutti i container di comunicare tra loro senza particolari filtri. Questo è molto comodo per gli sviluppatori, ma disastroso per la sicurezza . Se un container si arresta, un aggressore può usarlo come testa di ponte per attaccare gli altri.
Senza segmentazione della rete, politiche di traffico e controlli, una volta ottenuto l'accesso iniziale, il movimento laterale all'interno del cluster è solo questione di tempo .
Principali prassi da seguire prima di utilizzare Docker in produzione
Tutto inizia sull'host su cui verrà eseguito Docker. Eseguire container su sistemi operativi non sicuri è come mettere il carro davanti ai buoi , quindi è meglio stabilire alcune misure di sicurezza di base.
Idealmente, dovresti dedicare server o macchine virtuali esclusivamente ai carichi di lavoro containerizzati. Se possibile , evita di combinare Docker con database fisici, applicazioni legacy o altri servizi sullo stesso host: questo riduce la superficie di attacco e previene le interferenze.
Mantieni aggiornati il kernel e il sistema operativo host con le patch di sicurezza, preferibilmente utilizzando versioni LTS e una procedura di aggiornamento chiara . Inoltre, rafforza la sicurezza del file system, della configurazione SSH, dei servizi in background e, in generale, di tutto ciò che non è strettamente necessario per eseguire Docker.
Negli ambienti Linux, è fortemente consigliato attivare e configurare correttamente meccanismi come AppArmor, SELinux , cgroups e namespace . Questi sono i fondamenti dell'isolamento dei container e del controllo granulare delle autorizzazioni delle risorse dell'host.
Immagini Docker sicure: le fondamenta di tutto
La sicurezza dei tuoi container inizia dall'immagine. Se l'immagine è già vulnerabile, non importa quanto bene tu configuri tutto il resto . È qui che la disciplina fa la differenza.
Utilizzare immagini ufficiali, verificate e minime
Quando possibile, utilizzate immagini ufficiali o verificate (ad esempio, immagini provenienti da fornitori certificati o registri aziendali affidabili ). Queste immagini sono generalmente aggiornate, sottoposte a scansioni frequenti e riducono il rischio di imbattersi in codice dannoso.
Partite sempre da una base minimale: Alpine, Debian:Slim o equivalenti riducono drasticamente il numero di pacchetti installati. Minore è il numero di componenti della vostra immagine, minori saranno le potenziali vulnerabilità e più facile sarà mantenerla aggiornata.
Firma e verifica le immagini
Per evitare sorprese con immagini modificate, utilizzate meccanismi di verifica della fiducia nei contenuti come Docker Content Trust o sistemi di tipo notarile . L'idea è di utilizzare solo immagini firmate da qualcuno che considerate affidabile e di verificare la firma prima di eseguire qualsiasi operazione.
In molti casi, è sufficiente attivare l'uso obbligatorio delle firme prima della distribuzione, in modo che qualsiasi immagine priva di firma valida o proveniente da una fonte sconosciuta venga bloccata automaticamente.
Evitare di includere informazioni sensibili nell'immagine
Uno degli errori più comuni è includere chiavi, certificati o password nell'immagine stessa. Chiunque abbia accesso al registro di sistema può scaricare l'immagine ed estrarre questi dati sensibili . Non serve essere un genio per farlo.
Il metodo corretto consiste nell'iniettare i segreti in fase di esecuzione: Docker Secrets, Kubernetes Secrets o altri strumenti open source come Vault o Consul consentono di gestire le credenziali in modo centralizzato, crittografarle ed esporle solo ai container che ne hanno effettivamente bisogno.
Scansione delle vulnerabilità dell'immagine
Integrare gli scanner di vulnerabilità nel ciclo di vita è fondamentale. Strumenti come Trivy, Clair, Grype, Snyk, Anchore e altri si connettono alla pipeline CI/CD, ai registri o all'orchestratore e analizzano ogni immagine alla ricerca di CVE note e configurazioni pericolose.
Idealmente, questa scansione dovrebbe avvenire automaticamente in ogni build o prima del caricamento dell'immagine nel registro, e qualsiasi immagine con vulnerabilità di gravità elevata o critica dovrebbe essere impedita dalla promozione in produzione senza un'eccezione esplicita.
Costruzioni a più fasi e riduzione della superficie
Le build a più fasi consentono di compilare l'applicazione in un'immagine "completa" con tutti gli strumenti di sviluppo e di copiare solo il prodotto finale in un'immagine runtime molto leggera . In questo modo, si evita di lasciare compilatori, gestori di pacchetti e utility non necessari nell'immagine di produzione.
In definitiva, si ottengono container più piccoli che si scaricano e si avviano più velocemente, offrendo anche meno opportunità a un aggressore di muoversi all'interno del sistema.
Gestione dei privilegi, degli utenti e delle risorse dei container.
Uno degli errori più comuni è avviare i container come root e dimenticarsene. Se il processo all'interno del container viene eseguito come root e si verifica un errore di accesso, l'attaccante otterrà i privilegi di root sull'host , con tutti i rischi che ne conseguono.
L'approccio corretto consiste nel creare utenti specifici all'interno dell'immagine e utilizzare la direttiva USER nel Dockerfile, oppure assegnare un utente non privilegiato con l'opzione `--user` all'avvio del container . È consigliabile combinare questa soluzione con filesystem e volumi di sola lettura con permessi adeguati.
Inoltre, rivedete le funzionalità di Linux e la modalità privilegiata: evitate l'opzione –privileged a tutti i costi, tranne in casi molto specifici e controllati , e applicate i profili seccomp, AppArmor o SELinux per limitare le chiamate di sistema che il container può eseguire.
Parallelamente, definisci quote di risorse utilizzando i cgroup per limitare CPU, RAM e I/O. Ciò impedisce che un container compromesso provochi il crash dell'host o influisca sulle prestazioni di altri servizi , sia accidentalmente che nell'ambito di un attacco DoS interno.
Rete, registrazione e segmentazione dell'ambiente Docker.
La rete è un altro elemento critico per la sicurezza dei container. Non tutti i servizi devono essere accessibili ovunque , e ancor meno da Internet.
Utilizza reti Docker personalizzate e separa il traffico tra frontend, backend, database e servizi interni. Limita i container che possono comunicare tra loro e le porte utilizzate . In molti casi, sarà sufficiente che i servizi interni siano in ascolto solo su reti private, senza esposizione pubblica.
Configura i firewall sull'host (iptables, nftables, UFW, firewalld) per filtrare il traffico da e verso le porte pubblicate da Docker. Inoltre, applica policy di rete a livello di orchestratore (ad esempio, NetworkPolicies in Kubernetes ) per rafforzare ulteriormente questa segmentazione.
Per quanto riguarda i registri dei container, utilizzate registri affidabili, idealmente un registro privato dietro il vostro firewall con controllo degli accessi basato sui ruoli (RBAC) . Limitate chi può caricare e scaricare immagini e impedite a chiunque di effettuare il push di qualsiasi contenuto.
Implementare una chiara politica di etichettatura ti aiuta a sapere quale versione è distribuita in ogni ambiente. Evita di abusare dell'espressione "ultima versione" e utilizza il versionamento semantico o metodi simili per mantenere il controllo su cosa è in esecuzione e dove.
Monitoraggio, registrazione e gestione degli incidenti
Senza visibilità, la sicurezza è essenzialmente una questione di fede. I container sono effimeri e vengono creati e distrutti ad alta velocità , quindi è necessario un livello di monitoraggio centralizzato che non dipenda dal ciclo di vita di ogni singolo container.
Centralizzate i vostri log utilizzando soluzioni come ELK, Grafana Loki, Fluentd o altre, e assicuratevi che il demone Docker, i container e l'host inviino tutti i loro log a tale sistema. Questo vi permetterà di correlare gli eventi e rilevare modelli anomali.
Per il rilevamento delle minacce in fase di esecuzione, strumenti come Falco sono diventati di fatto uno standard . Analizzano le chiamate di sistema in tempo reale e attivano avvisi quando rilevano comportamenti sospetti: shell interattive all'interno dei container, accessi insoliti a file sensibili, connessioni di rete anomale, ecc.
Completate il tutto con un piano di risposta agli incidenti specifico per ogni container. Definite in anticipo come isolerete i container compromessi, quali prove raccoglierete, come ricreerete immagini pulite e come esaminerete regole e configurazioni dopo un attacco.
Strumenti e piattaforme di sicurezza Docker
L'ecosistema della sicurezza dei container è enorme. Esistono soluzioni praticamente per ogni livello del ciclo di vita : dal codice all'esecuzione, inclusi il registro e il cloud.
Piattaforme di sicurezza a ciclo completo
Alcuni strumenti sono progettati per fornire una copertura completa. Piattaforme come Aqua Security, Prisma Cloud, Check Point Container Security e Aikido Security combinano la scansione delle immagini, la protezione in fase di esecuzione, la gestione delle vulnerabilità, la conformità normativa e la visibilità multi-cloud.
Questo tipo di soluzioni sono particolarmente utili nelle grandi organizzazioni che necessitano di consolidare la sicurezza di container, Kubernetes, macchine virtuali e servizi cloud in un'unica console , riducendo così la frammentazione degli strumenti e l'affaticamento da notifiche.
Strumenti pensati per gli sviluppatori
Altri approcci si concentrano sull'integrazione diretta della sicurezza nel flusso di lavoro dello sviluppatore. Piattaforme come Snyk, Aikido Security e gli scanner Anchore si integrano con GitHub, GitLab, IDE e pipeline CI/CD per fornire feedback tempestivi, suggerire soluzioni e dare priorità alle vulnerabilità realmente sfruttabili.
L'idea è che il team di sviluppo stesso debba assumersi parte della responsabilità della sicurezza, correggendo immagini di base non sicure, dipendenze vulnerabili o configurazioni pericolose prima che qualsiasi cosa venga rilasciata in produzione.
Sicurezza in fase di esecuzione e rilevamento delle minacce
Quando i container sono in esecuzione, entrano in gioco le soluzioni runtime: Falco come progetto open source, Sysdig Secure, moduli EDR/IDS adattati ai container e altri prodotti simili.
Questi strumenti monitorano ciò che accade effettivamente nei container e sull'host e possono bloccare comportamenti dannosi, applicare policy o, quantomeno, generare avvisi molto dettagliati con informazioni contestuali provenienti da pod, namespace, immagini, ecc.
Gestione e inventario delle vulnerabilità
La generazione e la gestione delle distinte base del software (SBOM) sono diventate una questione cruciale. Strumenti come Anchore (con Syft e Grype), Qualys Container Security e soluzioni simili consentono di inventariare i pacchetti e le librerie inclusi in ogni immagine e di confrontare queste informazioni con i database delle vulnerabilità.
In questo modo, quando viene rilevata una nuova vulnerabilità CVE critica, è possibile individuare rapidamente quali immagini e container sono interessati nel proprio ambiente e pianificarne l'aggiornamento di conseguenza.
Cultura DevSecOps e buone pratiche organizzative
Al di là della tecnologia, la sicurezza di Docker è una questione culturale. Se la sicurezza viene rimandata alla fine, finirà per ostacolare le implementazioni e la tentazione sarà quella di aggirare i controlli.
L'approccio DevSecOps propone di integrare la sicurezza fin dall'inizio del ciclo di vita: revisione dei Dockerfile, scansione delle dipendenze, applicazione di politiche di qualità e sicurezza in ogni commit o richiesta di merge e automazione della maggior parte di questi controlli.
È inoltre fondamentale che i team di architettura e sicurezza definiscano i moduli best practice, i modelli Dockerfile, le immagini di base aziendali rinforzate e i requisiti minimi affinché un container possa raggiungere la produzione (porte consentite, registrazione, utenti, limiti delle risorse, ecc.).
La formazione gioca un ruolo fondamentale: maggiore è la comprensione da parte di sviluppatori e operatori delle implicazioni derivanti dall'esecuzione di container come root, dall'esposizione delle porte o dalla combinazione di ambienti diversi, minore sarà il numero di errori di base che si insinueranno nelle implementazioni e più naturale risulterà applicare le raccomandazioni di cui sopra.
In definitiva, la protezione delle applicazioni containerizzate con Docker richiede un approccio a più livelli: immagini minimali e affidabili, host protetti, privilegi rigorosi, reti segmentate, scansione continua, monitoraggio intelligente e una solida cultura DevSecOps . Combinando questi elementi, è possibile sfruttare tutti i vantaggi di Docker senza temere costantemente che il prossimo deployment possa creare una vulnerabilità in produzione.

