PDOを使ってMySQLにSSL接続するパッチ
こんにちは、熊谷です。
PHPからMySQLに接続するドライバはいくつかあります。MySQL拡張モジュールやMySQL改良版拡張モジュール、または抽象化レイヤであるPDOを通して。
最近はPDOを使用して接続するのが一般的なのかなと思ったりするのですが、symfonyを使用す る場合、どうしても選択肢はPDOをになってしまいます。今までPDOを使っていて何の問題もなかったのですが、最近一つの問題に突き当たりました。それはMySQLへのSSL接続です。
MySQLは5.0からSSLでの暗号化接続が比較的簡単に行えるようになっています。SSLでの接続方法についてはいろいろ検索すると出てきますので、そちらを参照してください。
そんなMySQLのSSL接続ですが、現時点、PHPから行うにはMySQL改良版拡張モジュールしか対応していないようで、PDOではSSL接続を行うことが出来ません。ということは、symfonyからも出来ないということになり、これは困った状態です。
いろいろ調べてみると、MySQLでSSL接続を行うにはmysql_real_connect()を呼び出す前にmysql_ssl_set()を実行するればいいとのことなので、PDOのMySQLドライバであるpdo_mysqlにそれを実装してみることにしました。実装といってもそんな大がかりなものではなく、mysql_driver.cにそれ用のコードを追加します。
--- mysql_driver.c.orig 2009-09-04 23:10:02.000000000 +0900
+++ mysql_driver.c 2009-09-07 17:37:47.000000000 +0900
@@ -444,6 +444,11 @@
{ "host", "localhost", 0 },
{ "port", "3306", 0 },
{ "unix_socket", PDO_MYSQL_UNIX_ADDR, 0 },
+ { "ssl_key", NULL, 0 },
+ { "ssl_cert", NULL, 0 },
+ { "ssl_ca", NULL, 0 },
+ { "ssl_ca_path", NULL, 0 },
+ { "ssl_cipher", NULL, 0 },
};
int connect_opts = 0
#ifdef CLIENT_MULTI_RESULTS
@@ -454,7 +459,7 @@
#endif
;
- php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
+ php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 10);
H = pecalloc(1, sizeof(pdo_mysql_db_handle), dbh->is_persistent);
@@ -550,6 +555,12 @@
if (vars[2].optval & & !strcmp("localhost", vars[2].optval)) {
unix_socket = vars[4].optval;
}
+
+ // SSL connection
+ if(vars[5].optval || vars[6].optval || vars[7].optval || vars[8].optval || vars[9].optval) {
+ mysql_ssl_set(H->server, vars[5].optval, vars[6].optval, vars[7].optval, vars[8].optval, vars[9].optval);
+ }
+
if (mysql_real_connect(H->server, host, dbh->username, dbh->password, dbname, port, unix_socket, connect_opts) == NULL) {
pdo_mysql_error(dbh);
goto cleanup;
そして、phpize、configure、make installで完了です。使い方は、DSNでssl_ca=やssl_cert=等々オプションを指定するだけです。例えば、
<?php
$dsn = 'mysql:host=localhost;dbname=sampledb;ssl_ca=/var/www/sample/config/cacert.pem';
$user = 'user1';
$pass = 'hogehoge';
$pdo = new PDO($dsn, $user, $pass);
というようなコードでMySQLに対してPHP からPDOを通してSSL接続することが可能になります。
PDOでMySQLにSSL接続出来ないよという方は試してみてください。