La gestione sicura dei segreti è un aspetto importante della sicurezza dei container. Se stai inserendo password e chiavi API come variabili di ambiente, rischi l'esposizione involontaria delle informazioni. Le variabili della shell vengono spesso registrate, trasmesse a processi figlio o divulgate a servizi di segnalazione errori a tua insaputa.
L'iniezione di valori come segreti dedicati attenua questi rischi. Docker ha un supporto integrato per la gestione sicura dei segreti a cui puoi collegarti con Docker Compose. L'accesso ai segreti è concesso in base al servizio.
Come funzionano i segreti?
La Docker CLI ha un batch di comandi di gestione segreti, ma questi funzionano solo con i cluster Swarm. Non puoi aggiungere segreti a container standalone utilizzando solo la Docker CLI.
Docker Compose ha aggiunto segreti "falsi" per portare queste funzionalità ai carichi di lavoro senza un cluster. L'implementazione di Compose funziona in modo simile alle funzionalità Docker Swarm e funziona con qualsiasi file Compose.
I segreti vengono creati come normali file di testo che vengono montati nei tuoi contenitori. La tua applicazione accede al valore del segreto leggendo il contenuto del file. Questo modello consente ai valori di rimanere inerti finché non vengono utilizzati in modo esplicito all'interno del tuo contenitore, a differenza delle variabili di ambiente visibili in modo permanente.
Definizione dei segreti nei file di composizione
Ottenere un segreto in un contenitore è un processo in due fasi. Per prima cosa devi definire il segreto, usando i secrets
di livello superiore campo nel tuo file Componi. Quindi aggiorni le definizioni del servizio per fare riferimento ai segreti di cui hanno bisogno.
Ecco un esempio che utilizza i segreti per fornire in modo sicuro una password a un servizio:
version: "3" services: app: image: example-app:latest secrets: - db_password secrets: db_password: file: ./db_password.txt
Il valore del segreto verrà letto dal db_password.txt
della tua directory di lavoro quando esegui docker-compose up
. Compose monterà il file su /run/secrets/db_password
all'interno del contenitore. La tua app può accedere alla password del database leggendo il contenuto del file segreto.
Utilizzo dei segreti Docker esistenti
Oltre ai segreti basati su file, Compose ti consente anche di fare riferimento ai segreti Docker Swarm esistenti. Se utilizzi questo meccanismo, devi creare i segreti in Docker prima esegui docker-compose up
. I docker secrets
lo spazio comandi funzionerà solo quando l'endpoint Docker attivo è un nodo gestore Swarm.
Crea il segreto utilizzando la Docker CLI:
# take value from standard input echo P@55w0rd | docker secret create db_password - OR # take value from a file docker secret create db_password ./db_password.txt
Ora aggiorna il tuo file Docker Compose per fare riferimento al segreto:
version: "3" services: app: image: example-app:latest secrets: - db_password secrets: db_password: external: true
Impostazione del segreto external
Il campo indica a Compose di ricavare il suo valore dai segreti Docker esistenti. Lo stack fallirà con un errore se provi ad avviarlo prima che il segreto esista.
Sintassi segreta estesa
Compose supporta una sintassi dei segreti più lunga se è necessario un controllo più granulare sul processo di iniezione. Il passaggio a questa sintassi ti consente di personalizzare i permessi dei file e di modificare il nome montato del segreto.
Sono disponibili cinque campi opzionali:
source
– Il nome del segreto a cui fare riferimento:deve essere uno dei valori definiti neisecrets
del tuo file Compose sezione.target
– Nome file da utilizzare quando il segreto viene montato nel contenitore.uid
– UID da impostare sul file segreto montato. Il valore predefinito è 0.gid
– GID da impostare sul file segreto montato. Il valore predefinito è 0.mode
– Autorizzazioni del filesystem da applicare al file segreto montato, espresse in notazione ottale. Il valore predefinito è 0444. Fai attenzione che i file segreti non sono mai scrivibili poiché sono sempre montati nel filesystem temporaneo di un contenitore.
Ecco un esempio modificato che rinomina il file segreto montato e ne cambia le autorizzazioni:
version: "3" services: app: image: example-app:latest secrets: - source: db_password target: database_password_secret mode: 0440 secrets: db_password: external: true
La sintassi semplice è in genere sufficiente per la maggior parte delle distribuzioni. Se hai requisiti più specifici, la versione estesa dovrebbe darti il controllo di cui hai bisogno. I singoli riferimenti segreti possono combinare e abbinare le due sintassi all'interno dello stesso file Compose.
Segreti e paternità delle immagini
Molte popolari immagini Docker della community ora supportano i segreti anziché le variabili di ambiente. In qualità di autore di immagini, offrire segreti è un approccio di best practice per proteggere i dati dei tuoi utenti.
È possibile supportare entrambi i meccanismi consentendo alle variabili di ambiente di essere impostate su un percorso di file. Se la tua immagine necessita di una connessione al database, consenti agli utenti di impostare il DB_PASSWORD
variabile di ambiente su P@55w0rd
o /run/secrets/db_password
. Il tuo contenitore dovrebbe verificare se il valore della variabile fa riferimento a un file valido; in tal caso, scartalo e leggi il valore finale dal file.
Questo modello offre agli utenti la flessibilità di scegliere il meccanismo più appropriato per la loro distribuzione. Ricorda che non tutti gli utenti saranno in grado di adottare i segreti:se Swarm e Compose non sono entrambi disponibili, non avranno modo di fornire i propri valori.
Conclusione
L'uso di segreti invece di normali variabili ambientali riduce i rischi di divulgazione involontaria di informazioni. Immagina uno scenario peggiore in cui un contenitore ha inviato le sue variabili di ambiente a un servizio di registrazione di terze parti compromesso. Gli aggressori ora hanno la password del database e le chiavi API.
Limitando i dati segreti all'accesso al filesystem, i valori non possono essere letti inavvertitamente poiché non sono una caratteristica perpetua del tuo ambiente. Ricorda però che i file segreti comportano i propri rischi. Potresti essere tentato di impegnarli nel controllo del codice sorgente, il che significherebbe che chiunque abbia accesso al tuo repository potrebbe leggere i loro valori.
I segreti dovrebbero essere "segreti" durante tutto il ciclo di vita del tuo contenitore. Per le distribuzioni di produzione, in genere è meglio automatizzare le build con un sistema CI. Imposta i tuoi segreti nelle impostazioni della pipeline del tuo provider CI, quindi usa lo script di build per scriverli in file a cui Compose può accedere. Ciò garantisce che solo tu abbia accesso ai valori effettivi, tramite l'interfaccia del tuo strumento CI.