2026年7月22日
2026年7月22日
WordPressとMySQLの接続をSSL/TLSで暗号化する設定手順
WordPress とデータベースが別のサーバーにある場合、wp-config.php に MYSQL_CLIENT_FLAGS を定義すると、PHP(mysqli)から MySQL/MariaDB への接続を TLS で暗号化できます。この記事では、DB サーバー側の準備、WordPress 側の設定、そして「本当に暗号化されているか」を確かめる方法までを順に説明します。
そもそも暗号化が必要な構成か確認する
最初に、自分のサイトが対象になるかを確認します。wp-config.php の DB_HOST が localhost の場合、PHP は多くの環境で Unix ソケット経由で接続しており、通信はネットワークに出ません。この構成では TLS を設定しても得られるものはほとんどありません。
暗号化が意味を持つのは、次のように DB への通信がネットワークを通る構成です。
- Web サーバーと DB サーバーを分けている(VPS 2台構成、Amazon RDS、マネージド DB など)
- 複数の Web サーバーから 1台の DB に接続している
- DB への経路に、自分で管理していないネットワーク区間が含まれる
この場合、DB のユーザー名・パスワードを含む認証のやり取りや、投稿・会員情報などのクエリ結果が経路上を流れます。プライベートネットワーク(VPC 内通信など)であっても、TLS を重ねておくと、経路の設定ミスや内部からの盗聴に対する備えになります。
DB サーバー側で TLS を有効にする
TLS が使える状態か確認する
MySQL 8.0 以降は、証明書ファイルが無い場合に起動時に自己署名証明書を自動生成し、TLS を受け付ける状態になっているのが一般的です。MariaDB は設定ファイルで証明書を指定するまで TLS が無効なことが多いので、まず現状を確認します。
-- DB サーバー上で管理ユーザーとして実行
SHOW GLOBAL VARIABLES LIKE 'tls_version';
SHOW GLOBAL VARIABLES LIKE 'ssl_%';
ssl_cert や ssl_key が空、または tls_version が空なら、TLS はまだ使えません。
証明書を設定する
社内 CA や自己署名 CA で発行したサーバー証明書を使う場合、my.cnf(MariaDB なら server.cnf など)に次のように指定します。パスやファイル名は環境に合わせて読み替えてください。設定変更の前に、既存の設定ファイルと DB のバックアップを取っておきます。
[mysqld]
ssl_ca = /etc/mysql/certs/ca.pem
ssl_cert = /etc/mysql/certs/server-cert.pem
ssl_key = /etc/mysql/certs/server-key.pem
鍵ファイルは DB のプロセスが読めて、他のユーザーからは読めない権限にしておきます。再起動後、先ほどの SHOW GLOBAL VARIABLES で値が入っていることを確かめます。
Amazon RDS や Aurora などのマネージド DB では、サーバー証明書はサービス側が用意しています。自分で証明書を置く必要はありませんが、クライアントが検証に使う CA バンドルはサービスのドキュメントから入手します。CA の世代は更新されることがあるため、利用中の CA と有効期限もあわせて確認してください。
暗号化していない接続を拒否する
TLS を「使える」状態にしただけでは、平文での接続も受け付けたままです。WordPress 側の設定が終わり、TLS で接続できることを確認してから、次のどちらかで平文接続を拒否します。
-- 方法1: WordPress 用ユーザーにだけ TLS を要求する
ALTER USER 'wp_user'@'10.0.0.%' REQUIRE SSL;
# 方法2: サーバー全体でネットワーク越しの平文接続を拒否する
[mysqld]
require_secure_transport = ON
方法1 は影響範囲が小さく、段階的に導入しやすいのが利点です。方法2 はすべてのネットワーク接続に適用されるため、バックアップスクリプトや監視ツールなど、他のクライアントが TLS に対応しているかを先に洗い出しておく必要があります。なお、require_secure_transport を有効にしても Unix ソケット経由の接続は安全な経路として扱われ、引き続き許可されます。RDS for MySQL や Aurora MySQL では、同じ名前のパラメータをパラメータグループで設定する形になります(2026年10月現在、詳細は各サービスのドキュメントで確認してください)。
WordPress 側の設定
MYSQL_CLIENT_FLAGS を定義する
WordPress のデータベースクラス wpdb は、接続時に MYSQL_CLIENT_FLAGS 定数が定義されていればその値を mysqli の接続フラグとして渡します。TLS を使うには MYSQLI_CLIENT_SSL を指定します。
wp-config.php の、require_once ABSPATH . 'wp-settings.php'; より前(「編集が必要なのはここまでです」のコメントより上)に追記します。
// DB 接続を TLS で暗号化する
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL );
あわせて DB_HOST が DB サーバーのホスト名になっているかを確認します。サーバー証明書のホスト名検証を行う構成では、IP アドレスではなく証明書に含まれるホスト名で接続する必要があります。
wp-config.php を編集する前にはファイルのコピーを取り、まずステージング環境で試してください。設定に誤りがあると、サイト全体が「データベース接続確立エラー」になります。
証明書の検証について知っておくこと
MYSQLI_CLIENT_SSL は通信を暗号化しますが、サーバー証明書をどこまで検証するかは、PHP の mysqlnd のバージョンや php.ini の OpenSSL 関連設定によって変わります。WordPress コアには、執筆時点で確認できる範囲では CA 証明書のパスを直接渡すための定数が用意されていません。
検証まで厳密に行いたい場合は、PHP が参照する CA ストアに DB の CA 証明書を追加する、wpdb を拡張するドロップイン(wp-content/db.php)を用いる、といった方法がありますが、いずれも PHP やホスティング環境に依存します。どの方法でも、ステージングで「誤った CA のときに接続が失敗するか」を試して、検証が働いていることを確かめてください。
PHP には検証を無効にする MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT というフラグもあります。原因の切り分けで一時的に使うことはあっても、本番でこのフラグを残すと「暗号化はされているが相手が本物か確かめていない」状態になり、なりすましに弱くなります。
暗号化されているかを確認する
設定を入れただけで満足せず、WordPress が実際に使っている接続で TLS が有効かを確認します。wp db query は内部で mysql コマンドを呼び出すため、PHP の接続とは別物です。WordPress の接続そのものを調べるには、WP-CLI の wp eval-file で wpdb を通してクエリを実行します。
<?php
// check-db-tls.php(確認が終わったら削除する)
global $wpdb;
$row = $wpdb->get_row( "SHOW SESSION STATUS LIKE 'Ssl_cipher'" );
echo ( $row && '' !== $row->Value ) ? 'TLS 使用中: ' . $row->Value : 'TLS 未使用';
echo PHP_EOL;
wp eval-file check-db-tls.php
暗号スイート名(例: TLS_AES_256_GCM_SHA384)が表示されれば暗号化されています。空なら平文です。
ただし、WP-CLI が使う PHP(CLI 版)と、Web で動く PHP-FPM では php.ini が別のことがあります。Web 側も確かめたい場合は、DB サーバー側で接続中のセッションの状態を確認します。MySQL 8.0 なら performance_schema から、スレッドごとの TLS の状態を見られます。
SELECT t.PROCESSLIST_USER, t.PROCESSLIST_HOST, s.VARIABLE_VALUE AS tls_version
FROM performance_schema.threads t
JOIN performance_schema.status_by_thread s
ON s.THREAD_ID = t.THREAD_ID AND s.VARIABLE_NAME = 'Ssl_version'
WHERE t.PROCESSLIST_USER = 'wp_user';
接続できなくなったときの切り分け
設定後に「データベース接続確立エラー」が出た場合、可能性の高い順に次を確認します。
- DB サーバー側で TLS が有効になっていない:
SHOW GLOBAL VARIABLES LIKE 'tls_version';が空なら、サーバー側の証明書設定が読み込まれていません。設定ファイルの場所と再起動を確認します。 - 証明書の検証に失敗している: 自己署名証明書や、CA が PHP 側に知られていない場合に起こります。PHP のエラーログに SSL 関連のメッセージが出ていないかを確認し、CA の配置を見直します。
- ホスト名の不一致:
DB_HOSTを IP アドレスにしていて、証明書のホスト名と一致しないケースです。証明書に含まれる名前で接続します。 - TLS バージョンの不一致: 新しい MySQL では古い TLS 1.0/1.1 が使えなくなっています。古い PHP や OpenSSL の組み合わせだと交渉に失敗することがあります。
原因が分からないまま本番が止まった場合は、wp-config.php の MYSQL_CLIENT_FLAGS の行をコメントアウトすれば元の接続に戻せます(DB 側で平文接続を拒否する設定をまだ入れていない場合)。この「戻し方」を用意しておくためにも、平文接続の拒否は最後に行います。
暗号化とあわせて見直したいこと
通信の暗号化は、DB を守る対策の一部にすぎません。次の点もあわせて見直すと効果が高まります。
- DB のポート(通常 3306)を、Web サーバーの IP アドレスからだけ受け付けるようにファイアウォールやセキュリティグループで絞る
- WordPress 用の DB ユーザーに、そのサイトのデータベース以外の権限を与えない
- wp-config.php のパーミッションを見直し、Web から読まれないようにする
- バックアップファイルの転送経路や保存先も暗号化する
まとめ
- DB が別サーバーにある構成では、wp-config.php に
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL );を追加すると WordPress の DB 接続を TLS で暗号化できる - 先に DB サーバー側で TLS を有効にし、WordPress 側で接続を確認してから、
REQUIRE SSLやrequire_secure_transportで平文接続を拒否する - 証明書の検証の扱いは PHP 環境に依存するため、ステージングで誤った CA のときに失敗するかまで試す
- 確認は
wp eval-fileで wpdb 経由のSsl_cipherを見るか、DB 側の performance_schema で行う - 作業前に wp-config.php と DB のバックアップを取り、戻し方を決めておく