Azure MySQLでWordPressからのSSL接続を有効にする

Build2017でいよいよパブリックプレビューとなった Azure Database for MySQL ですが、既存のClearDBからの移行を試していると、(プレビューということもあり)案の定いくつかの問題に遭遇してしまいました。

ここでは、App ServiceにデプロイしているWordPressからのMySQLへのSSL接続について、発生する問題を回避しつつ設定する方法を紹介します。

Azure Database for MySQLのセキュリティ構成

Azure Database for MySQL(以下Azure MySQL)には、[接続のセキュリティ]という設定項目があり、デフォルトではSSL接続の強制が有効になっています。ファイアウォールについても設定が必須になっています。
したがって、WordPress側に何も設定しないままだと、(当然ですが)SSL接続が必須のMySQLサーバには接続ができません。

ポータルでのセキュリティ設定

まあ、SSL強制をOFFにするという荒技もありますが、Azureに限らずパブリッククラウドのDBaaSではほとんどがSSL接続を推奨しているので、ここはSSL接続に拘りたいところです。

設定手順

WordPressからのMySQLへのSSL接続は、世の中的にあまり実績が無いのか(WordPress公式サイトを含めて)思ったより情報が少なく、唯一頼りになった情報は、結局MS本社のApp Service Teamブログ Connect Azure App Service to Azure database for MySQL and PostgreSQL via SSL のみという状況でした。

このブログではWordPressを含めて主要フレームワークからの接続事例が掲載されているので、基本的にはこの通りで良いのですが、若干わかりにくい手順になっていたので、以下に整理したものを掲載します。

Azure MySQLとのSSL通信に必要なローカル証明書ファイルの準備

  • 証明機関 (CA) 証明書ファイル (.cer) をここからダウンロードします。
  • OpenSSLで.pem形式に変換します(MyServerCACert.pemとします)。
OpenSSL> x509 -inform DER -in BaltimoreCyberTrustRoot.cer -out MyServerCACert.pem

App Serviceへの証明書のアップロード

  • kudu等を使って、App ServiceのD:\home\site\wwwrootbinディレクトリを作成します。
  • ローカルで生成した.pemファイルの内容をテキストエディタでコピーしておきます。
  • kuduのコンソールでbin配下に空のMyServerCACert.pemファイルを作成します。

kuduコンソールでのpemファイル作成

コンソールでMyServerCACert.pemを編集し、コピーしておいた証明書の文字列をペーストして保存します。

アプリケーション設定に証明書のパスを追加

App Serviceの[アプリケーション設定]にて、以下のKey-Valueを追加します。

  • key: MYSQL_SSL_CA
  • value: D:\home\site\wwwroot\bin\MyServerCACert.pem

アプリケーション設定

wp-config.phpの編集

wp-config.phpに以下の記述を追記します。

define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);
define('MYSQL_SSL_CA', getenv('MYSQL_SSL_CA'));

1つ目では、phpのmysqli拡張のSSL接続定数を設定しています。本家ブログの方では、PHP7.0で廃止されてしまったmysql拡張の方の定数(MYSQL_CLIENT_SSL)を呼んでいましたが、それを使うとPHP7.0以上の環境ではDB接続エラーとなります。

必ず、MYSQLI_CLIENT_SSL(MYSQLの後ろにIがついている方)の方を入れましょう。あと、この件に関しては、 @m2wasabi さんに調査をサポートしてもらいました。ありがとうございました!

2つ目では、先ほどApp Settingに追加した値 MYSQL_SSL_CA を環境変数として読み込んで、証明書のパスを取得しています。

あとは、普通にAzure MySQLの接続先情報をwp-config.phpにセットすれば問題なくSSL接続でMySQLに繋がるようになります。

その他、Azure MySQLに関してはファイアウォール設定でもいろいろあるので別の機会に書きたいと思います。