Come proteggere il socket TCP di Docker con TLS

0
166

L'API di Docker non è completamente protetta per impostazione predefinita, ad eccezione dei permessi del filesystem sul suo socket Unix. Dovresti impostare TLS quando esponi l'API Docker su TCP in modo che Docker Engine e i tuoi client possano verificarsi a vicenda’ identità. Altrimenti chiunque abbia accesso alla porta TCP potrebbe esplorare i tuoi contenitori Docker, avviarne di nuovi ed eseguire azioni come root sul tuo sistema.

Il TLS configurato richiederà ai client di presentare un certificato valido firmato dall'autorità di certificazione del server. Per farlo funzionare, devi creare certificati SSL, quindi configurare Docker Engine per richiedere connessioni TLS. Anche i client Docker CLI devono essere regolati per prevedere un server TLS.

Esposizione del socket TCP

Puoi esporre il socket TCP di Docker utilizzando il flag -H per definire un endpoint aggiuntivo all'avvio del processo Docker. Questo flag può essere ripetuto più volte; in questo esempio saranno disponibili sia il socket Unix che il socket TCP:

/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

La porta 2375 viene convenzionalmente utilizzata per le connessioni Docker non crittografate. La porta 2376 dovrebbe essere utilizzata invece una volta che TLS è stato configurato.

È possibile configurare Docker per l'utilizzo automatico di questi flag modificando la definizione del servizio Docker. Aggiungi un override in /etc/systemd/system/docker.service.d/override.conf che cambia la riga ExecStart:

[Service] ExecStart=/usr/bin/dockerd -H …

Ricarica systemd per applicare la modifica:

sudo systemctl daemon-reload

Creazione della tua autorità di certificazione

Inizia creando un'autorità di certificazione (CA) per la tua configurazione TLS. Utilizzerai questa CA per firmare i tuoi certificati; il server rifiuterà di comunicare con i client che presentano un certificato da una CA diversa.

Pubblicità

Utilizza OpenSSL per generare chiavi CA pubbliche e private sulla macchina che ospita il tuo server Docker:

# Genera la chiave privata openssl genrsa -aes256 -out ca-private.pem 4096 # Genera una chiave pubblica dalla chiave privata openssl req -new -x509 -days 365 -key ca-private.pem -sha256 -out ca-public.pem

Ti verrà chiesto di fornire una passphrase, un indirizzo email, il codice del paese, i nomi di stato e città e il nome dell'organizzazione da includere con la tua chiave pubblica. Inserisci le informazioni nel tuo terminale, premendo invio dopo ogni riga per andare avanti e creare la chiave.

Generazione di una chiave server e Richiesta di firma del certificato

Quindi crea una chiave del server e una richiesta di firma del certificato:

# Genera la chiave del server openssl genrsa -out server-key.pem 4096 # Genera una richiesta di firma del certificato openssl req -subj “/CN=example.com” -sha256 -new -key server-key.pm -out request.csr < p>

La richiesta di firma del certificato (CSR) contiene tutte le informazioni necessarie per produrre un certificato firmato certificato. È importante verificare che il nome comune nella CSR sia corretto per il tuo server. Questo è specificato nel campo CN come esempio.com sopra; dovresti impostarlo sul nome di dominio completo (FQDN) per il tuo server.

 

 

Impostazione di estensioni di certificato

L'utilizzo di questa CSR consentirebbe connessioni a il server tramite il suo FQDN. È necessario specificare le estensioni del certificato se si desidera aggiungere un altro dominio o utilizzare un indirizzo IP. Crea un file di estensioni con i campi subjectAltName e extendedKeyUsage per impostarlo:

echo subjectAltName = DNS:sub.example.com;IP=192.168.0.1 >> extfile.cnf echo extendedKeyUsage = serverAuth >> pubblicità extFile.cnf

Questo esempio consentirebbe inoltre connessioni tramite sub.example.com e 192.168.0.1 .

Generazione di un certificato firmato< /h2>

Ora sei pronto per combinare tutti i componenti e generare un certificato firmato:

openssl x509 -req -days 365 -sha256 -in request.csr -CA ca-public. pem -CAkey ca-private.pem -CAcreateserial -extfile extfile.cnf -out certificate.pem

Questo prende la richiesta di firma del certificato, aggiunge il tuo file di estensione e usa le chiavi della tua CA per produrre un certificato OpenSSL firmato. Devi fornire la passphrase della CA per completare il processo.

Questo certificato scade dopo un anno. Puoi regolare il flag -days per ottenere una vita utile per le tue esigenze. Dovresti provvedere a generare un certificato sostitutivo prima della scadenza di questo.

Generazione di un certificato client

Quindi dovresti generare un altro certificato da utilizzare per i tuoi client Docker. Questo deve essere firmato dalla stessa CA del certificato del server. Utilizza un file di estensioni con extendedKeyUsage = clientAuth per preparare questo certificato per l'uso in uno scenario client.

