首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL SSL 主從複寫完整實戰:憑證建立、配置與常見錯誤排查

     編輯:MySQL 資料庫相關知識

前言

跨公網進行 MySQL 複寫時,資料以明文傳輸極易被竊聽或竄改。啟用 SSL/TLS 不僅能加密複寫流量,透過雙向憑證驗證還能防止暴力破解與中間人攻擊。本文完整記錄從 OpenSSL 安裝、CA 建立、伺服器/客戶端憑證簽發、MySQL 配置到複寫啟動的全流程,並針對常見錯誤(時間不同步、權限錯誤、憑證路徑錯誤)給出解決方案。

一、環境準備與 OpenSSL 安裝

# 建議使用系統套件管理器安裝,避免手動編譯版本不一致
yum install -y openssl openssl-devel  # CentOS/RHEL
apt-get install -y openssl libssl-dev  # Debian/Ubuntu

驗證版本:openssl version 應為 1.1.1 或 3.0+(支援 TLS 1.2/1.3)。

二、啟用 MySQL SSL 支援

2.1 檢查目前狀態

SHOW VARIABLES LIKE '%ssl%';

若 have_ssl、have_openssl 顯示 DISABLED,需確認編譯參數 -DWITH_SSL=system 或安裝官方 RPM/DEB(已內建 SSL)。

2.2 修改 my.cnf 啟用 SSL

[mysqld]
ssl=ON
ssl_ca=/etc/mysql/ssl/ca.pem
ssl_cert=/etc/mysql/ssl/server-cert.pem
ssl_key=/etc/mysql/ssl/server-key.pem

[client]
ssl=ON
ssl_ca=/etc/mysql/ssl/ca.pem
ssl_cert=/etc/mysql/ssl/client-cert.pem
ssl_key=/etc/mysql/ssl/client-key.pem

重啟 MySQL 後再次執行 SHOW VARIABLES LIKE '%ssl%',應顯示 YES。

三、建立私有 CA 與伺服器/客戶端憑證

所有操作在 **主庫** 執行,完成後將對應檔案分發至從庫。

3.1 建立 CA 目錄結構

mkdir -p /etc/mysql/ssl/{certs,crl,newcerts,private}
touch /etc/mysql/ssl/index.txt
echo 01 > /etc/mysql/ssl/serial
echo 01 > /etc/mysql/ssl/crlnumber

3.2 產生 CA 私鑰與自簽憑證

# 私鑰 4096 bits,有效期 10 年
(umask 077; openssl genrsa -out /etc/mysql/ssl/private/ca-key.pem 4096)
openssl req -new -x509 -key /etc/mysql/ssl/private/ca-key.pem \
  -out /etc/mysql/ssl/certs/ca.pem -days 3650 \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/OU=DBA/CN=MySQL-CA"

3.3 產生伺服器憑證(主庫與從庫各一組)

# 主庫
openssl genrsa -out /etc/mysql/ssl/private/server-key.pem 2048
openssl req -new -key /etc/mysql/ssl/private/server-key.pem \
  -out /etc/mysql/ssl/certs/server-req.pem \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/OU=DBA/CN=mysql-master"
openssl x509 -req -in /etc/mysql/ssl/certs/server-req.pem \
  -CA /etc/mysql/ssl/certs/ca.pem -CAkey /etc/mysql/ssl/private/ca-key.pem \
  -CAcreateserial -out /etc/mysql/ssl/certs/server-cert.pem -days 365 -sha256

# 從庫(CN 不同)
openssl genrsa -out /etc/mysql/ssl/private/client-key.pem 2048
openssl req -new -key /etc/mysql/ssl/private/client-key.pem \
  -out /etc/mysql/ssl/certs/client-req.pem \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/OU=DBA/CN=mysql-slave"
openssl x509 -req -in /etc/mysql/ssl/certs/client-req.pem \
  -CA /etc/mysql/ssl/certs/ca.pem -CAkey /etc/mysql/ssl/private/ca-key.pem \
  -CAcreateserial -out /etc/mysql/ssl/certs/client-cert.pem -days 365 -sha256

