MySQL supporta connessioni sicure (criptate) tra client e server sfruttando il protocollo Secure Sockets Layer (SSL).
In questo articolo affronteremo per prima cosa la generazione dei certificati, poi configureremo il server per supportare connessioni sicure e infine vedremo come poter richiedere l’autenticazione del client tramite certificato. In appendice ho inserito anche un breve script in PHP che mostra come è possibile sfruttare questo tipo di connessione.
Premetto che per i miei test ho utilizzato una macchina con installati Ubuntu 8.04, MySQL 5.1 e OpenSSl 0.9.8.
Generazione certificati
Prima di tutto è necessario creare i certificati per l’autenticazione del server e del client. Per queste operazioni potete seguire le indicazioni che trovate nel paragrafo “Generare una C.A.”
Configurazione di MySQL
A questo punto avrete a disposizione 3 certificati e 3 chiavi private.
Copiate nella directory di MySQL il certificato della CA, quello server e la sua chiave privata.
# mkdir /etc/mysql/ssl # cp my-ca.crt /etc/mysql/ssl/my-ca.crt # cp server.crt /etc/mysql/ssl/server.crt # cp server.key /etc/mysql/ssl/server.key |
Aprite il file di configurazione di MySQL /etc/mysql/my.cnf, cercate le seguenti direttive e modificate:
ssl-ca= /etc/mysql/ssl/my-ca.crt ssl-cert=/etc/mysql/ssl/server.crt ssl-key= /etc/mysql/ssl/server.key |
se non fossero presenti potete aggiungerle sotto la sezione [mysqld]
Ora è possibile riavviare MySQL per testare il funzionamento:
# /etc/init.d/mysql restart |
connettevi al server e lanciate la seguente query:
SHOW VARIABLES LIKE "%ssl%"; |
se il valore “have_ssl” è YES allora è tutto corretto.
Nel caso in cui il valore è DISABLED, qualcosa è andato storto e possono esserci diverse cause.
Nel mio caso la causa era APPARMOR, una applicazione che serve per limitare i permessi dei vari programmi che girano sul pc.
In particolare tramite questa applicazione è possibile limitare le directory e i file a cui ha accesso MySQL.
Aprendo il file di configurazione /etc/apparmor.d/usr.sbin.mysqld potremo trovare una lista di directory a cui dovete aggiungere:
/etc/mysql/ssl/*.crt r, /etc/mysql/ssl/*.key r, |
con queste direttive, MySQL ora è in grado di leggere i certificati.
Riavviate APPARMOR:
# /etc/init.d/apparmor restart |
e nuovamente MySQL. Lanciate la query indicata sopra e se questa volta il valore è YES, siete a posto.
Creazione utenti di accesso
E’ possibile definire due tipi di accesso:
utente obbligato a connettersi usando SSL
utente obbligato ad autenticarsi con un certificato personale
per il primo tipo, utilizzare la seguente query:
GRANT ALL PRIVILEGES ON test.* TO 'pippo'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE SSL; |
per il secondo invece:
GRANT ALL PRIVILEGES ON test.* TO 'pluto'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE X509; |
Connessione al server
Il client per connettersi deve avere il certificato della CA ed eventualmente il proprio certificato e chiave.
Per connettersi da console con il primo utente:
$ mysql -–ssl-ca=my-ca.crt -upippo -p |
per il secondo:
$ mysql --ssl-ca=my-ca.crt -–ssl-cert=client.crt -–ssl-key=client.key -upluto -p |
Connessione con PHP
Anche PHP mette a disposizione delle funzioni per connettersi a MySQL utilizzando SSL.
È necessario avere installato PHP 5 con l’estensione “mysqli” attiva.
Ecco lo script:
$path = dirname(__FILE__).'/'; $link = mysqli_init(); /* il file con la chiave (*.key) non deve essere coperto da password */ //mysqli_ssl_set($link, null, null, $path.'my-ca.crt', null, null); // certificato server mysqli_ssl_set($link, $path.'client.key', $path.'client.crt', $path.'my-ca.crt', null, null); // certificato server e client //mysqli_real_connect($link,'172.18.1.215','ciao','ciao','pippo'); // utente libero //mysqli_real_connect($link,'172.18.1.215','pippo','pippo','pippo'); // utente con REQUIRE SSL mysqli_real_connect($link,'172.18.1.215','asd','asd','pippo'); // utente con REQUIRE X509 if (mysqli_connect_error()) { die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error()); } echo 'Success... ' . mysqli_get_host_info($link) . '<br>'; echo 'Server version: ' . mysqli_get_server_info($link) . "<br>"; $res = mysqli_query($link, 'SHOW VARIABLES LIKE "%ssl%";'); while ($row = mysqli_fetch_assoc($res)) { print_r($row); } mysqli_close($link); |
Risorse
http://dev.mysql.com/doc/refman/5.1/en/secure-connections.html
http://www.php.net/manual/en/class.mysqli.php
Grazie mille per la guida. Ottima!
7. I like the helpful information you provide in your articles. I’ll bookmark your blog and check again here regularly. I am quite certain I will learn plenty of new stuff right here! Best of luck for the next!