Vai al paragrafo

Introduzione alla sicurezza di Kubernetes

Copia URL

Nonostante l'adozione di questi sistemi sia in crescita, quando si parla di container e Kubernetes la principale preoccupazione rimane la sicurezza. La buona notizia è che ci sono molti accorgimenti che puoi prendere per rendere più sicura l'implementazione dei container. Questa introduzione alla protezione di Kubernetes descrive molte delle misure che puoi adottare per fare il primo passo con la sicurezza dei container.

Le immagini dei container sono spesso una fonte primaria delle vulnerabilità che possono essere introdotte negli ambienti cloud native. Uno degli aspetti fondamentali di una strategia per la sicurezza efficace è garantire l'aderenza alle pratiche di creazione di immagini sicure in tutta l'organizzazione. Sebbene la scansione delle immagini sia una parte importante del profilo di sicurezza di un'organizzazione, la protezione delle immagini è un metodo per garantire in modo proattivo la sicurezza delle applicazioni containerizzate nelle prime fasi del ciclo di vita dell'applicazione.

Adotta le seguenti best practice per creare immagini dei container in sicurezza:

  1. Usa immagini di base minime

    L'immagine dovrebbe contenere solo le librerie e gli strumenti necessari al container per ridurre la superficie di attacco.

  2. Usa immagini di base provenienti da fonti attendibili

    Se non stai creando un'immagine da zero, scegli immagini di base che provengono da una fonte attendibile. Dovresti essere in grado di vedere il Dockerfile e il codice sorgente di tutti i componenti dell'immagine, che dovrebbe essere ospitata in un registro affidabile. Le immagini di base dovrebbero inoltre essere aggiornate spesso.

  3. Specifica un utente

    Se il Dockerfile non specifica un utente, il container verrà eseguito per impostazione predefinita con l'utente root; questo espande la potenziale superficie di attacco e fornisce un percorso facile per l'escalation dei privilegi se l'applicazione viene compromessa.

  4. Verifica le immagini del Docker

    Garantire l'autenticità delle immagini non è semplice, ma è una componente importante della creazione di immagini sicure. Tutte le immagini di base devono essere firmate e convalidate. Estrarre immagini solo da registri attendibili è un modo per garantire che siano tutte autentiche.

  5. Esegui una scansione alla ricerca di vulnerabilità

    È importante trovare e correggere le vulnerabilità che esistono all'interno delle immagini dei container, comprese quelle introdotte dalle librerie open source.

  6. Non includere i segreti

    I segreti, che comprendono dati sensibili come credenziali e chiavi, non devono essere incorporati nelle immagini dei container.

  7. Imposta dei limiti per le risorse

    Ridurre la quantità di risorse di CPU o di memoria a cui un container può accedere aiuta a minimizzare i danni causati da un eventuale utilizzo inappropriato.

  8. Limita i privilegi

    Imposta i privilegi del container in modo che siano il più restrittivi possibile e configura il container per assicurarti che non sia possibile effettuare un'escalation dei privilegi.

  9. Utilizza build in più fasi

    È possibile sfruttare gli strumenti di compilazione utilizzati per generare e compilare applicazioni quando vengono eseguiti su sistemi di produzione. Invece di utilizzare le stesse immagini nella fase di compilazione ed esecuzione, utilizza Dockerfile multifase per eliminare gli strumenti di compilazione non necessari dalle immagini di runtime. Anche i debugger dovrebbero essere rimossi dalle immagini di produzione.

  10. Usa tecniche di programmazione incentrate sulla sicurezza

    A questo scopo è possibile utilizzare un linter per rilevare il codice non sicuro durante il processo di sviluppo.

Sebbene questi passaggi siano specifici per il processo di creazione delle immagini, i principi alla base della creazione di immagini sicure dovrebbero essere applicati anche alle pratiche di sicurezza in altre parti dell'applicazione. Tali pratiche includono ridurre il più possibile le dimensioni della superficie di attacco, limitare i privilegi e rafforzare le configurazioni invece di utilizzare le impostazioni predefinite di Kubernetes e altri aspetti dello stack cloud native.

Benchmark CIS per Kubernetes

Il Center for Internet Security (CIS) crea le best practice per la sicurezza informatica. Il CIS utilizza il crowdsourcing per definire le proprie raccomandazioni sulla sicurezza. I benchmark CIS sono tra i suoi strumenti più popolari.

Le organizzazioni possono utilizzare il benchmark CIS per Kubernetes per rafforzare i propri ambienti Kubernetes. Sono disponibili numerosi strumenti open source e commerciali che confrontano automaticamente le impostazioni e i controlli delineati nel benchmark CIS per identificare le configurazioni non sicure.

Il benchmark CIS fornisce una serie di utili controlli della configurazione, ma le organizzazioni dovrebbero considerarli un punto di partenza e adottare altre misure per garantire che vengano applicate a Kubernetes le procedure ottimali, inclusa l'implementazione di policy di rete, impostazioni di controllo degli accessi basato sui ruoli (RBAC), privilegi di amministrazione e altre protezioni per il server dell'API Kubernetes.

Il controllo degli accessi basato sui ruoli (RBAC) di Kubernetes fornisce il metodo standard per la gestione dell'autorizzazione per gli endpoint dell'API Kubernetes. La configurazione dell'RBAC del cluster controlla quali soggetti possono eseguire determinati verbi e su quali tipi di risorse e in quali spazi dei nomi. Ad esempio, una configurazione potrebbe concedere all'utente "alice" l'accesso per visualizzare le risorse di tipo "pod" nello spazio dei nomi external-api. L'API RBAC include 4 oggetti dichiarativi: Role, ClusterRole, RoleBinding e ClusterRoleBinding.

L'oggetto Role indica le risorse con spazio dei nomi costituite da regole che impostano le autorizzazioni per i singoli spazi dei nomi, mentre l'oggetto ClusterRole indica risorse senza spazio dei nomi che concedono autorizzazioni a livello di cluster o autorizzazioni che si estendono su più spazi dei nomi. Ogni regola è una combinazione di verbi, tipi di risorse e selettori dello spazio dei nomi.

Un'associazione di ruoli è il ponte che lega un utente, un gruppo di utenti o un account di servizio (noti anche come soggetti) a un ruolo e concede a tali utenti le autorizzazioni definite in quel ruolo. Un'associazione di ruoli del cluster lega un ClusterRole a tutti gli spazi dei nomi nel cluster. In questo modo, un RoleBinding assegna le autorizzazioni all'interno di uno spazio dei nomi, mentre un ClusterRoleBinding concede tali autorizzazioni a tutto il cluster.

Sulla base della nostra esperienza con i clienti, abbiamo scoperto i seguenti cinque errori più comuni da individuare nelle impostazioni di configurazione RBAC.

 

Errore di configurazione n. 1:Ruolo di amministratore del cluster concesso inutilmente

Il ruolo di amministratore del cluster integrato concede accesso illimitato al cluster. Durante la transizione dal controller ABAC in uso a RBAC, alcuni amministratori e utenti potrebbero aver replicato la configurazione permissiva di ABAC concedendo ampie autorizzazioni per l'amministrazione del cluster, trascurando gli avvisi nella documentazione pertinente. Se agli utenti o ai gruppi viene regolarmente concesso il ruolo di amministratore del cluster, eventuali errori o compromissioni dell'account possono avere conseguenze pericolose e di ampia portata. Anche gli account di servizio in genere non necessitano di questo tipo di accesso. In entrambi i casi, dovrebbe essere creato un ruolo cluster o un ruolo più personalizzato e concesso solo agli utenti specifici che ne hanno bisogno.

Errore di configurazione n. 2:Uso improprio dell'aggregazione dei ruoli

In Kubernetes 1.9 e versioni successive, l'aggregazione dei ruoli può essere utilizzata per semplificare le concessioni di privilegi consentendo l'aggiunta di nuovi privilegi ai ruoli esistenti. Tuttavia, se queste aggregazioni non vengono esaminate attentamente, possono modificare l'uso previsto di un ruolo. Ad esempio, il ruolo system:view potrebbe aggregare in modo improprio regole con verbi diversi da view violando l'intenzione originale, ovvero che i soggetti a cui è stato concesso tale ruolo non potessero mai modificare il cluster.