3.4 驗證憑證鏈

openssl verify -CAfile /etc/mysql/ssl/certs/ca.pem \
  /etc/mysql/ssl/certs/server-cert.pem /etc/mysql/ssl/certs/client-cert.pem

3.5 設定檔案權限並分發

chown -R mysql:mysql /etc/mysql/ssl
chmod 600 /etc/mysql/ssl/private/*.pem
chmod 644 /etc/mysql/ssl/certs/*.pem

# 將 ca.pem、client-cert.pem、client-key.pem 複製到從庫相同路徑
scp /etc/mysql/ssl/certs/ca.pem /etc/mysql/ssl/certs/client-cert.pem /etc/mysql/ssl/private/client-key.pem slave:/etc/mysql/ssl/

四、建立複寫帳號(強制 SSL)

CREATE USER 'repl'@'%' IDENTIFIED BY 'ReplPassw0rd!' REQUIRE SSL;
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

五、主庫備份與從庫初始化

# 主庫:取得 binlog 位置
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
# 記下 File 與 Position,例如 mysql-bin.000007, 1015
UNLOCK TABLES;

# 使用 xtrabackup 或 mysqldump 完整備份並傳輸至從庫
# 從庫:還原資料、設定 server-id、relay-log 等

六、從庫啟動 SSL 複寫

CHANGE MASTER TO
  MASTER_HOST='192.168.1.100',
  MASTER_USER='repl',
  MASTER_PASSWORD='ReplPassw0rd!',
  MASTER_LOG_FILE='mysql-bin.000007',
  MASTER_LOG_POS=1015,
  MASTER_SSL=1,
  MASTER_SSL_CA='/etc/mysql/ssl/certs/ca.pem',
  MASTER_SSL_CERT='/etc/mysql/ssl/certs/client-cert.pem',
  MASTER_SSL_KEY='/etc/mysql/ssl/private/client-key.pem',
  MASTER_SSL_VERIFY_SERVER_CERT=1;

START SLAVE;
SHOW SLAVE STATUS\G

關鍵欄位應顯示:Slave_IO_Running: Yes、Slave_SQL_Running: Yes、Master_SSL_Allowed: Yes。

七、常見錯誤與排查

錯誤訊息原因解決
SSL connection error: ASN: before date in the future主從伺服器系統時間不同步安裝 chrony/ntpdate 強制同步:ntpdate pool.ntp.org
Access denied for user 'repl'@'...' (using password: YES)未加 REQUIRE SSL 或憑證路徑錯誤重建帳號加 REQUIRE SSL;檢查 MASTER_SSL_* 路徑與權限
SSL error: unable to get private key私鑰檔案權限非 600 或擁有者非 mysqlchown mysql:mysql /etc/mysql/ssl/private/*key.pem && chmod 600 /etc/mysql/ssl/private/*key.pem
Master_SSL_Verify_Server_Cert: No未啟用伺服器憑證驗證在 CHANGE MASTER TO 加入 MASTER_SSL_VERIFY_SERVER_CERT=1

八、驗證加密連線

# 從庫測試 SSL 連線
mysql -u repl -p -h 192.168.1.100 \
  --ssl-ca=/etc/mysql/ssl/certs/ca.pem \
  --ssl-cert=/etc/mysql/ssl/certs/client-cert.pem \
  --ssl-key=/etc/mysql/ssl/private/client-key.pem \
  -e "SHOW STATUS LIKE 'Ssl_cipher';"

# 主庫查看複寫執行緒 SSL 狀態
SHOW PROCESSLIST;
# 應看到 system user 執行緒的 Command 為 "Binlog Dump",且 Info 含有 SSL

結語: SSL 複寫不僅滿足合規需求,更是跨公網部署的基礎防線。建議搭配 require_secure_transport=ON 強制所有連線走 TLS,並定期輪換憑證(每年一次)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved