Links#
https://dev.mysql.com/doc/refman/8.4/en/using-encrypted-connections.html
https://dev.mysql.com/doc/refman/8.4/en/encrypted-connection-protocols-ciphers.html
https://dev.mysql.com/doc/refman/8.4/en/creating-ssl-rsa-files.html
https://dev.mysql.com/doc/refman/8.4/en/connection-options.html1. Important Points#
MySQL 支持 TLS 加密连接。生产环境里,重点不是“能连上”,而是“强制加密 + 验证 CA + 验证主机名”。
server side:
enable encrypted connections
require secure transport for client connections
client side:
use VERIFY_CA or VERIFY_IDENTITY
pin CA certificate
verify server hostname when possible
do not do this in production:
ssl-mode=DISABLED
rejectUnauthorized=false
insecure_skip_verify2. Server Configuration#
常见服务端配置:
[mysqld]
require_secure_transport=ON
tls_version=TLSv1.2,TLSv1.3
ssl_ca=/etc/mysql/certs/ca.pem
ssl_cert=/etc/mysql/certs/server-cert.pem
ssl_key=/etc/mysql/certs/server-key.pemfile layout:
/etc/mysql/certs/ca.pem
/etc/mysql/certs/server-cert.pem
/etc/mysql/certs/server-key.pem
permissions:
private key should be readable only by mysql process owner
certificate files should not be world-writable检查当前状态:
SHOW VARIABLES LIKE 'require_secure_transport';
SHOW VARIABLES LIKE 'tls_version';
SHOW VARIABLES LIKE 'have_ssl';note:
MySQL 8.4 supports TLSv1.2 and TLSv1.3 for connections3. Client Configuration / Verify#
推荐用客户端显式验证:
mysql \
--host=db.example.com \
--user=shop_app \
--password \
--ssl-mode=VERIFY_IDENTITY \
--ssl-ca=/etc/mysql/certs/ca.pem \
-e "SHOW STATUS LIKE 'Ssl_cipher';"如果不方便做主机名校验,最低也要做 CA 校验:
mysql \
--host=db.example.com \
--user=shop_app \
--password \
--ssl-mode=VERIFY_CA \
--ssl-ca=/etc/mysql/certs/ca.pem验证当前会话:
SHOW STATUS LIKE 'Ssl_cipher';
SHOW STATUS LIKE 'Ssl_version';4. Java#
JDBC URL example:
jdbc:mysql://db.example.com:3306/shop?sslMode=VERIFY_IDENTITY&enabledTLSProtocols=TLSv1.2,TLSv1.3
recommendation:
trust the server CA
keep hostname verification on5. Python#
mysql-connector-python style:
ssl_ca=/etc/mysql/certs/ca.pem
ssl_verify_cert=True
ssl_verify_identity=True6. Go#
go-sql-driver/mysql style:
register a tls.Config with RootCAs and ServerName
use tls=custom in the DSN7. Node.js#
mysql2 style:
ssl:
ca: fs.readFileSync('/etc/mysql/certs/ca.pem')
rejectUnauthorized: true