Errore di configurazione n. 3:Concessione di ruoli duplicati

Le definizioni dei ruoli possono sovrapporsi tra loro, dando ai soggetti lo stesso accesso in vari modi. Gli amministratori a volte permettono che si verifichi questa sovrapposizione intenzionalmente, ma questa configurazione può rendere più difficile capire a quali soggetti sono concessi gli accessi. Questa situazione può rendere più difficile la revoca dell'accesso se un amministratore non si rende conto che più associazioni di ruolo concedono gli stessi privilegi.

Errore di configurazione 4:Ruolo inutilizzato

I ruoli che vengono creati ma non concessi a nessun soggetto possono aumentare la complessità della gestione del metodo RBAC. Allo stesso modo, i ruoli concessi solo a soggetti che non esistono (come gli account di servizio negli spazi dei nomi eliminati o gli utenti che hanno lasciato l'organizzazione) possono rendere difficile la visualizzazione delle configurazioni importanti. La rimozione di questi ruoli inutilizzati o inattivi è in genere sicura e consente di concentrare l'attenzione sui ruoli attivi.

Errore di configurazione n. 5:Assegnazione di ruoli mancanti

Le associazioni di ruolo possono fare riferimento a ruoli che non esistono. Se lo stesso nome di ruolo viene riutilizzato per uno scopo diverso in futuro, queste associazioni di ruolo inattive possono concedere improvvisamente e inaspettatamente privilegi a soggetti diversi da quelli previsti da chi crea il nuovo ruolo.

 

La corretta configurazione dei ruoli e delle associazioni RBAC del cluster aiuta a ridurre al minimo l'impatto causato da compromissioni delle applicazioni, acquisizioni di account utente, bug delle applicazioni o semplici errori umani.

Sicurezza di container e Kubernetes sicurezza delle macchine virtuali (VM) a confronto

Le macchine virtuali (VM) e i container hanno architetture fondamentalmente diverse, sebbene presentino abbastanza somiglianze da causare confusione. Le differenze tra container e macchine virtuali hanno ramificazioni molto importanti nell'ambito della sicurezza. Sia le macchine virtuali che i container forniscono isolamento a vari livelli ed entrambi consentono la portabilità. Le macchine virtuali sono completamente autosufficienti, dispongono di un proprio sistema operativo, e non condividono risorse con altre macchine virtuali. I container condividono gli host con altri container, rendendo così più complicata la definizione di un confine sicuro.

I container e Kubernetes presentano un diverso paradigma architetturale che richiede un diverso approccio alla sicurezza. Le tecniche consolidate per la sicurezza basata su host non vengono trasferite ai container. Anche altre tecniche di sicurezza del dominio host o VM, come la creazione di firewall di rete attorno a un perimetro definito, non si applicano ai container. Inoltre, un elemento fondamentale delle best practice per la sicurezza delle macchine virtuali è l'applicazione di patch di sicurezza. Tuttavia, le patch non possono essere applicate a un container in esecuzione, ma è necessario aggiornare l'immagine del container e ricrearlo.

Per proteggere i container è necessario:

  • controllare le connessioni tra i container
  • assicurare che i container siano privi di vulnerabilità note
  • impedire ai container di avere accesso root
  • limitare le autorizzazioni e l'accesso solo a ciò che è necessario per il funzionamento dell'applicazione

Kubernetes aggiunge un ulteriore livello di complessità e introduce ulteriori potenziali rischi per la sicurezza. La gestione delle configurazioni e delle policy di rete Kubernetes è fondamentale per un solido approccio alla sicurezza delle applicazioni containerizzate.

Inoltre, le modifiche al flusso di lavoro che derivano dal passaggio alle applicazioni containerizzate rendono più importante l'integrazione della sicurezza durante l'intero ciclo di vita. La sicurezza deve essere integrata nell'applicazione dall'inizio, a partire dalla configurazione delle immagini e dei container. Non è possibile aggiungere misure di sicurezza a un'applicazione containerizzata alla fine del processo di sviluppo, subito prima del deployment.

La sicurezza nelle applicazioni containerizzate richiede il controllo dell'origine di tutti i componenti, inclusi gli elementi open source, la gestione delle configurazioni, la scansione delle immagini e l'attivazione di controlli dell'accesso basati sul ruolo granulari. I container e Kubernetes impongono un approccio diverso alla sicurezza, ma data la loro natura dichiarativa e immutabile, offrono l'opportunità, se configurati correttamente, di creare le applicazioni più sicure di sempre.

In Kubernetes, i container vengono eseguiti all'interno dei pod, uno dei numerosi oggetti Kubernetes, e la configurazione di runtime di ciascun pod può essere impostata e applicata utilizzando una combinazione di contesto di sicurezza nella specifica del pod, criteri di sicurezza del pod (PSP) o un controller di ammissione come Open Policy Agent (OPA) Gatekeeper.

Il contesto di sicurezza è definito nel manifest di deployment e consente di definire il requisito esatto per ogni carico di lavoro. Può essere configurato per un Pod o un Container. I criteri di sicurezza dei pod sono una risorsa Kubernetes a livello di cluster che controlla il contesto di sicurezza con cui i pod possono essere eseguiti. Se i criteri PSP sono abilitati per un cluster, qualsiasi tentativo di creare un pod che non aderisce al PSP associato verrà rifiutato dal controller di ammissione del PSP.

Limita i privilegi di runtime del container:

  • Non eseguire i processi dell'applicazione come root. Imposta runAsUser su MustRunAsNonRoot
  • Non consentire l'escalation dei privilegi. Imposta allowPrivilegeEscalation su false
  • Usa un filesystem root di sola lettura. Imposta readOnlyRootFilesystem su true
  • Usa il montaggio del filesystem predefinito (mascherato) /proc.
  • Non utilizzare la rete host o lo spazio di elaborazione. Imposta hostPID, hostNetwork e hostIPC su false
  • Elimina le funzionalità Linux inutilizzate e non aggiungere funzionalità opzionali che la tua applicazione non richiede assolutamente
  • Usa le opzioni SELinux per controlli di processo più dettagliati
  • Assegna a ogni applicazione il proprio account di servizio Kubernetes
  • Non montare le credenziali dell'account di servizio in un container se non è necessario accedere all'API Kubernetes

 

Usa spazi dei nomi Kubernetes

Gli spazi dei nomi Kubernetes forniscono l'ambito per gli oggetti cluster, consentendo una gestione granulare degli oggetti cluster. Container/pod, servizi e deployment all'interno di uno spazio dei nomi possono essere isolati utilizzando controlli come i criteri di rete Kubernetes o avere il loro accesso limitato utilizzando il controllo degli accessi basato sui ruoli di Kubernetes (RBAC).

Pianifica come vuoi assegnare gli spazi dei nomi prima di iniziare a distribuire i carichi di lavoro nei cluster. L'utilizzo di uno spazio dei nomi per applicazione offre la migliore opportunità di controllo, sebbene comporti un carico di gestione aggiuntivo durante l'assegnazione dei privilegi del ruolo RBAC e dei criteri di rete predefiniti. Se decidi di raggruppare più di un'applicazione in uno spazio dei nomi i criteri principali da tenere in considerazione sono i seguenti: determina se tali applicazioni hanno requisiti RBAC comuni e se è sicuro concedere tali privilegi agli account di servizio e agli utenti che necessitano dell'accesso all'API Kubernetes in quello spazio dei nomi.

In generale, la gestione della configurazione è la pratica ingegneristica di stabilire i criteri relativi alle configurazioni e assicurare che tali criteri vengano applicati in modo coerente nell'organizzazione, durante tutto il ciclo di vita dell'applicazione. Le configurazioni rivestono un ruolo fondamentale nella gestione dei rischi per la sicurezza nelle applicazioni cloud native, soprattutto perché molte configurazioni predefinite per container e Kubernetes non sono sicure. Le configurazioni errate sono la fonte più comune di rischio per la sicurezza nelle applicazioni containerizzate in esecuzione su Kubernetes.

La gestione della configurazione deve essere automatizzata, con protezioni gestite centralmente in modo che i singoli sviluppatori o operatori non siano responsabili della configurazione manuale dei carichi di lavoro. Queste protezioni dovrebbero essere basate sui criteri di sicurezza dell'organizzazione.

Secondo IBM, il 95% degli errori di sicurezza del cloud è causato da errori umani. Con l'aumentare della complessità delle applicazioni in esecuzione su sistemi distribuiti in container e Kubernetes, cresce anche il rischio di configurazioni errate. In assenza di uno strumento di gestione della configurazione centralizzato, è quasi impossibile per le organizzazioni garantire che i criteri di configurazione vengano applicati in modo coerente. Per le aziende con una configurazione multicloud o di cloud ibrido, definire una configurazione corretta in modo coerente è ancora più difficile, perché ogni ambiente richiede un diverso set di configurazioni. Esistono inoltre persistenti lacune nelle competenze di sviluppatori e operatori, i quali non sono sempre a conoscenza delle migliori pratiche per impostare una configurazione sicura.

In molti casi il modo più semplice per gli sviluppatori di impostare le configurazioni per l'esecuzione delle applicazioni è anche il meno sicuro, come consentire l'accesso root, concedere privilegi di amministratore o impostare limiti di risorse molto elevati. Con gli strumenti giusti, la gestione della configurazione può essere integrata nel flusso di lavoro DevOps in modo da non rallentare la velocità di sviluppo. Si tratta di una best practice, perché consente di trovare un equilibrio tra la necessità di distribuire rapidamente e quella di proteggere le configurazioni del carico di lavoro.

La gestione della configurazione dovrebbe includere le modalità sia per ottenere visibilità sulle configurazioni sia per definire quali configurazioni sono consentite, in modo che le build non sicure o i deployment rischiosi possano essere scartati automaticamente. Le organizzazioni devono disporre di un'unica interfaccia per vedere tutte le configurazioni rilevanti su container e Kubernetes ed essere avvisate della presenza di configurazioni potenzialmente rischiose.

I capisaldi della gestione della configurazione per container e Kubernetes sono i seguenti:

  • Controlli degli accessi basato sui ruoli (RBAC). Le organizzazioni devono essere in grado di individuare le configurazioni eccessivamente permissive e/o i ruoli non necessari.
  • Segreti. Un buon strumento di gestione della configurazione può limitare in modo proattivo l'accesso ai segreti.
  • Valutazioni basate su criteri. L'impostazione dei criteri di sicurezza dell'organizzazione è una parte cruciale di qualsiasi approccio alla sicurezza e dovrebbe esserci un modo per verificare i deployment rispetto a tali criteri predeterminati.
  • Privilegi. I privilegi di accesso dovrebbero essere assegnati in base ai principi del privilegio minimo.
  • Limiti delle risorse. Sia i container che i cluster Kubernetes dovrebbero avere limiti sulla CPU e sulla memoria disponibili.
  • Criteri di rete. I criteri di rete dovrebbero limitare il più possibile la comunicazione tra le parti dell'applicazione per limitare i potenziali danni in caso di compromissione di un container.

Il modo più semplice per iniziare con la gestione della configurazione è seguire le best practice accettate dal settore come i benchmark CIS. Con l'avanzare dell'adozione dei container da parte dell'organizzazione, la creazione di criteri di governance organizzativa per la gestione della configurazione è una best practice. La gestione della configurazione dovrebbe coprire le configurazioni sia dei container sia di Kubernetes, poiché le configurazioni devono essere gestite in modo appropriato in entrambi i sistemi per garantire un solido profilo di sicurezza.

Per impostazione predefinita, Kubernetes consente a tutti i pod all'interno di un cluster di comunicare liberamente. Ciò semplifica le operazioni delle applicazioni, ma crea anche un rischio per la sicurezza. Sebbene le impostazioni predefinite siano eccessivamente permissive, Kubernetes dispone anche di funzionalità di imposizione integrate che possono essere configurate per limitare la comunicazione tra le risorse. La segmentazione della rete è una componente della limitazione della comunicazione tra le parti del deployment. La segmentazione della rete è richiesta anche da alcuni framework di conformità, incluso PCI-DSS.

La segmentazione della rete funziona suddividendo le reti in sottoreti più piccole. Dal punto di vista della sicurezza, il vantaggio principale è che se un utente malintenzionato ottiene l'accesso a un'applicazione in esecuzione sullo stesso cluster Kubernetes con altre applicazioni, la segmentazione della rete impedisce a tale utente di accedere a tutte le app del cluster. È anche un modo per isolare da altre parti dell'applicazione i carichi di lavoro sensibili e/o quelli che rientrano nell'ambito di un particolare framework di conformità.

I criteri di rete dovrebbero essere il più restrittivi possibile, consentendo ai singoli container di comunicare solo con i container necessari affinché l'applicazione funzioni come previsto.

In Kubernetes, la segmentazione della rete viene eseguita applicando i relativi criteri, sia tramite le capacità di imposizione della rete nativa di Kubernetes, sia utilizzando livelli di infrastruttura aggiuntivi come una service mesh.

Per impostazione predefinita, non ci sono restrizioni alla comunicazione tra pod, container e nodi, né all'interno dello stesso spazio dei nomi né tra spazi dei nomi. L'adozione di criteri di rete per limitare la comunicazione, in genere a partire da criteri che negano tutte le comunicazioni, è un buon punto di partenza nell'ambito delle best practice. Poiché i pod devono comunicare tra loro, è meglio elencare sistematicamente gli altri pod con cui un determinato pod deve comunicare. Anche l'ingresso e l'uscita dall'Internet pubblico dovrebbero essere consentiti in base a un elenco di elementi consentiti, solo per i pod che ne hanno bisogno.

Esiste anche un rischio operativo associato alla modifica dei criteri di rete e all'aumento della segmentazione della rete. L'utilizzo di uno strumento per visualizzare l'impatto delle modifiche ai criteri di rete a livello di sistema sull'applicazione può aiutare a ridurre al minimo il rischio di conseguenze impreviste derivanti dalla modifica dei criteri di rete.

Nessuna organizzazione avrà mai un'applicazione o un'infrastruttura IT perfettamente sicura. La sicurezza richiede una definizione delle priorità e la comprensione dei rischi e dei compromessi associati alle diverse azioni. La profilazione del rischio è il processo di definizione dei rischi per la sicurezza noti dell'organizzazione e delle sue politiche e pratiche relative alla gestione di tali rischi. Ogni organizzazione deve accettare un certo livello di rischio, ma dovrebbe valutare con chiarezza qual è quello accettabile. La profilazione del rischio dovrebbe essere eseguita non solo per l'organizzazione nel suo insieme, ma per le singole applicazioni. I carichi di lavoro sensibili o che rientrano nell'ambito dei requisiti di conformità hanno un profilo di rischio diverso rispetto ai carichi di lavoro non sensibili.

La profilazione del rischio aiuta anche a valutare l'importanza delle vulnerabilità esistenti nell'ambiente. Rispondere a ogni vulnerabilità sarebbe impossibile, quindi un profilo di sicurezza forte richiede la valutazione del rischio di ogni vulnerabilità al fine di dare la priorità alla correzione corretta.

In un'applicazione containerizzata distribuita, può essere difficile comprendere il profilo di rischio dell'applicazione e assegnarvi priorità. Potrebbero essere presenti centinaia di vulnerabilità in qualsiasi potenziale applicazione, ma non tutte le vulnerabilità hanno lo stesso rischio. Il rischio per la sicurezza derivante da una vulnerabilità dipende da fattori quali:

  • la gravità della vulnerabilità
  • se l'applicazione è rivolta al pubblico o meno
  • se l'applicazione è in produzione
  • se l'applicazione rientra nell'ambito delle normative di conformità
  • se l'applicazione accede o meno a dati sensibili
  • il livello di privilegio del container
  • l'esposizione alla rete del container

Mentre le organizzazioni dovrebbero definire in anticipo quale livello di rischio è accettabile, spesso stabilendo criteri interni sulla velocità con cui devono essere risolte le vulnerabilità a ciascun livello di gravità, la profilazione del rischio non è un esercizio statico. Il processo di valutazione dei rischi per la sicurezza, in particolare nel contesto di un'applicazione containerizzata, deve avvenire continuamente durante il runtime.

La valutazione manuale di potenziali incidenti di sicurezza, vulnerabilità e criteri conduce inevitabilmente a errori e burnout. Soprattutto su larga scala, la profilazione del rischio di fatto spesso non è possibile senza affidarsi a strumenti automatizzati per individuare i rischi per la sicurezza e definirne le priorità. Una corretta profilazione del rischio in Kubernetes dovrebbe utilizzare i dati dichiarativi e contestuali di Kubernetes per automatizzare il processo di definizione delle priorità. Ciò consente ai team di sicurezza di concentrarsi innanzitutto sulla correzione dei deployment a rischio più elevato invece di dedicare tempo al processo di profilazione del rischio.

Idealmente, la profilazione del rischio può essere utilizzata sia come strumento reattivo che proattivo. Quando i rischi vengono rilevati e risolti in un deployment, tali informazioni possono essere utilizzate per trovare altri deployment con fattori di rischio simili e affrontare così in anticipo e in modo proattivo i potenziali rischi per la sicurezza.

La sicurezza del runtime è una linea di difesa fondamentale contro gli aggressori. Idealmente, le vulnerabilità senza patch, le configurazioni o le credenziali non sicure dovrebbero essere rilevate durante la fase di creazione o deployment. In realtà, tuttavia, il rilevamento e la risposta durante il runtime sono essenziali perché a volte le vulnerabilità sfuggono al rilevamento durante le fasi precedenti e perché vengono scoperte di continuo nuove vulnerabilità. È anche importante per motivi di conformità e come linea di difesa contro le minacce interne.

I carichi di lavoro dichiarativi e immutabili richiedono un modello completamente nuovo per rilevare e rispondere a potenziali incidenti di sicurezza in fase di runtime. Il fatto che i container generalmente eseguano un numero minimo di processi, combinato con la natura dichiarativa di Kubernetes, rende alcuni aspetti della sicurezza del runtime più semplici rispetto alle applicazioni basate su macchine virtuali (VM). D'altra parte, ai container in esecuzione non dovrebbero essere applicate patch di sicurezza allo stesso modo in cui queste verrebbero applicate a un'app basata su VM; dovrebbero invece essere trattati come immutabili ed essere interrotti, aggiornati e riavviati.

Il rilevamento è la componente fondamentale della sicurezza del runtime. Ciò comporta la ricerca di una baseline per il comportamento dell'applicazione e l'analisi di qualsiasi attività che si discosti troppo dalla baseline. Tra le attività che potrebbero essere tracciate vi sono le richieste di rete e le esecuzioni di processi. Quando tali attività si discostano da quanto previsto, potrebbe essere un segno che sono potenzialmente sospette o dannose. Un esempio è provare a connettersi a Internet quando non è consentito. In ogni caso, questo tipo di comportamento anomalo indicherebbe un problema che deve essere approfondito.

Il rilevamento delle anomalie può essere più accurato nei container rispetto ai carichi di lavoro basati su VM, perché i container contengono solo un'applicazione, rendendo più semplice distinguere un comportamento baseline per un container da uno che non lo è. Il rilevamento delle anomalie, tuttavia, dovrebbe sempre essere collegato anche a un processo di risposta agli incidenti.

A seconda del tipo di comportamento anomalo, la migliore linea d'azione potrebbe essere quella di rispondere automaticamente, facendo in modo che la piattaforma interrompa i pod o i container colpiti. In altri casi, potrebbe essere più appropriato inviare un avviso e valutare manualmente il comportamento. Tuttavia, la potenziale risposta agli incidenti dovrebbe essere quanto più automatizzata possibile per ridurre al minimo i tempi di risposta e aumentare la sicurezza complessiva delle applicazioni containerizzate.

Il kubelet è il principale "agente del nodo" in esecuzione su ciascun nodo. Una configurazione errata può esporre a una serie di rischi per la sicurezza. Per impostare la configurazione del kubelet è possibile utilizzare argomenti sul file del kubelet in esecuzione o un file di configurazione del kubelet.

Per trovare il file di configurazione del kubelet, esegui il seguente comando:

ps -ef | grep kubelet | grep config

Cerca l'argomento --config, che indicherà la posizione del file di configurazione del kubelet.

Quindi esegui il seguente comando su ciascun nodo:

ps -ef | grep kubelet

Nell'output, verifica quanto segue:

l'argomento --anonymous-auth è visualizzato come false. Nell'articolo sul kubelet citato in precedenza, una delle configurazioni errate sfruttate era quella in cui le richieste anonime (e non autenticate) potevano essere servite dal server kubelet.

L'argomento --authorization-mode è visualizzato come AlwaysAllow se presente. Se non è presente, assicurati che ci sia un file di configurazione del kubelet specificato da --config e che nel file l'argomento authorization: mode sia impostato su un'opzione diversa da AlwaysAllow.

L'argomento --client-ca-file è presente e impostato sulla posizione del file dell'autorità di certificazione. Se non è presente, assicurati che sia presente un file di configurazione del kubelet specificato da --config e che nel file l'argomento authentication: x509: clientCAFile sia impostato sulla posizione del file dell'autorità di certificazione del client.

L'argomento --read-only-port è presente e impostato su 0. Se non è presente, assicurati che sia presente un file di configurazione del kubelet specificato da --config e che readOnlyPort sia impostato su 0 se presente.

--protect-kernel-defaults è visualizzato come true. Se non è presente, assicurati che sia presente un file di configurazione del kubelet specificato da --config, e che il file abbia impostato protectKernelDefaults su true.

L'argomento --hostname-override non è presente, per garantire che la configurazione TLS tra il kubelet e il server API non si interrompa.

L'argomento --event-qps è presente e impostato su 0. Se non è presente, assicurati che sia presente un file di configurazione del kubelet specificato da --config e che eventRecordQPS venga visualizzato come 0.

Gli argomenti --tls-cert-file e --tls-private-key-file sono impostati in modo corretto o il file di configurazione del kubelet specificato in --config contiene le impostazioni appropriate per tlsCertFile e tlsPrivateKeyFile. Questa configurazione garantisce che tutte le connessioni avvengano tramite il protocollo TLS sui kubelet.

Gli argomenti RotateKubeletServerCertificate e --rotate-certificates sono impostati su true se i kubelet ottengono i certificati dal server API e assicurati che il kubelet utilizzi solo cifrature crittografiche forti.

Il server API Kubernetes gestisce le chiamate API REST da utenti o applicazioni in esecuzione all'interno del cluster per abilitare la gestione del cluster. Considerato il gateway per il piano di controllo Kubernetes, puoi accedere al server API utilizzando kubectl, librerie client o effettuando richieste API direttamente. Un modo per gestire l'autorizzazione per il server API Kubernetes è utilizzare il controllo degli accessi basato sui ruoli (RBAC) di Kubernetes. Puoi anche convalidare le richieste al server API utilizzando i controller di ammissione.

La protezione del server API inizia con il controllo del suo accesso. Il Center for Internet Security (CIS) fornisce le migliori pratiche di configurazione per rafforzare e proteggere il server API.

Esegui il comando seguente sul nodo principale:

ps -ef | grep kube-apiserver

Nell'output, verifica quanto segue:

l'argomento --anonymous-auth viene visualizzato come false. Questa impostazione garantisce che le richieste non rifiutate da altri metodi di autenticazione non vengano trattate come anonime e quindi consentite in base ai criteri.

L'argomento --basic-auth-file non è presente. L'autenticazione di base utilizza credenziali con testo normale, invece dei token o certificati preferiti, per l'autenticazione.

L'argomento --insecure-allow-any-token non è presente. Questa impostazione assicurerà che siano consentiti solo i token protetti autenticati.

L'argomento –kubelet-https non è presente o viene visualizzato come true. Questa configurazione garantisce che le connessioni tra il server API e i kubelet siano protette in transito tramite il protocollo Transport Layer Security (TLS).

L'argomento --insecure-bind-address non è presente. Questa configurazione impedirà al server API di collegarsi a un indirizzo non sicuro, impedendo l'accesso non autenticato e non crittografato al nodo principale, riducendo così al minimo il rischio che gli aggressori possano leggere dati sensibili in transito.

L'argomento --insecure-port viene visualizzato come 0. Questa impostazione impedirà al server API di servire su una porta non sicura, il che impedirebbe l'accesso non autenticato e non crittografato al nodo principale e ridurrebbe al minimo il rischio che un utente malintenzionato prenda il controllo del cluster.

L'argomento --secure-port non esiste oppure viene visualizzato come numero intero compreso tra 1 e 65535. L'obiettivo in questo caso è assicurarsi che tutto il traffico sia servito su https con autenticazione e autorizzazione.

L'argomento --profiling viene visualizzato come false. A meno che tu non stia riscontrando colli di bottiglia o debba risolvere un problema, non è necessario il profiler e averlo inutilmente fa correre il rischio di esporre i dettagli del sistema e del programma.

L'argomento --repair-malformed-updates viene visualizzato come false. Questa impostazione assicurerà che le richieste intenzionalmente malformate provenienti dai client vengano rifiutate dal server API.

L'argomento --enable-admission-plugins è impostato con un valore che non contiene AlwaysAdmit. Se configuri questa impostazione in modo dare sempre l'ammissione ("AlwaysAdmit"), le richieste verranno ammesse anche se non sono esplicitamente consentite dall'apposito plugin di controllo, il che ne ridurrebbe l'efficacia.

L'argomento --enable-admission-plugins è impostato con un valore che contiene AlwaysPullImages. Questa configurazione garantisce che gli utenti non siano autorizzati a estrarre immagini dal nodo per inviarle a qualsiasi pod semplicemente conoscendo il nome dell'immagine. Con questo controllo abilitato, le immagini verranno sempre estratte prima di avviare un container, un'operazione che richiederà credenziali valide.

L'argomento --enable-admission-plugins è impostato con un valore che contiene SecurityContextDeny. Questo controllo garantisce che non sia possibile personalizzare il contesto di sicurezza a livello di pod in un modo non indicato nel criterio di sicurezza del pod.

L'argomento --disable-admission-plugins è impostato con un valore che non contiene NamespaceLifecycle. È consigliabile non disabilitare questo controllo, perché assicura che gli oggetti non vengano creati in spazi dei nomi inesistenti o in spazi dei nomi impostati per essere terminati.

L'argomento --audit-log-path è impostato su un percorso appropriato in cui si desidera memorizzare i log di audit. È sempre una buona pratica di sicurezza abilitare il controllo per qualsiasi componente Kubernetes, quando disponibile, incluso il server API Kubernetes.

L'argomento --audit-log-maxage è impostato su 30 o su qualsiasi numero di giorni in cui è necessario archiviare i file dei log di audit in conformità con i criteri di conservazione dei dati interni ed esterni.

L'argomento --audit-log-maxbackup è impostato su 10 o su qualsiasi numero che aiuti a soddisfare i requisiti di conformità per la conservazione della quantità di vecchi file di log.

L'argomento --audit-log-maxsize è impostato su 100 o su qualsiasi numero che aiuti a soddisfare i requisiti di conformità. Si noti che il numero 100 rappresenta 100 MB.

L'argomento --authorization-mode è presente e non è impostato su AlwaysAllow. Questa impostazione garantisce che solo le richieste autorizzate siano consentite dal server API, in particolare nei cluster di produzione.

L'argomento --token-auth-file non è presente. Questo argomento, quando presente, utilizza l'autenticazione basata su token statico, che presenta diversi difetti di sicurezza; si consiglia di utilizzare invece metodi di autenticazione alternativi, come i certificati.

L'argomento --kubelet-certificate-authority è presente. Questa impostazione aiuta a prevenire un attacco man-in-the-middle quando c'è una connessione tra il server API e il kubelet.

Gli argomenti --kubelet-client-certificate e --kubelet-client-key sono presenti. Questa configurazione garantisce che il server API si autentichi negli endpoint HTTPS del kubelet (per impostazione predefinita, il server API non esegue questo passaggio).

L'argomento --service-account-lookup è presente e impostato su true. Questa impostazione aiuta a prevenire un'istanza in cui il server API verifica solo la validità del token di autenticazione senza garantire che il token dell'account di servizio incluso nella richiesta sia presente in etcd.

L'argomento --enable-admission-plugins è impostato su un valore che contiene PodSecurityPolicy.

L'argomento --service-account-key-file è presente ed è impostato su una coppia di chiavi pubblica/privata separata per la firma dei token dell'account di servizio. Se non specifichi una coppia di chiavi pubblica/privata, utilizzerà la chiave privata dal certificato di servizio TLS, il che impedirebbe di ruotare le chiavi per i token dell'account di servizio.

Gli argomenti --etcd-certfile e --etcd-keyfile sono presenti in modo che il server API si identifichi nel server etcd utilizzando il certificato client e la chiave. Tieni presente che il server etcd memorizza oggetti che sono probabilmente di natura sensibile, pertanto qualsiasi connessione client deve utilizzare la crittografia TLS.

L'argomento --disable-admission-plugins è impostato e non contiene ServiceAccount. Questa configurazione assicurerà che quando viene creato un nuovo pod, non utilizzerà un account di servizio predefinito all'interno dello stesso spazio dei nomi.

Gli argomenti --tls-cert-file e --tls-private-key-file sono presenti in modo tale che il server API serva solo il traffico HTTPS tramite TLS.

L'argomento --client-ca-file è presente per garantire che l'autenticazione TLS e del certificato client sia configurata per i deployment del cluster Kube.

L'argomento --etcd-cafile è presente ed è impostato in modo tale che il server API debba verificare se stesso sul server etcd tramite il file dell'autorità di certificazione SSL.

L'argomento --tls-cipher-suites è impostato in modo da utilizzare cifrature crittografiche forti.

L'argomento --authorization-mode è presente con un valore contenente Node. Questa configurazione limita gli oggetti che i kubelet possono leggere associati ai loro nodi.

L'argomento --enable-admission-plugins è impostato e contiene il valore NodeRestriction. Questo plugin assicura che un kubelet possa modificare solo il proprio oggetto API Node e gli oggetti API Pod associati al suo nodo.

L'argomento --encryption-provider-config è impostato sul file EncryptionConfig, il quale dovrebbe avere tutte le risorse necessarie. Questa impostazione garantisce che tutti gli oggetti API REST archiviati nell'archivio chiave-valore etcd siano crittografati quando inattivi.

Assicurati che sia utilizzato il provider di crittografia aescbc per tutte le risorse desiderate poiché è considerato il più potente.

L'argomento --enable-admission-plugins contiene il valore EventRateLimit per impostare un limite al numero di eventi accettati dal server API per l'ottimizzazione delle prestazioni del cluster.

L'argomento --feature-gates non è impostato con un valore contenente AdvancedAuditing=false. In altre parole, assicurati che il controllo avanzato non sia disabilitato per scopi di audit e indagine.

L'argomento --request-timeout non è impostato oppure è impostato su un valore appropriato (né troppo corto né troppo lungo). Il valore predefinito è 60 secondi.

L'argomento --authorization-mode esiste ed è impostato su un valore che include il controllo RBAC di Kubernetes.

Questa impostazione garantisce che il controllo RBAC sia attivato. Oltre alla semplice attivazione, dovresti seguire diversi altri consigli su come utilizzare al meglio RBAC, tra cui:

  • Evita di assegnare agli utenti il ruolo di amministratore del cluster perché conferisce poteri molto ampi sull'ambiente e dovrebbe essere usato con molta parsimonia, se proprio necessario.
  • Controlla le regole di aggregazione dei ruoli per assicurarti di utilizzarle correttamente.
  • Non concedere autorizzazioni duplicate ai soggetti perché può rendere più difficile la revoca dell'accesso.
  • Rimuovi regolarmente i ruoli inutilizzati.

La sfida della sicurezza con le impostazioni predefinite

Uno dei maggiori rischi che i container e Kubernetes presentano è che le configurazioni predefinite di nessuna delle due tecnologie sono sicure. Per ridurre il rischio che si verifichi un incidente di sicurezza occorre modificare le configurazioni predefinite in modo proattivo e coerente nell'intera organizzazione. Trascurare questo passaggio, per negligenza, carenza di conoscenze o la mancata inclusione di un passaggio di gestione della configurazione nei flussi di lavoro, porterà a carichi di lavoro inutilmente vulnerabili.

 

Impostazioni predefinite nei container

Molte impostazioni predefinite dei container, così come alcune pratiche comuni durante la loro creazione, possono rendere i container vulnerabili. Ecco alcuni passaggi a cui prestare attenzione durante la configurazione dei contenitori.

  • Specifica un utente. Se non viene specificato un utente, verrà utilizzato per impostazione predefinita l'utente root, fornendo potenzialmente al container l'accesso root all'host.
  • Verifica le immagini. Le impostazioni predefinite non impongono la verifica delle immagini, rendendo così possibile estrarre inconsapevolmente immagini compromesse.
  • Imposta limiti per le risorse. I limiti delle risorse possono essere configurati, ma non ci sono limiti predefiniti. Limitare la CPU e la memoria che un container può utilizzare aiuta a impedire che il container consumi grandi quantità di risorse se viene compromesso.
  • Installa strumenti e librerie in modo selettivo. Meno strumenti e librerie sono presenti nei container, meno ne avrà a disposizione un aggressore se ottiene l'accesso al container. Assicurati di non installare solo un set standard di strumenti in ogni container, ma piuttosto solo ciò che è effettivamente necessario.
  • Controlla l'accesso al registro consentendo gli elenchi. Oltre a garantire che tutte le immagini utilizzate provengano da fonti attendibili, l'accesso al registro deve essere strettamente controllato, idealmente solo consentendo gli elenchi di utenti attendibili.

Impostazioni predefinite in Kubernetes

Kubernetes fornisce inoltre molti strumenti per migliorare il profilo di sicurezza dell'organizzazione, ma devono essere configurati attivamente per fornire vantaggi in termini di sicurezza. Ecco alcuni elementi essenziali da controllare in Kubernetes.

  • Configura i controlli degli accessi basati sui ruoli (RBAC). RBAC è abilitato per impostazione predefinita in Kubernetes 1.6 e versioni successive, ma deve ancora essere configurato correttamente per fornire vantaggi. Idealmente, l'accesso dovrebbe essere fornito dallo spazio dei nomi, non dai cluster.
  • Usa gli spazi dei nomi. L'impostazione predefinita consiste nell'eseguire tutto nello stesso spazio dei nomi. Utilizza attivamente la separazione fornita dagli spazi dei nomi per isolare i carichi di lavoro l'uno dall'altro.
  • Utilizza i criteri di rete di Kubernetes. Poiché non sono disponibili criteri di rete configurati e pronti all'uso, le organizzazioni devono installare un plugin di rete per controllare il traffico in ingresso e in uscita dall'applicazione e configurare i criteri di conseguenza.
  • Abilita i log di audit. I log di audit generalmente non sono abilitati per impostazione predefinita, ma dovrebbero essere attivati per ottenere visibilità sulle chiamate API anomale e sugli errori di autorizzazione.

Il rischio dell'inazione

Di solito i team di sviluppo senza ampie competenze in materia sicurezza sono i primi a utilizzare container e Kubernetes. Ignorare la sicurezza, tuttavia, espone le organizzazioni a rischi indipendentemente dal tipo di infrastruttura che utilizzano.

Come accennato, ma è opportuno ripeterlo, le configurazioni sia dei container che di Kubernetes non sono sicure per impostazione predefinita. Le funzionalità di sicurezza native di Kubernetes devono essere configurate attivamente per fornire vantaggi in termini di sicurezza. Il modo più rapido e semplice per rendere attiva un'applicazione è spesso concederle troppi privilegi e/o impostare limiti di risorse molto più elevati di quelli necessari per l'applicazione o lasciare i valori predefiniti così come sono. Sebbene le organizzazioni possano essere tentate all'inizio di trascurare la sicurezza, in particolare mentre acquisiscono familiarità con container e Kubernetes, ciò le mette a serio rischio. Gli aggressori sono in grado di sfruttare le applicazioni containerizzate su Kubernetes con la stessa facilità con cui possono sfruttare le applicazioni tradizionali.

Il rischio principale di non agire è che l'applicazione venga compromessa da utenti malintenzionati. Quanto questo potrebbe essere catastrofico dipende dal settore dell'organizzazione, dal tipo di applicazione in uso e dall'ambito e dal tipo di violazione. Le probabilità che trascurando la sicurezza si verifichi un incidente dipendono anche da fattori come il fatto che l'applicazione sia collegata a Internet.

Non fare nulla per garantire la sicurezza delle applicazioni containerizzate rischia di rendere le applicazioni inutilmente vulnerabili. Ignorare la sicurezza porta a:

Vulnerabilità di sicurezza prive di patch. Nuove vulnerabilità di sicurezza vengono scoperte continuamente e alcune di esse hanno causato seri problemi. Sia la community open source che gli utenti malintenzionati verranno a conoscenza di queste vulnerabilità non appena vengono pubblicate: è quindi rischioso non riuscire a risolverle rapidamente.

Autorizzazioni troppo permissive. Sebbene il controllo degli accessi basato sui ruoli (RBAC) in Kubernetes sia abilitato per impostazione predefinita, spetta allo sviluppatore mettere in atto i controlli di accesso. Senza linee guida sulla sicurezza, gli sviluppatori spesso creano carichi di lavoro che hanno un accesso eccessivo.

Carichi di lavoro non isolati. Per impostazione predefinita, tutto può essere eseguito in un unico spazio dei nomi predefinito. L'uso degli spazi dei nomi per iniziare a isolare i carichi di lavoro è una best practice per la sicurezza di base. Senza un'attenzione consapevole a questo passaggio di sicurezza, non verrà definito un adeguato livello isolamento.

Nessun controllo sui criteri di rete. I criteri di rete Kubernetes possono aiutare le organizzazioni a controllare il traffico, ma richiedono un plugin di rete e la configurazione dei criteri.

Se si aspetta ad applicare i controlli di sicurezza, alla fine si otterranno pratiche di sicurezza disarticolate, ostacolando così la verifica, con il risultato di rallentare la velocità di sviluppo e aumentare il rischio di incidenti di sicurezza. È opportuno invece che le organizzazioni applichino i controlli di sicurezza in anticipo e spesso nel ciclo di vita dello sviluppo del software.

In quanto considerato principalmente un sistema di orchestrazione dei container, Kubernetes facilita la gestione dei container ma introduce anche potenziali vulnerabilità di sicurezza negli ambienti infrastrutturali. Le differenze tra la sicurezza dei container e Kubernetes e quella delle macchine virtuali, insieme a una costante carenza di competenze per quanto riguarda la sicurezza di Kubernetes, possono portare a rischi per la sicurezza non necessari.

Le best practice di sicurezza per Kubernetes, come tutte le best practice di sicurezza, includono sia procedure ottimali per rendere l'applicazione e l'infrastruttura più sicure, sia pratiche organizzative e culturali per ottenere un controllo centralizzato sulla sicurezza.

La creazione e l'applicazione di criteri di sicurezza nell'organizzazione è una best practice indipendentemente dallo stack tecnologico su cui si basa l'azienda. La sicurezza è un processo di gestione del rischio e non è possibile, ad esempio, fare affidamento sugli strumenti per decidere quanto rischio è accettabile per ciascuna applicazione. Questo tipo di decisione deve essere presa da persone che siano in grado di valutare quanto rischio è accettabile per l'organizzazione in generale, per le singole unità aziendali e per ogni applicazione.

Controllo centrale della sicurezza. In relazione al primo punto, le organizzazioni hanno bisogno di un modo per garantire che vengano seguite le politiche di sicurezza e governance impostate. I team centrali devono avere visibilità sulle configurazioni e le vulnerabilità nell'intera applicazione distribuita e devono avere un modo per visualizzare facilmente i potenziali problemi e di assegnare loro delle priorità. Inoltre, devono essere in grado di creare protezioni in modo che le persone ricevano un feedback istantaneo quando una configurazione rischiosa, un'immagine non sicura o altri potenziali rischi per la sicurezza fanno parte di una build.

Gestisci la sicurezza nelle fasi iniziali. Gestire la sicurezza nelle prime fasi del processo di sviluppo non solo aiuta a rimuovere il collo di bottiglia della verifica del profilo di sicurezza e a distribuire le applicazioni più rapidamente, ma riduce anche la probabilità di errori che espongono allo sfruttamento di una vulnerabilità o di una configurazione errata.

Utilizza l'automazione. Poiché il footprint di Kubernetes si estende a più cluster e centinaia di spazi dei nomi, la gestione delle configurazioni o il monitoraggio manuale del comportamento del runtime non è più possibile.

Esistono anche alcune best practice tecniche molto importanti e specifiche per rendere Kubernetes il più sicuro possibile.

  • Mantieni Kubernetes aggiornato. Poiché le patch di sicurezza non vengono sempre rilasciate per le versioni precedenti, è consigliabile eseguire una versione più recente supportata.
  • Controllo degli accessi basato sui ruoli. L'accesso deve essere sempre configurato in base ai privilegi minimi.
  • Limita le comunicazioni tra i pod. I limiti dovrebbero essere il più restrittivi possibile purché i pod funzionino come previsto.
  • Usa la segmentazione della rete. Ogni pod dovrebbe essere in grado di comunicare solo con le risorse interne o esterne di cui ha bisogno e rimanere isolato da tutte le altre risorse.

La gestione delle vulnerabilità è un componente fondamentale per proteggere le applicazioni. È il processo di identificazione, valutazione e correzione delle vulnerabilità della sicurezza in tutte le fasi del ciclo di vita dello sviluppo del software. La gestione delle vulnerabilità nelle applicazioni containerizzate e cloud native deve essere automatizzata e integrata nei processi DevOps di creazione e distribuzione delle applicazioni. L'ambiente è troppo complesso per gestire manualmente le vulnerabilità e, in uno scenario reale, se la gestione rallenta troppo la velocità di sviluppo, le organizzazioni saranno tentate di ignorare le misure di sicurezza.

La gestione delle vulnerabilità non è un singolo passaggio a cui sottoporre l'applicazione, ma piuttosto un processo continuo che inizia con la scansione e l'introspezione delle immagini in fase di creazione e continua per tutto il ciclo di vita dell'applicazione, negli ambienti di test e di produzione.

La scansione delle immagini e l'implementazione di policy relative alle vulnerabilità delle immagini durante la fase di creazione sono i primi passi verso un'efficace gestione delle vulnerabilità native dei container. La possibilità di eseguire scansioni su richiesta, durante la creazione delle immagini o una volta che i container sono in esecuzione, è importante per essere in grado di individuare le vulnerabilità che potrebbero essere state esposte durante il runtime. La gestione delle vulnerabilità deve essere in grado di individuare l'esposizione sia nei container che in Kubernetes, poiché entrambi gli ambienti possono essere fonte di vulnerabilità.

Non esiste un'applicazione completamente sicura e una buona gestione delle vulnerabilità consente ai team non solo di vedere le vulnerabilità, ma fornisce anche informazioni aggiuntive utili per assegnare priorità alla criticità specifica per l'organizzazione di ogni singola vulnerabilità. Ad esempio, anche un CVE ad alta priorità ha un profilo di rischio diverso a seconda dell'importanza del carico di lavoro. Una buona gestione delle vulnerabilità consiste nell'essere in grado di bilanciare, valutare e dare priorità alle correzioni per determinare il miglior profilo di sicurezza possibile.

La gestione delle vulnerabilità dovrebbe essere automatizzata principalmente nelle applicazioni cloud native. L'intelligenza umana è necessaria per definire i criteri, ma gli strumenti dovrebbero essere responsabili dell'individuazione delle violazioni dei criteri e dell'adozione di azioni appropriate in base alla vulnerabilità, al livello di rischio e alla fase del ciclo di vita, quali il fallimento automatico delle build, il blocco delle distribuzioni o la riduzione a zero delle build in produzione.

La scansione delle immagini e delle vulnerabilità dovrebbe iniziare durante la fase di creazione, ma deve continuare per l'intero ciclo di vita dell'applicazione, anche in fase di esecuzione. È possibile scoprire nuove vulnerabilità di sicurezza in qualsiasi momento e la capacità di rilevare eventuali vulnerabilità nei deployment in esecuzione è fondamentale per il profilo di sicurezza dell'organizzazione. Le vulnerabilità nei deployment in esecuzione potrebbero comportare un rischio immediato per la sicurezza e le organizzazioni hanno bisogno di un modo per rilevarle e porvi rimedio il prima possibile.

Nella fase di creazione, le immagini non conformi, comprese quelle con vulnerabilità gravi e risolvibili, dovrebbero non essere create. I team DevOps dovrebbero ricevere il feedback direttamente nel sistema CI. Al momento della distribuzione, gli strumenti di sicurezza possono applicare un controllo di ammissione per impedire automaticamente il deployment di container con vulnerabilità note rilevate nell'immagine. È fondamentale sapere come dare la priorità alla correzione, a seconda della gravità della vulnerabilità, dell'importanza del carico di lavoro e della tolleranza generale dell'organizzazione al rischio per la sicurezza. Le organizzazioni dovrebbero prendersi il tempo necessario per creare criteri personalizzati e implementare strumenti che consentano di applicare tali criteri, in fase di creazione e distribuzione, tramite l'automazione. Una volta che i deployment sono in esecuzione, le organizzazioni dovrebbero continuare a cercare le vulnerabilità.

 

Diverse funzionalità negli scanner di immagini

Non tutti gli scanner di immagini forniscono lo stesso livello di controlli completi: alcuni analizzano solo il sistema operativo sottostante, altri analizzano anche le librerie, altri eseguono controlli a livello di lingua e altri ancora analizzano il contenuto dei file. È importante scegliere uno scanner di immagini che sia quanto più completo possibile, almeno in base alle esigenze dell'organizzazione, nonché uno che sia compatibile con i linguaggi di programmazione utilizzati dalle applicazioni.

Alcuni scanner di immagini eseguono una scansione in tempo reale su ogni pull di immagini, ma questo approccio può aumentare la latenza; le organizzazioni devono quindi decidere se le informazioni in tempo reale valgono il calo delle prestazioni.

 

Scansione durante il runtime

Come per la scansione delle immagini durante la fase di creazione, non tutte le vulnerabilità rilevate richiedono la stessa risposta. Le organizzazioni hanno bisogno di un modo per dare priorità alle correzioni in base all'importanza dei carichi di lavoro, alla sensibilità dei dati, all'esposizione a Internet e alla gravità delle vulnerabilità rilevate. Non esistono due organizzazioni che usano le stesse procedure o obiettivi del livello di servizio per elaborare la risposta appropriata alle vulnerabilità scoperte. Vi sono dei compromessi da tenere in considerazione in relazione, ad esempio, al blocco di ogni container in cui sono state scoperte vulnerabilità, indipendentemente dalla gravità o dalla sensibilità. La corretta scansione delle vulnerabilità nei deployment in esecuzione richiede sia gli strumenti giusti per garantire la visibilità e le informazioni corrette, sia criteri di sicurezza aziendali valutati attentamente che offrano il giusto equilibrio tra gestione delle vulnerabilità e impatto operativo.

La complessità delle reti aziendali e delle applicazioni distribuite in esse si è evoluta, ma di pari passo si sono evoluti anche i modelli di minaccia e i metodi utilizzati per approfondire l'infiltrazione. La protezione dei perimetri può servire solo come difesa di prima linea per salvaguardare le reti interne, non rappresenta una strategia completa per la protezione dell'infrastruttura e dei dati. Una sicurezza solida richiede una combinazione di controlli e strategie.

Le reti zero trust rappresentano un pezzo importante del puzzle della sicurezza, in quanto permettono di aumentare la sicurezza del traffico interno delle applicazioni. Questo modello capovolge il principio assodato secondo cui tutto il traffico all'interno di una rete protetta da firewall è autentico con il presupposto opposto: nessuna connessione di rete dovrebbe essere considerata sicura finché non si dimostra il contrario.

In passato, gli amministratori di rete operavano partendo dal presupposto che ogni entità, che fosse un'applicazione, un server o una parte di software o hardware di rete presente nelle loro reti interne, appartenesse a quella rete e potesse essere considerata attendibile. Alcune applicazioni non richiedevano l'autenticazione delle connessioni client né si affidavano a credenziali statiche e condivise, ad es. una password per i database. Tutte le applicazioni dovevano gestire gli schemi di autenticazione o autorizzazione di cui avevano bisogno, se in uso. Spesso le connessioni di rete interne, anche quelle per servizi sensibili, non utilizzavano alcuna crittografia.

Molte reti aziendali seguono ancora questo schema. Tuttavia, un singolo utente malintenzionato che si inserisca all'interno di questo ambiente inadeguatamente protetto, sia attraverso un attacco diretto, un trojan horse introdotto accidentalmente da un individuo autorizzato, o semplicemente un punto debole nel firewall di rete, può provocare il caos sfruttando appieno questa attendibilità implicita. Le possibilità potrebbero non essere infinite, ma sono prevedibili. Dall'analisi dei pacchetti di rete non crittografati al rilevamento delle password delle applicazioni ai database o ad altri sistemi critici fino all'acquisizione del controllo degli strumenti di rete, questo scenario apre le porte a rischi inaccettabili, inclusa l'esfiltrazione o la perdita di dati.

I modelli zero trust costituiscono la base di un numero crescente di infrastrutture di produzione che mettono al primo posto la sicurezza. Invece di presumere che ogni entità su una rete possa essere considerata attendibile senza verifica, il modello zero trust presuppone che nessuna possa esserlo, nemmeno l'infrastruttura di rete stessa. Il framework zero trust non offre un'implementazione prescrittiva o un insieme specifico di tecnologie da utilizzare. Descrive piuttosto una serie di principi e obiettivi, lasciando i dettagli tecnici specifici dell'implementazione a ciascuna organizzazione.

Architetture zero trust

Le architetture zero trust generalmente seguono questi principi:

  • I controlli di sicurezza dovrebbero applicarsi allo stesso modo a tutte le entità, siano esse software o hardware, indipendentemente dalla loro posizione nella rete.
  • Le connessioni di rete devono essere autenticate a entrambe le estremità, dal server e dal client. L'autenticazione del client da parte del server ora è generalmente prevista, ma i client dovrebbero anche verificare di essere connessi a un server valido. Le connessioni dovrebbero essere riautenticate e le richieste dovrebbero essere nuovamente autorizzate quando necessario quando riguardano più di una singola transazione.
  • La concessione delle autorizzazioni dovrebbe seguire il principio del privilegio minimo, consentendo solo le autorizzazioni minime necessarie per il carico di lavoro di un client.
  • Tutte le connessioni di rete e le transazioni dovrebbero essere soggette a monitoraggio continuo per l'analisi.

Implementazione di un modello zero trust in Kubernetes

Come si presenta un modello zero trust in un cluster Kubernetes? Sebbene non esista un'unica metodologia per l'implementazione dei principi zero trust all'interno di un cluster Kubernetes, per molti degli obiettivi dell'architettura le service mesh sono diventate una soluzione utilizzata diffusamente.

Le service mesh creano un livello di rete virtualizzato per connettere e controllare i servizi applicativi distribuiti. Sebbene la maggior parte delle soluzioni di service mesh inizialmente non si concentrasse sulla sicurezza della rete, ma piuttosto su come facilitare e gestire l'individuazione intelligente dei servizi e il routing delle richieste, ora i progetti open source più diffusi offrono funzionalità che si integrano con un'architettura zero trust. Poiché molte service mesh tentano di creare un overlay che non richiede la modifica delle singole applicazioni, eliminano gran parte della necessità di apportare modifiche significative per consentire rigorosi controlli di autenticazione e autorizzazione.

Le service mesh che supportano Kubernetes in genere utilizzano un routing point-to-point decentralizzato assegnando a ogni singolo pod del cluster la propria istanza proxy. Questi proxy possono gestire i certificati TLS client, che il proxy può utilizzare per dimostrare la propria identità quando effettua connessioni ad altri servizi o riceve connessioni da altri client. L'utilizzo dei certificati TLS per fornire una prova di identità sia sul lato client che sul lato server è chiamato Mutual Transport Layer Security (mTLS). Il metodo mTLS, oltre a eseguire l'autenticazione della connessione, serve anche a crittografare la connessione di rete. Oltre all'autenticazione e alla crittografia via cavo, service mesh diverse supportano diverse fonti di autorizzazione, che vanno dagli elenchi statici alle integrazioni con single sign on di terze parti o altri servizi.

Le service mesh non forniscono una soluzione zero trust completa per i cluster Kubernetes, ma offrono molti dei principali vantaggi del metodo zero trust. Anche se non è possibile ottenere un'architettura zero trust perfetta nei cluster Kubernetes, qualsiasi modifica incrementale apportata in quella direzione contribuirà a proteggere il cluster e i relativi carichi di lavoro.

Proteggere le applicazioni cloud native e l'infrastruttura sottostante richiede modifiche sostanziali in termini di approccio alla sicurezza di un'organizzazione. Infatti, è necessario anticipare i controlli lungo il ciclo di sviluppo delle applicazioni, ricorrere a controlli integrati per applicare policy che prevengano i problemi di scalabilità e operatività, e stare al passo con le pianificazioni dei rilasci sempre più frequenti.

Red Hat® Advanced Cluster Security for Kubernetes è una piattaforma di sicurezza Kubernetes native che permette alle organizzazioni di creare, distribuire ed eseguire le applicazioni cloud native con maggiore sicurezza e accelerare il processo di innovazione in tutta tranquillità. Questa soluzione consente di migliorare la sicurezza del processo di creazione delle applicazioni, di proteggere le configurazioni e la piattaforma delle applicazioni, di rilevare i problemi di runtime e avviare un'azione di risposta coerente.

Keep reading

ARTICOLO

Container e VM

I container Linux e le macchine virtuali (VM) sono entrambi pacchetti di ambienti di elaborazione che combinano vari componenti IT e li isolano dal resto del sistema.

ARTICOLO

Cos'è l'orchestrazione dei container?

Definiamo orchestrazione dei container l'automazione dei processi di deployment, gestione, scalabilità e networking dei container.

ARTICOLO

Cos'è un container Linux?

Un container Linux è un insieme di processi, isolati dal resto del sistema, che esegue un'immagine distinta contenente tutti i file necessari per supportare tali processi.

Scopri di più sui container

Prodotti

Una piattaforma applicativa aziendale che offre servizi verificati per consentire la distribuzione delle app sulle infrastrutture preferite.

Risorse

Checklist

10 considerazioni sui deployment Kubernetes

Checklist

Sei considerazioni per scegliere la piattaforma Kubernetes giusta

Serie Open Answers: Cos'è Red Hat OpenShift?

Formazione

Corso di formazione gratuito

Running Containers with Red Hat Technical Overview

Corso di formazione gratuito

Containers, Kubernetes and Red Hat OpenShift Technical Overview

Corso di formazione gratuito

Developing Cloud-Native Applications with Microservices Architectures