# Genera una chiave client openssl genrsa -out client-key.pem 4096 # Crea una richiesta di firma del certificato openssl req -subj '/CN=client' -new -key client-key.pem -out client-request.csr # Completa il firma echo extendedKeyUsage = clientAuth >> extfile-client.cnf openssl x509 -req -days 365 -sha256 -in client-request.csr -CA ca-public.pem -CAkey ca-private.pem -CAcreateserial -extfile extfile-client.cnf -out client-certificate.pem

Preparazione alla configurazione di Docker

Copia i file ca-public.pem, certificate.pem e server-key.pem in una nuova directory pronta per fare riferimento nella configurazione Docker. Successivamente, copia i file ca-public.pem, client-certificate.pem e client-key.pem sul computer da cui ti connetterai.

Pubblicità

Puoi eliminare il richiesta di firma del certificato e file di estensione nella directory di lavoro. Fai attenzione a non perdere le tue chiavi private perché non sono recuperabili. Senza di essi non sarai in grado di convalidare certificati o generare rinnovi.

Configurazione del demone Docker

Ora puoi avviare il demone Docker con i flag TLS che fanno riferimento al certificato e alle chiavi generati. I parametri –tlscacert, –tlscert e –tlskey specificano i percorsi delle rispettive risorse OpenSSL generate sopra.

/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 –tlsverify –tlscacert=ca-public.pem –tlscert=certificate.pem –tlskey=server-key.pem

L'aggiunta del flag –tlsverify consente l'imposizione delle connessioni TLS. Ai client senza un certificato corrispondente verrà impedito di accedere al socket TCP di Docker.

Configurazione del client Docker

Attiva TLS su il client fornendo i flag TLS quando si utilizza il comando docker. È inoltre necessario aggiungere il flag -H per specificare l'indirizzo del socket Docker remoto a cui connettersi. Dal punto di vista del client, –tlsverify significa che il comando si connetterà solo ai server con un certificato TLS firmato dalla stessa autorità di certificazione.

docker -H tcp://0.0.0.0:2376 –tlsverify –tlscacert=ca-public.pem –tlscert=client-certificate.pem –tlskey=client-key.pem ps < p>Fornire questi flag ogni volta che si utilizza la CLI diventa ripetitivo molto rapidamente. Se lavorerai principalmente con lo stesso host protetto da TLS, imposta le variabili di ambiente DOCKER_HOST e DOCKER_TLS_VERIFY nel tuo profilo shell. Copia i file dei certificati in ca, cert e key all'interno della tua directory ~/.docker. Questi corrispondono ai flag –tls di Docker e definiscono un certificato predefinito per il client.

export DOCKER_HOST=tcp://0.0.0.0:2376 export DOCKER_TLS_VERIFY=1

Puoi semplificare il lavoro con più host che utilizzano una combinazione di connessioni locali, remote, non protette e TLS impostando contesti Docker. Questa funzione ti consente di passare da un target all'altro utilizzando i comandi Docker CLI.

Pubblicità

Il client Docker supporta anche modalità di verifica alternative. L'utilizzo di una combinazione di flag tls, tlscacert, tlscert, tlskey e tlsverify attiva diversi livelli di applicazione TLS.

Con solo tls impostato, Docker autenticherà il server utilizzando il pool CA predefinito. L'aggiunta dei flag tlscacert e tlsverify senza una chiave client imporrà al server di utilizzare la CA specificata senza altri controlli. L'omissione di tlscacert e tlsverify ma l'inclusione delle altre tre chiavi verificherà il certificato del client senza autenticare la CA del server.

Conclusione

La protezione del socket TCP di Docker con i certificati TLS ti consente di esporre l'API in modo più sicuro impedendo connessioni da client non autorizzati. Agli attori che effettuano la scansione delle porte della tua rete verrà impedito di connettersi a Docker, offrendoti un livello di protezione che impedisce che la tua macchina venga compromessa con privilegi a livello di root.

Una volta generati i certificati, tu possono usarli per autenticarsi con Docker CLI o con i propri client HTTP. Curl li accetterà come flag –cert, –key e –cacert, ad esempio.

TLS è solo un componente di un'istanza dell'API Docker protetta. Fornisce la crittografia e garantisce che i client siano affidabili, ma non è un meccanismo di controllo dell'accesso granulare.

Se desideri limitare ciò che i singoli client possono fare, dovresti configurare un plug-in di autorizzazione Docker Engine. I plugin possono contattare un servizio esterno per determinare se una particolare richiesta API può procedere. In alternativa, puoi utilizzare un proxy inverso davanti al tuo socket TCP per imporre il controllo dell'accesso prima che le richieste raggiungano Docker.