はじめに
目的
本ドキュメントは、MySQLで暗号化通信(SSL/TLS)を導入する際の手順とポイントを分かりやすくまとめたガイドです。具体的には、SSLモードの種類、証明書の準備、サーバーとクライアントの設定、ファイル権限の設定、接続確認までを順に解説します。
対象読者
- 自社システムのDB通信を安全にしたいエンジニア
- 初めてMySQLのSSL設定を行う管理者
専門用語は必要最小限にし、具体例で補足しますので、初心者の方でも取り組みやすい内容です。
章の構成(全体の流れ)
- SSLモードの説明と使い分け
- 証明書の生成と準備手順
- MySQLサーバーの設定ファイル編集
- 許可・所有権の設定と配置場所
- 接続確認とトラブルシュートの方法
本ガイドの方針
実際の操作手順を重視します。作業前にバックアップを取り、テスト環境で検証することを推奨します。安全性を確保するため、証明書の保管やファイル権限には特に注意してください。
MySQLのSSLモードの種類と機能
概要
MySQLは接続時の暗号化と検証を制御する複数のSSLモードを提供します。各モードはセキュリティレベルと接続の成否条件が異なります。ここでは日常的に使う5つのモードを分かりやすく説明します。
PREFERRED
暗号化接続を試み、サーバーが対応しない場合は暗号化なしで接続します。デフォルト設定で互換性が高く、開発環境や混在環境で使いやすいです。ただし暗号化が保証されないため機密性の高い通信には注意が必要です。
REQUIRED
必ず暗号化された接続を行います。サーバーがTLSをサポートしないと接続は失敗します。社内ネットワークや外部公開されるサービスで推奨されます。
DISABLED
暗号化を行いません。設定が簡単ですが、通信が平文で流れるため本番環境では推奨しません。テスト用に限定すべきです。
VERIFY_CA
サーバー証明書の発行元(CA)を検証します。CAが信頼できる場合に有効で、中間者攻撃を防ぎます。ただしサーバー名の照合は行いません。
VERIFY_IDENTITY
CA検証に加え、証明書のホスト名と接続先のホスト名を照合します。最も厳格なモードで、本番環境での利用に適しています。
使い分けの目安
開発や互換性重視ならPREFERRED、内部サービスはREQUIRED、本番公開はVERIFY_IDENTITYを基本にしてください。VERIFY系を使う場合は正しい証明書(CN/SAN)とタイムゾーンの時刻合わせを確認すると安心です。
SSL証明書の生成と準備
前提
MySQLでSSLを使うには、まずルートCA(信頼の元)を作り、そのCAでサーバー証明書とクライアント証明書を署名します。ここではOpenSSLを例に、必要な手順と注意点を分かりやすく説明します。
1. ルートCAの作成
1) 秘密鍵を作成します(例):
openssl genrsa -out ca.key 4096
2) 自己署名証明書を作ります:
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -subj "/CN=MyLocalCA"
2. サーバー証明書の作成
1) サーバー鍵とCSRを作成します:
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=db.example.com"
2) SAN(IPやホスト名)を設定して署名します。簡易ファイル(san.ext)を作り、例:
subjectAltName = DNS:db.example.com,IP:192.0.2.10
次に署名:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 825 -sha256 -extfile san.ext
3. クライアント証明書の作成
サーバーと同様にクライアントの鍵・CSRを作り、CAで署名します。クライアントは接続時にserver.crtの代わりにclient.crtとclient.keyを使います。
注意点
- CSR作成時にCNとSANを正しく設定してください。IPで接続する場合はSANにIPを入れます。
- 鍵にパスフレーズを付けるかどうかは運用次第です。自動起動するサーバーでは外すことがありますが、鍵の保護に注意してください。
MySQLサーバーの設定ファイル編集
1) 事前準備
設定ファイル(例:/etc/my.cnf)を編集する前にバックアップを取ります。sudo cp /etc/my.cnf /etc/my.cnf.bak のように保存してください。root権限で操作します。
2) サーバー側設定例 ([mysqld])
[mysqld] セクションにSSL関連を追加します。例:
[mysqld]
ssl-ca=/etc/mysql/ssl/ca.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem
# 利用するTLSの最小バージョン指定(例: TLS 1.2)
tls-version=TLSv1.2,TLSv1.3
証明書のパスは実際の配置場所に合わせて変更してください。秘密鍵の権限は限定してください(例: 600)。
3) クライアント設定例 ([client])
クライアント側の設定は同じファイルに書くか、~/.my.cnfに記述できます。
[client]
ssl-mode=VERIFY_CA
ssl-ca=/etc/mysql/ssl/ca.pem
ssl-cert=/etc/mysql/ssl/client-cert.pem
ssl-key=/etc/mysql/ssl/client-key.pem
ssl-modeにはREQUIRED、VERIFY_CA、VERIFY_IDENTITYなどがあります。用途に応じて選んでください。
4) 設定反映と確認
設定を保存したらMySQLを再起動します(systemctl restart mysqld など)。ログにエラーが出ないか確認し、クライアントからTLS接続できるかテストします。
注意点:ファイルパスと権限を正しく設定し、間違いがあれば元のバックアップから戻してください。
ファイルのパーミッション設定と配置
配置場所の選び方
- MySQLデーモンが読み書きできる場所に置きます。一般的には /etc/mysql/ssl や /etc/ssl/mysql などを使います。
所有者とパーミッション
- 所有者をmysqlユーザーに変更します。例: chown -R mysql:mysql /etc/mysql/ssl
- 秘密鍵(private key): 600(所有者のみ読み書き可)
- サーバ証明書・CA証明書: 644(所有者は書込可、他は読み取り可)
- 証明書ディレクトリ: 700や750にして中のファイルを保護します。
コマンド例
- ディレクトリ作成: mkdir -p /etc/mysql/ssl
- 所有者変更: chown -R mysql:mysql /etc/mysql/ssl
- 秘密鍵: chmod 600 /etc/mysql/ssl/server-key.pem
- 証明書: chmod 644 /etc/mysql/ssl/server-cert.pem /etc/mysql/ssl/ca.pem
- パーミッション確認: ls -l /etc/mysql/ssl
SELinux / AppArmor の注意点
- SELinuxが有効な場合、コンテキストを設定しないとMySQLがファイルにアクセスできません。restoreconやsemanageで正しいコンテキストを付けます。
- AppArmorを使うディストリの場合はプロファイルにパスを追加してください。
動作確認
- パーミッションを設定したらMySQLを再起動してログを確認します。エラーが出ればパーミッションやコンテキストを再確認してください。
SSL接続の確認と検証
1. MySQLクライアントでの確認
MySQLに接続後、\s(バックスラッシュs)またはSTATUSコマンドを実行します。暗号化接続中は「Cipher」「SSL: Cipher in use」などが表示されます。非暗号化だと「SSL: Not in use」と出ます。
例:
mysql> STATUS;
--------------
SSL: Cipher in use is DHE-RSA-AES256-SHA
--------------
上のようにCipher名があれば暗号化されています。
2. サーバー側設定の検証
SHOW VARIABLES LIKE ‘ssl%’; を実行して、ssl_ca、ssl_cert、ssl_keyやhave_opensslの値を確認します。正しく設定されていればファイルパスが表示され、have_opensslやhave_sslがYESになります。
例:
mysql> SHOW VARIABLES LIKE 'ssl%';
+---------------+---------------------+
| Variable_name | Value |
+---------------+---------------------+
| ssl_ca | /etc/mysql/ca.pem |
| ssl_cert | /etc/mysql/server.pem |
| ssl_key | /etc/mysql/server-key.pem |
+---------------+---------------------+
3. クライアントからTLSを強制
接続時にオプションを指定します:
mysql –ssl-mode=REQUIRED -u user -p -h host
検証を厳密にするなら –ssl-mode=VERIFY_CA または –ssl-mode=VERIFY_IDENTITY を使います。
4. 非暗号化と出たときの対処
1) サーバーが証明書を読み込んでいるか設定ファイルとパーミッションを確認します。
2) サーバー再起動後にSHOW VARIABLESで反映を確認します。
3) クライアント側がTLSを拒否していないかオプションを確認します。












