雑記

インフラのことだったりプログラムのことだったりどうでもいいこと書いたり。要は雑記。

MySQLにSSL接続してみる

環境

OS CentOS5系と6系で確認
MySQLのバージョン 5.0系、5.1系、5.5系で確認

設定可能なMySQLのバージョン

5系から

SSLが有効となっているか確認

mysql> show variables like '%ssl%';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED | 
| have_ssl      | DISABLED | 
| ssl_ca        |          | 
| ssl_capath    |          | 
| ssl_cert      |          | 
| ssl_cipher    |          | 
| ssl_key       |          | 
+---------------+----------+
  • have_sslとhave_opensslがDISABLEDですね

SSL設定に必要となるファイル

  • CA証明書
  • サーバの秘密鍵
  • サーバの証明書

接続時にクライアントからの証明書を求める場合

以下のファイルも必要となります。

  • クライアントの秘密鍵
  • クライアントの証明書

各証明書と秘密鍵を作る

CAの秘密鍵

# openssl genrsa -out ca-key.pem 2048

CAの証明書

# openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca-cert.pem
  • DNは適当に

サーバの秘密鍵とCSR

# openssl req -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-req.pem

サーバの証明書

# openssl x509 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -out server-cert.pem -set_serial 01

MySQLに設定

  • my.cnfのmysqldセクションに以下を設定
[mysqld] 

ssl-ca=/tmp/ssl/ca-cert.pem
ssl-cert=/tmp/ssl/server-cert.pem
ssl-key=/tmp/ssl/server-key.pem
  • その後再起動
# /etc/init.d/mysqld restart

再度SSLが有効となっているか確認

mysql> show variables like '%ssl%';
+---------------+-------------------------------------+
| Variable_name | Value                               |
+---------------+-------------------------------------+
| have_openssl  | YES                                 | 
| have_ssl      | YES                                 | 
| ssl_ca        | /tmp/ssl/ca-cert.pem                | 
| ssl_capath    |                                     | 
| ssl_cert      | /tmp/ssl/server-cert.pem            | 
| ssl_cipher    |                                     | 
| ssl_key       | /tmp/ssl/server-key.pem             | 
+---------------+-------------------------------------+
  • YESとなっていますOKですね。

SSL接続用アカウントの作成

  • GRANTにREQUIRE SSLを付与するとssl接続を強制することができます。
mysql> GRANT ALL PRIVILEGES ON *.* TO user_name@'%' IDENTIFIED BY 'password' REQUIRE SSL;
  • クライアントの証明書の提示を求めるにはREQUIRE x509を付与すればよいです。
mysql> GRANT ALL PRIVILEGES ON *.* TO user_name@'%' IDENTIFIED BY 'password' REQUIRE X509;

mysql clientから接続してみる

  • CAの中間証明書を指定して接続
# mysql -u user_name -p -h host --ssl-ca=ca-cert.pem
mysql> show status like 'Ssl_cipher';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| Ssl_cipher    | DHE-RSA-AES256-SHA | 
+---------------+--------------------+
  • Valueに値が入っていればOK。暗号化していなかったら空です。

PHPから接続するには

  • mysql_connectだとSSL_CLIENT_SSLを付与すればいけた
<?php
$conn = mysql_connect('hostname', 'user_name', 'password', false, MYSQL_CLIENT_SSL);

if (!$conn)
{
var_dump(mysql_error());
exit;
}

$res = mysql_query("show status like 'Ssl_cipher'");

while ( $row = mysql_fetch_assoc($res) )
{
var_dump($row);
}

mysql_close($conn);