しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Database for MySQL の SSL 接続が分かりにくい話

Build 2017 で発表された Azure Database for MySQL ですが、デフォルトで SSL での接続のみ許可されるようになっています。基本的に SSL で接続するべきだと思うので、無効化するのはお勧めしません。

Azure のドキュメントにも SSL に関する記事がいくつか用意されているので、一読をお勧めします。

実際に WordPress から SSL 接続を行う場合には、三宅さんが既に記事を書いてくださっているので、この手順通りにするとセキュアな MySQL 接続が行えます。

ドキュメントを読むと、少し気になる記述があることに気が付きました。証明書に関する問題です。

Currently, there is a known issue if you use "--ssl-mode=VERIFY_IDENTITY" option in your mysql.exe connection to the service, the connection will fail with the following error: ERROR 2026 (HY000): SSL connection error: SSL certificate validation failure Please downgrade to "--ssl-mode=VERIFY_CA" or lesser SSL modes. If you require to use "--ssl-mode=VERIFY_IDENTITY", then you can ping your server name to resolve the regional server name, such as westeurope1-a.control.database.windows.net, and use that regional server name in the connection until this issue is resolved. We plan to remove this limitation in the future.

Configure SSL connectivity in your application to securely connect to Azure Database for MySQL | Microsoft Docs

mysql クライアントのオプションとして --ssl-mode=VERIFY_IDENTITY を選ぶと、接続に失敗するという問題です。VERIFY_CA に変更すると繋がるようになるみたいですが、気になる問題です。

オプションに関してはドキュメントを読んでおきました。VERIFY_IDENTITY の場合は CN のチェックまでを行うようになるみたいでした。

https://dev.mysql.com/doc/refman/5.7/en/secure-connection-options.html#option_general_ssl-mode

つまり、今の Azure Database for MySQL は異なる CN の証明書を返してくるということです。Issue として認識はされているみたいですけど、Public Preview までに改善しておいて欲しかったですね。

オプションの組み合わせについてはいくつかパターンがあるので、実際に試してみた結果が以下です。

mysql -h xxxx.mysql.database.azure.com -u xxxx@xxxx -p
> OK

mysql -h xxxx.mysql.database.azure.com -u xxxx@xxxx -p --ssl-mode=DISABLED
> ERROR 2001 (28000): SSL connection is required. Please specify SSL options and retry.

mysql -h xxxx.mysql.database.azure.com -u xxxx@xxxx -p --ssl-mode=VERIFY_CA --ssl-ca=MyServerCACert.pem
> OK

mysql -h xxxx.mysql.database.azure.com -u xxxx@xxxx -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=MyServerCACert.pem
> ERROR 2026 (HY000): SSL connection error: SSL certificate validation failure

mysql -h xxxx.control.database.windows.net -u xxxx@xxxx -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=MyServerCACert.pem
> OK

試したところ --ssl-mode を指定しなくても接続できるのは少し違和感がありますが、一応 Azure の推奨は --ssl-ca を指定する方法なので、それに従っておくことにします。

ちなみにログイン後に status を打ち込むと接続状態を確認できます。AES で暗号化されていますね。

f:id:shiba-yan:20170528030252p:plain

証明書の CN が異なっているので、実際に SSL で接続する場合には CN の検証を行わないように設定する必要があるので注意ですね。それでいいのかという問題はひとまず置いておきます。

本当に CN が異なっているのか、SSL の Server Hello をキャプチャして確認しました。

f:id:shiba-yan:20170528030025p:plain

xxxx.mysql.database.azure.com に対して接続しているのに対して、実際にサーバーから送信された証明書は xxxx.control.database.windows.net が指定されています。

結局のところ CNAME で別名が付けられているのに、証明書が対応していないというオチでした。

f:id:shiba-yan:20170528030920p:plain

GA までには直ると思いますが、今すぐ使い始めようと考えている人は CN のチェックを行わない設定で使うことと、直ったタイミングでちゃんと検証を行うように修正することが必要となるでしょう。

思ったより MySQL と PHP で SSL 接続する情報が少ないのは何故でしょうね。気になりました。