BLOGTIMES
2014/01/14

MySQL に SSL 接続できないときはキーの形式を確認すべし

  mysql  ssl 
このエントリーをはてなブックマークに追加

Amazon RDS 上の MySQL 対しては SSL 接続を試したことがあったので、自前のサーバにも簡単に SSL 接続できるだろうと思って挑戦してみたら、変なところにはまり込んでしまったのでその顛末をメモ。

例えば MySQL Connector/ODBC を使って MySQL に SSL 接続したい場合には下記のように SSL Key や SSL CertificateSSL Certificate Authority を設定する必要があります。
MySQL Connector/ODBC - MySQL に SSL 接続できないときはキーの形式を確認すべし

上記は一見、正しいようにみえるのですが、実際に接続しようとすると下記のような「SSL connection error: Unable to get private key (#2026)」というエラーが発生します。
MySQL ODBC エラー - MySQL に SSL 接続できないときはキーの形式を確認すべし

キーは openssl で生成で生成しているので、壊れているはずはない・・・・・・と思っていたのですが、それが間違いの始まりでした。結論から言えば、MySQL は SSL キーの形式が PKCS#8 だと上手く接続できないことがあるようです。少なくとも MySQL-server-5.6.15-1.el6.x86_64.rpm や MySQL Connector/ODBC 5.2、MySQL Workbench 6.0 は読み込むことができませんでした(ただし CentOS 6.x 標準の mysql-server-5.1.71-1.el6.x86_64 は PKCS#8 でも問題なく動いたので、バージョンによる違いはあるみたいです。)。

これについては、既に下記でバグとして報告されています。

MySQL Bugs: #71271: MySQL fails to load PKCS#8 private key

A private key can be in PKCS#1 or PKCS#8 format.

The PKCS#1 format can be recognized as it starts with
-----BEGIN RSA PRIVATE KEY-----

The PKCS#8 format can be recognized as it starts with
-----BEGIN PRIVATE KEY-----

MySQL accepts keys in PKCS#1 format, but fails to load keys in PKCS#8 format.

キーの形式は見分けがつきにくいですが、テキストエディタで開いたときに-----BEGIN RSA PRIVATE KEY-----で始まっている場合は PKCS#1(=読み込める)、-----BEGIN PRIVATE KEY-----で始まっている場合は PKCS#8(=読み込めないことがある)という感じです。このバグを回避するためには PKCS#8 を PKCS#1 に変換するには openssl を使って下記のようなコマンドを実行すれば OK です。

openssl rsa -in pkcs8.key -out pkcs1.key

くだらないことですが、だいぶ時間を食ってしまいました。

証明書を自動生成するスクリプト

今回はこんなスクリプトを書いて必要な証明書を自動生成するようにしていました。

make_cert.sh

openssl genrsa -out ca.key 2048 openssl req -new -x509 -nodes -config openssl.cnf -extensions v3_ca -days 10000 -key ca.key -out ca.crt -subj '/C=JP/ST=Tokyo/L=Chuo-ku/O=Foo/OU=Bar/CN=BarCA' openssl req -newkey rsa:2048 -days 10000 -nodes -config openssl.cnf -extensions usr_cert -keyout mysql.key -out mysql.req -subj '/C=JP/ST=Tokyo/L=Chuo-ku/O=Foo/OU=Bar/CN=mysql.example.com' openssl x509 -req -in mysql.req -days 10000 -CA ca.crt -CAkey ca.key -out mysql.crt -set_serial 01 -extfile openssl.cnf -extensions usr_cert openssl req -newkey rsa:2048 -days 10000 -nodes -config openssl.cnf -extensions usr_cert -keyout client.key -out client.req -subj '/C=JP/ST=Tokyo/L=Chuo-ku/O=Foo/OU=Bar/CN=client.example.com' openssl x509 -req -in client.req -days 10000 -CA ca.crt -CAkey ca.key -out client.crt -set_serial 01 -extfile openssl.cnf -extensions usr_cert

openssl.cnf については CentOS 6.x の標準のものから nsCertType などを書き換えたものを使っています。

diff -u /etc/pki/tls/openssl.cnf openssl.cnf

--- /etc/pki/tls/openssl.cnf 2013-12-13 00:12:32.000000000 +0900 +++ openssl.cnf 2013-11-12 15:42:49.462470657 +0900 @@ -184,10 +184,12 @@ # nsCertType = client, email # and for everything including object signing: -# nsCertType = client, email, objsign +#nsCertType = client, email, objsign + +nsCertType = server, client, email, objsign # This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment +keyUsage = nonRepudiation, digitalSignature, keyEncipherment # This will be displayed in Netscape's comment listbox. nsComment = "OpenSSL Generated Certificate" @@ -244,10 +246,10 @@ # Key usage: this is typical for a CA certificate. However since it will # prevent it being used as an test self-signed certificate it is best # left out by default. -# keyUsage = cRLSign, keyCertSign +keyUsage = cRLSign, keyCertSign # Some might want this also -# nsCertType = sslCA, emailCA +nsCertType = sslCA, emailCA # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy

    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/6405
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン