
I secret sono fondamentali per il funzionamento di molti sistemi in produzione. La loro esposizione accidentale rientra tra i rischi principali e va gestita con attenzione. Gli sviluppatori devono fare il possibile per proteggere i secret delle applicazioni.
Il problema si fa ancora più complesso quando un'azienda adotta un'architettura a microservizi e diversi servizi devono accedere a secret differenti per funzionare correttamente. Da qui nasce una nuova sfida: come distribuire, gestire, monitorare e ruotare i secret delle applicazioni evitando esposizioni accidentali?
Kubernetes Secrets
Kubernetes mette a disposizione un oggetto chiamato Secret, che permette di memorizzare dati sensibili delle applicazioni come password, chiavi SSH, API key, token e altro ancora. Un Kubernetes Secret può essere iniettato in un container di un Pod come variabile d'ambiente oppure montato come file. Grazie ai Kubernetes Secrets è possibile separare i dati sensibili e la configurazione dal deployment dell'applicazione.
Per esempio, un secret di Kubernetes si può creare con il comando kubectl create secret:
https://gist.github.com/02c582490747681776f1f480ec2f4165
oppure tramite un file Kubernetes db-credentials.yaml che descrive lo stesso secret:
Attenzione: archiviare dati sensibili in un Kubernetes Secret non li rende automaticamente sicuri. Per impostazione predefinita, tutti i dati nei Kubernetes Secrets sono salvati in chiaro e codificati in base64.
A partire dalla versione 1.13, Kubernetes supporta la cifratura at rest dei dati dei Secret, tramite l'oggetto EncryptionConfiguration con un provider di cifratura integrato o esterno.
Elenco dei provider di cifratura attualmente supportati:
Provider integrati: aescbc, aesgsm, secretbox
Tuttavia, la cifratura at rest dei Secret non è attiva per impostazione predefinita. E anche quando viene abilitata, da sola non basta e non può essere considerata una soluzione completa di gestione dei secret.
Una soluzione completa per la gestione dei secret deve garantire anche distribuzione, rotazione, controllo degli accessi a granularità fine, audit log, monitoraggio dell'utilizzo, versionamento, storage cifrato in modo robusto, API e SDK client comodi da usare, oltre probabilmente ad altre funzionalità utili.
Cloud Secrets Management
Diversi cloud vendor offrono servizi di gestione dei secret all'interno delle proprie piattaforme cloud, per aiutare a proteggere i secret necessari ad accedere ad applicazioni, servizi e API. Affidarsi a questi servizi evita di inserire informazioni sensibili in chiaro nel codice e di sviluppare cicli di gestione dei secret fai-da-te. I servizi di Secrets Management permettono di controllare l'accesso ai secret delle applicazioni con permessi a granularità fine e tracciamento degli accessi.
Integrare Kubernetes con i servizi di Secrets Management
In linea generale, qualsiasi applicazione può sfruttare un SDK o un'API specifica del vendor per accedere ai secret memorizzati in un servizio di Secrets Management. Di solito ciò comporta modificare il codice dell'applicazione oppure ricorrere a script di bootstrap o a Init containers, utilizzando strumenti CLI client o web API.
Tutto più semplice con lo strumento secrets-init
Oggi rilasciamo doitintl/secrets-init: uno strumento open source (Apache License 2.0) che semplifica l'integrazione dei servizi cloud-native di Secrets Management con workloads containerizzati eseguiti su cluster Kubernetes gestiti dal cloud o autogestiti.
In sostanza, secrets-init è un sistema init minimale, pensato per essere eseguito come PID 1 all'interno di un ambiente container, in modo analogo a dumb-init, e offre un'integrazione fluida con diversi servizi cloud-native di Secrets Management, tra cui:
Perché serve un sistema init in un container Docker?
Suggeriamo di leggere la spiegazione nel repo Yelp dumb-init
In sintesi:
- Inoltro corretto dei segnali
- Reaping degli zombie orfani
Cosa fa secrets-init
secrets-init viene eseguito come PID 1 e si comporta come un semplice sistema init usato come ENTRYPOINT o primo comando del container: il suo compito è avviare un processo figlio e inoltrare tutti i segnali di sistema alla sessione che ha quel processo come radice. È in questo che consiste, in sostanza, un processo init. Allo stesso tempo, secrets-init propaga quasi tutte le variabili d'ambiente senza modificarle, sostituendo le speciali variabili secret con i valori recuperati dai servizi di Secret Management.
Integrazione con Docker
secrets-init è un file binario compilato staticamente (senza dipendenze esterne) e può essere facilmente incluso in qualsiasi immagine Docker. È sufficiente scaricare il binario di secrets-init e impostarlo come ENTRYPOINT del container Docker.
Per esempio:
https://gist.github.com/7efe25155c034ee1b978a2477b3224e4
Integrazione con Kubernetes
Per usare secrets-init con un oggetto Kubernetes (Pod/Deployment/Job/ecc.) senza modificare l'immagine Docker, conviene iniettare secrets-init nel Pod di destinazione tramite un initContainer. Si può utilizzare l'immagine Docker doitint/secrets-init oppure crearne una propria. Basta copiare il binario secrets-init dall'init container in un volume condiviso e modificare il command del Pod in modo che esegua secrets-init come primo comando.
Integrazione con AWS Secrets Manager
Per iniziare a usare secrets-init con AWS Secrets Manager, è sufficiente impostare un ARN di secret AWS come valore di una variabile d'ambiente. secrets-init risolverà il valore della variabile d'ambiente, sulla base dell'ARN specificato, restituendo il valore del secret referenziato.
Esempio di utilizzo di secrets-init con un Job Kubernetes:
https://gist.github.com/6ae6d57ed08b26c64f534f87fc1872df
Integrazione con AWS Systems Manager Parameter Store
AWS Systems Manager Parameter Store consente di memorizzare i parametri delle applicazioni in chiaro o cifrati (una sorta di secret).
Come nell'esempio precedente, è possibile impostare un ARN di AWS Parameter Store come valore di una variabile d'ambiente. secrets-init risolverà il valore della variabile d'ambiente, sulla base dell'ARN specificato, restituendo il valore del parametro referenziato.
Esempio di formato di AWS Systems Manager Parameter Store:
https://gist.github.com/9a7a83ec1659c391412557e5af340f42
Per recuperare i secret AWS da AWS Secrets Manager e da Parameter Store, secrets-init deve essere eseguito con un ruolo IAM autorizzato ad accedere ai secret desiderati.
Lo si può ottenere assegnando il ruolo IAM al Pod Kubernetes o al task ECS. Si veda il post sul blog EKS Introducing fine-grained IAM roles for service accounts.
È anche possibile assegnare il ruolo IAM all'istanza EC2 su cui gira il container, ma questa opzione è decisamente meno sicura e non è consigliata.
Integrazione con Google Secret Manager
Google Cloud ha rilasciato di recente un nuovo servizio per la gestione dei secret nel cloud: Google Secret Manager
È possibile impostare il nome di un secret Google come valore di una variabile d'ambiente, utilizzando il prefisso riconosciuto da secrets-init (gcp:secretmanager:) seguito dal nome del secret (projects/{PROJECT_ID}/secrets/{SECRET_NAME} oppure projects/{PROJECT_ID}/secrets/{SECRET_NAME}/versions/{VERSION}). secrets-init risolverà il valore della variabile d'ambiente, sulla base del nome specificato, restituendo il valore del secret referenziato.
https://gist.github.com/65d46eb2b1fe44417a9d91828c94712d
Per recuperare i secret Google da Google Secret Manager, secrets-init deve essere eseguito con un ruolo IAM autorizzato ad accedere ai secret desiderati.
Lo si può ottenere assegnando il ruolo IAM al Pod Kubernetes tramite Workload Identity. È anche possibile assegnare il ruolo IAM all'istanza GCE su cui gira il container, ma questa opzione è meno sicura.
(15–03–2020) Aggiornamento: Kubernetes Admission Webhook
Il progetto kube-secrets-init implementa un admission webhook Kubernetes che inietta un initContainer in qualsiasi Pod con riferimenti espliciti (variabili d'ambiente) o impliciti (Secrets e ConfigMaps di Kubernetes) a secret nel cloud.
Link utili
- Kubernetes GKE Workload Identity – post sul blog DoiT
- doitintl/secrets-init – repository GitHub
- kube-secrets-init – repository GitHub dell'admission webhook Kubernetes
Conclusioni
Mi auguro che questo articolo le sia utile. Resto a disposizione per commenti e domande.
Vuole leggere altri contenuti? Visiti il nostro blog o segua Alexei su Twitter.