Connessioni sicure a MySQL con SSL

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

2 pensieri su “Connessioni sicure a MySQL con SSL

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *