PHPでMySQLを扱うに当たって、SSL通信を行うときのメモ
細かい説明は省きますが、まずはSSL証明書を作成する。
注意することとしては証明書を作成する際にcommon nameとかを適当に書くとあとで泣きを見る。
mkdir /etc/mysql-ssl cd /etc/mysql-ssl # CAキーの作成 openssl genrsa -out ca-key.pem 2048 # CA証明書を作成 openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca-cert.pem # MySQLサーバーの秘密鍵とCSRの作成 openssl req -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-req.pem # MySQLサーバーの証明書作成 openssl x509 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -out server-cert.pem -set_serial 01
/etc/my.cnf [mysqld]にSSL設定を追記
[mysqld] ssl-ca=/etc/mysql-ssl/ca-cert.pem ssl-cert=/etc/mysql-ssl/server-cert.pem ssl-key=/etc/mysql-ssl/server-key.pem
MySQLを再起動
# OS が違う場合は適宜コマンドを変更してください service mysqld restart
コマンドラインからMySQLにログインしてSSL通信が有効になっているか確認。
下記のコマンドを入力した結果が同じようになればSSL通信が有効になっている。
mysql> SHOW VARIABLES LIKE '%ssl%' +---------------+--------------------------------+ | Variable_name | Value | +---------------+--------------------------------+ | have_openssl | YES | | have_ssl | YES | | ssl_ca | /etc/mysql-ssl/ca-cert.pem | | ssl_capath | | | ssl_cert | /etc/mysql-ssl/server-cert.pem | | ssl_cipher | | | ssl_key | /etc/mysql-ssl/server-key.pem | +---------------+--------------------------------+
SSL通信するユーザーを作成する((例) ユーザー名: user , パスワード: password ホスト:ローカルホスト)
GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY 'password' REQUIRE SSL;
SSL通信を使用してコマンドラインでログインする(例)
クライアント証明書を必要としない設定なのでCA証明書を指定するか、cipherの指定でログインできる。
mysql -h localhost -u user -p password --ssl-ca=/etc/mysql-ssl/ca-cert.pem
mysql -h localhost -u user -p password --ssl-cipher=DHE-RSA-AES256-SHA
ログインしてSSL通信が有効になっているか確認する。
Valueに以下の値が入っていればSSL通信している。
mysql> SHOW STATUS LIKE 'Ssl_cipher'; +---------------+--------------------+ | Variable_name | Value | +---------------+--------------------+ | Ssl_cipher | DHE-RSA-AES256-SHA | +---------------+--------------------+
ここまでで、ようやくPHPでSSL通信を使う下準備ができたので、mysqliクラスを拡張してSSL通信を使う。
class foo_mysqli extends mysqli { const MYSQL_SERVER_URI = 'localhost'; const MYSQL_USER_NAME = 'user'; const MYSQL_USER_PASSWD = 'password'; const MYSQL_USE_DB = 'test'; public function __construct($host, $user, $pass, $db) { parent::init(); parent::ssl_set( // 未使用のパラメータにはNULLを入力 NULL, // 鍵ファイルへのパス NULL, // cert証明書ファイルへのパス NULL, // CAファイルへのパス(ca-cert.pem 指定) NULL, // 信頼された SSL CA 証明書が PEM フォーマットで格納されているディレクトリへのパス。 "DHE-RSA-AES256-SHA" // SSL の暗号化に使用可能な暗号形式の一覧。 ); // オートコミットをオフにする初期設定 // 意図せずにロールバックされたりするときはこの設定をしないか、明示的にcommitすること if (!parent::options(MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT = 0')) { die('Setting MYSQLI_INIT_COMMAND failed'); } if (!parent::options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) { die('Setting MYSQLI_OPT_CONNECT_TIMEOUT failed'); } if (!parent::real_connect($host, $user, $pass, $db)) { die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error()); } } } // 使用例 $mysqli = foo_mysqli( foo_mysqli::MYSQL_SERVER_URI, foo_mysqli::MYSQL_USER_NAME, foo_mysqli::MYSQL_USER_PASSWD, foo_mysqli::MYSQL_USE_DB ); echo 'Success... ' . $mysqli->host_info . "\n"; $mysqli->close();
なお、Windows版xamppで若干はまったのが、php.iniの設定
SSLのモジュールがコメントアウトされているので、コメントアウトを解除してapacheを再起動する。
extension=php_openssl.dll
これで基本的なPHPでのMySQL、SSL通信ができるようになった。
次は、クライアント証明書を必要とする設定を書こうと思う。
あ、、、新年明けましておめでとうござます(笑)
最近のコメント