MySQL
e' il piu' diffuso DBMS relazionale Open Source.
MySQL supporta in modo nativo il protocollo SSL: e' quindi possibile
accedere ai dati presenti sul DB con una connessione cifrata.
Questo documento descrive i dettagli del funzionamento e della configurazione
della base dati MySQL utilizzando il protocollo SSL per la trasmissione dei dati.
La versione cui fa riferimento il documento e' la 5.7,
perche' sono molte ed importanti le novita' introdotte in tale release
per la gestione delle connessioni crittografate
[NdE e' l'ultima versione di produzione disponibile da ottobre 2015].
Questa pagina ha un taglio pratico e presenta diverse configurazioni possibili
tuttavia non e' un documento introduttivo ed e' consigliato ad un pubblico informaticamente adulto...
La prima parte del documento contiene un poco di teoria e variazioni sulla configurazione: chi ha fretta puo' partire da qui!
Un documento introduttivo su MySQL e' Introduzione a MySQL, mentre un documento piu' completo e' Qualcosa in piu' su MySQL. Per una documentazione completa della teoria e dettagli specifici si rimanda alla documentazione MySQL ufficiale.
Un breve accenno all'architettura di MySQL puo' essere utile... L'architettura di MySQL e' molto semplice: vi e' un singolo processo che gestisce un thread per ogni connessione! Per completezza e' riportato anche il processo dello shell di lancio che resta attivo:
/bin/sh /usr/local/mysql/bin/mysqld_safe --user=mysql /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --pid-file=/usr/local/...
Ogni database MySQL corrisponde ad una directory posta sotto la directory indicata dal parametro datadir. All'interno della directory si trovano i file relativi ad ogni tabella. La memorizzazione dei dati dipende dallo Storage Engine. E' sempre presente un file tabella.frm che contiene la struttura della tabella, eventuali altri file dipendono dall'Engine di memorizzazione (eg. .frm, .MYD e .MYI per MyISAM, .frm e .ibd per InnoDB).
Gli utenti si collegano a MySQL utilizzando una connessione TCP-IP
su una porta socket. Di default la porta utilizzata da MySQL e' la 3306.
Il processo mysqld e' in LISTEN su tale porta e quando arriva una nuova
richiesta di connessione effettua l'attivazione del thread corrispondente.
Nella fase iniziale della connessione di un client vengono scambiati gli
hash delle password
(crittografati SHA1 dalla versione 4.1) ma tutta la successiva trasmissione
dati avviene in chiaro con il protocollo TCP.
La trasmissione in chiaro dei dati puo' essere accettabile quando si utilizzano reti dedicate e protette, come generalmente avviene tra application server e DB server, ma fornisce un livello molto basso di sicurezza. Nel caso in cui sia necessario un livello di sicurezza maggiore e' necessario effettuare la crittografazione dell'intera trasmissione dati con il protocollo SSL che MySQL supporta in modo nativo.
Ecco la ragione di questo documento!
Con la configurazione SSL tutto il traffico in rete tra il client ed il DB viene
crittografato.
Abbiamo utilizzato fino ad ora il termine SSL ma e' sbagliato!
Un'avvertenza: ho inserito questo paragrafo per completezza,
ma e' piuttosto criptico (per forza, dato l'argomento ;-):
potete tranquillamente saltarlo!
Per essere precisi l'SSL (Secure Sockets Layer) e' il predecessore dell'attuale TLS (Transport Layer Security) e sono entrambe protocolli crittografici utilizzati per le comunicazioni sopra il livello di trasporto TCP (Transmission Control Protocol). L'utilizzo piu' comune e noto del TLS/SSL e' su web per garantire la sicurezza delle comunicazioni verso i siti (con il protocollo HTTPS), altrettanto importante e significativo e' l'uso del TLS/SSL nelle connessioni VPN, ... Per l'accesso alle basi dati e' molto meno utilizzato poiche' solitamente queste vengono poste su reti interne e protette.
TLS/SSL forniscono meccanismi per l'autenticazione, l'integrita' dei dati e la cifratura operando al di sopra del livello di trasporto [NdE il livello di trasporto e' il TCP]. Nella fase di avvio della comunicazione tra due nodi viene prima negoziato l'algoritmo da utilizzare, quindi vengono scambiate le chiavi di cifratura ed eseguita l'autenticazione. La fase di autenticazione avviene con lo scambio di chiavi asimmetriche (ovviamente viene inviata solo la chiave pubblica) e la verifica di certificati emessi da certificate authority (CA). Una volta instaurata la comunicazione i messaggi vengono cifrati con chiavi simmetriche ed verificati singolarmente con un checksum.
Per ogni fase vengono utilizzati protocolli diversi ed in ogni versione vengono
aggiornati gli algoritmi (eliminando quelli che sono stati ricosciuti come meno sicuri).
Attualmente vengono utilizzati per lo scambio di chiavi: RSA, Diffie-Hellman, ECDH, ...
per l'autenticazione: RSA, DSA, ECDSA, ...
per la cifratura simmetrica: RC4, DES, Triple DES, AES, ...
per la verifica d'integrita': in TLS sono utilizzati HMAC-MD5 o HMAC-SHA.
Ad esempio con l'SSL per la verifica di integrita' venivano utilizzati anche:
MD2, MD4, MD5 e SHA, ora ritenuti non sufficientemente sicuri.
Oltre agli algoritmi di crittografia e' importante anche la generazione di numeri casuali,
necessaria in diverse fasi dei protocolli di scambio di chiavi.
Tutto chiaro? Probabilmente no... ma non importa! E' piu' semplice di quanto sembri: con il corretto utilizzo di TLS/SSL si e' certi dell'identita' del chiamato/chiamante, ogni messaggio viene verificato (e quindi non puo' essere modificato), ogni messaggio viene cifrato (e quindi non puo' essere letto da altri).
Per configurare e rendere attiva la connessione SSL con il DB MySQL con le versioni piu' recenti... Non serve nulla: e' gia' tutto fatto!
MySQL supporta in modo nativo l'SSL quindi non e' necessario ricompilare programmi,
installare componenti aggiuntivi o
acquistare licenze [NdA nelle versioni precedenti alla 5.7 l'SSL era supportato
ma in molti casi era necessario ricompilare i sorgenti].
Sarebbe solo necessario effettuare una corretta configurazione...
Anche la configurazione praticamente e' gia' pronta!
Non e' sempre cosi', pero' con una installazione da RPM
vengono gia' eseguiti tutti i passi di creazione dei certificati
e di lancio di mysqld con SSL abilitato (-ssl).
Nel caso in cui il setup non sia stato eseguito in modo automatico
si puo' utilizzare lo script mysql_ssl_rsa_setup che genera,
utilizzando openssl, tutti i file necessari.
Vengono creati i file certificati e chiavi per la CA, per il server e per il client
MySQL utilizza il formato .PEM (eg. server-cert.pem, server-key.pem).
Viene anche creata la coppia di chiavi pubblica/privata RSA per lo scambio
iniziale della password con connessioni non crittografate.
Sempre per default e' configurato anche il file my.cnf che conterra':
[mysqld] ssl-ca=ca.pem ssl-cert=server-cert.pem ssl-key=server-key.pem
Una volta terminata la configurazione e' sufficiente far partire il DB con il parametro -ssl che... e' abilitato per default!
Ora MySQL accetta connessioni sia in chiaro che con SSL sulla porta 3306. E' il client che decide quale tipo di modalita' utilizzare... Tutti coloro che potevano collegarsi al DB ora possono farlo anche con un protocollo cifrato.
Come abbiamo visto il mysqld accetta le connessioni sulla porta 3306 sia in chiaro che cifrate.
E' il client che decide se utilizzare una connessione cifrata oppure in chiaro.
Il comando mysql --ssl-mode=PREFERRED riporta l'opzione per indicare il tipo di connessione.
PREFERRED e' il valore di default e consente di utilizzare la
connessione cifrata se disponibile, altrimenti di trasmettere in chiaro.
Gli altri due valori sono REQUIRED, che indica che la connessione deve essere cifrata,
e DISABLED, che indica che la connessione non deve essere cifrata.
Una volta effettuata la connessione e' possibile controllare il tipo di cifratura utilizzato nella propria sessione con:
Il DBA puo' decidere quando una connessione deve essere cifrata!
La configurazione si effettua a livello di utente:
CREATE USER xxx ... REQUIRE tls_option
Dove tls_option puo' essere una o piu' delle seguenti clausole:
In questo modo e' possibile scegliere tra le diverse possibilita' nella connessione da client.
Le clausole piu' utilizzate sono le prime tre e corrispondono ad un livello crescente di
sicurezza sulla trasmissione dei dati e sull'identita' del client.
Poiche' in MySQL l'utente corrisponde in realta' alla coppia nome_utente - host_provenienza e' possibile configurare gli accessi cifrati in modo semplice ed efficace.
Il DBA puo' verificare le tipologie di connessione di ogni thread interrogando la vista PERFORMANCE_SCHEMA.THREADS:
Nella prima query la colonna CONNECTION_TYPE riporta il tipo di connessione: SSL/TLS o TCP/IP a seconda che venga utilizzata o meno la crittografia. Con la seconda query vengono estratti i dettagli sui protocolli e gli algoritmi di cifratura.
Naturalmente anche il general query log e gli strumenti di auditing riportano l'indicazione del tipo di connessione...
Nel caso in cui si voglia utilizzare la connessione SSL a MySQL da un'applicazione Java sono necessari alcuni altri passi...
Innanzi tutto va importato nel keystore di java la CA di MySQL utilizzando il comando:
keytool -import -alias mysqlServerCACert -file ca.pem -keystore truststore.jks
Quindi l'URL di connessione dovra' contentere:
jdbc:mysql://host/db?verifyServerCertificate=true&useSSL=true&requireSSL=true
Utili ed importanti sono anche le funzioni di crittografia presenti in MySQL e la possibilita' di crittografare i tablespace InnoDB: ma entrambe gli argomenti non sono stati descritti in questa pagina perche' richiedono una trattazione specifica.
L'utilizzo del protocollo SSL presenta notevoli vantaggi in termini di sicurezza
ma ha i suoi costi.
La crittografazione ha un peso computazionale, con gli HW attuali difficimente e' un problema,
ma puo' rallentare attivita' massive quali i backup ed sicuramente e' sconsigliabile per un DWH;
la configurazione e' piu' complessa e richiede tempo, i certificati veri hanno un costo
ed una scadenza.
In particolare la scadenza dei certificati richiede una gestione attenta:
quante volte e' successo di dover sostituire velocemente il certificato su un Web Server?
Lo stesso puo' avvenire anche con un certificato utilizzato nell'SSL di MySQL!
L'utilizzo di protocolli cifrati per la connessione a MySQL aumenta in modo significativo
la sicurezza dei dati ed e' quindi una soluzione
quando si hanno dati personali, sensibili o critici da proteggere.
Le configurazioni in Cloud sono sempre piu' diffuse e questo presenta nuove sfide perche' in precedenza
le basi dati venivano accedute solo da reti interne e protette: con l'SSL si possono proteggere
in modo efficace i dati anche se ospitati in Cloud.
Le piu' recenti normative di sicurezza prevedono in modo esplicito
la crittografia dei dati (eg. il GDPR lo prevedende per i dati personali)
quindi le connessioni cifrate verso i DB diverrano sempre piu' diffuse.
Riassumendo la connessione SSL a MySQL e' utile e questo documento ha cercato di dimostrare anche che non e' difficile!
Titolo: Connessione SSL a MySQL
Livello: Esperto
Data:
14 Febbraio 2016
Versione: 1.0.0 - 14 Febbraio 2016
Autore: mail [AT] meo.bogliolo.name