MySQL在默认安装完成后,客户端与服务端之间的网络传输通常不经过加密,包括登录凭证、SQL语句以及返回的数据集都可能以明文形式经过网络设备。如果应用服务器和数据库服务器部署在不受信任的网络环境中,攻击者可以通过抓包工具直接读取敏感信息。启用SSL/TLS加密后,MySQL会在传输层建立安全通道,对数据进行加密和完整性校验,有效降低中间人攻击和数据泄露的风险。配置过程主要集中在证书准备、服务端参数调整、客户端连接方式修改以及最终验证四个阶段。

一、生成SSL证书与密钥文件
MySQL的SSL依赖X.509证书体系。最简单的做法是使用OpenSSL生成一套自签名证书,这套证书包括一个CA证书、一个服务器证书和对应的私钥。如果业务对安全要求更高,还可以为每个客户端签发独立的客户端证书,实现双向认证。自签名证书适合内部测试或中小规模生产环境,如果已经有企业CA,则可以直接由企业CA签发服务器证书。
生成证书时需要规划好文件存放目录,例如Linux下可以放在/etc/mysql/certs/,Windows下可以放在C:\ProgramData\MySQL\certs\。证书文件后续会被MySQL服务进程读取,因此必须保证运行MySQL服务的系统账户对证书文件有读取权限。私钥文件的权限尤其要严格控制,建议设置为600,避免其他用户读取。
下面是一套完整的OpenSSL命令示例,用于生成CA证书、服务器证书和服务器私钥。命令中的重定向符号在代码块中已做转义处理。
# 创建证书存放目录 mkdir -p /etc/mysql/certs cd /etc/mysql/certs # 生成CA私钥 openssl genrsa 2048 > ca-key.pem # 生成CA自签名证书,有效期10年 openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca.pem # 生成服务器私钥和证书签名请求 openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem # 使用CA签署服务器证书,有效期10年 openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem # 清理证书请求文件 rm -f server-req.pem # 设置文件权限 chmod 600 server-key.pem chmod 644 ca.pem server-cert.pem
上述命令执行过程中,openssl会交互式询问国家、省份、组织名称等信息,这些信息会被写入证书。对于服务器证书的通用名称,建议填写数据库服务器的实际主机名或IP地址。如果客户端启用了主机名验证,证书中的CN或SAN必须与连接地址一致,否则握手会失败。自签名CA证书是服务端和客户端建立信任的基础,客户端需要信任该CA证书才能验证服务器身份。
二、配置MySQL服务端启用SSL
证书生成完成后,需要修改MySQL的配置文件,让服务进程加载这些证书。在Linux系统中,配置文件通常位于/etc/mysql/my.cnf或/etc/my.cnf;Windows系统下则可能是my.ini文件。找到[mysqld]段,添加SSL相关的配置项。如果希望强制所有远程连接都必须使用SSL,可以同时开启require_secure_transport参数。
配置项ssl-ca指向CA证书,ssl-cert指向服务器证书,ssl-key指向服务器私钥。这三个参数缺一不可。设置require_secure_transport为ON之后,所有未使用SSL的TCP连接都会被拒绝,包括root用户通过命令行连接时也必须添加SSL参数。对于本地socket连接是否要求SSL,不同MySQL版本行为略有差异,一般需要单独测试。
[mysqld] ssl-ca=/etc/mysql/certs/ca.pem ssl-cert=/etc/mysql/certs/server-cert.pem ssl-key=/etc/mysql/certs/server-key.pem require_secure_transport=ON
修改配置文件后需要重启MySQL服务。在Linux下可以使用systemctl restart mysql或service mysql restart,Windows下则通过服务管理界面或命令net stop mysql和net start mysql完成重启。重启完成后,使用具有管理员权限的账号登录MySQL,执行SHOW VARIABLES LIKE 'have_ssl'查看SSL支持状态。如果返回值为YES,说明服务端已经成功加载证书;如果返回DISABLED,则说明配置未生效或者证书路径错误。
SHOW VARIABLES LIKE 'have_ssl'; SHOW VARIABLES LIKE 'ssl_ca'; SHOW VARIABLES LIKE 'ssl_cert'; SHOW VARIABLES LIKE 'ssl_key';
服务端还需要确认MySQL版本是否支持SSL。MySQL 5.7及以上版本默认编译了SSL支持,但个别二进制发行版可能没有启用。如果have_ssl始终为DISABLED,可以用mysqld --verbose --help | grep ssl查看编译时是否包含ssl参数。同时检查MySQL错误日志,里面会记录证书加载失败的具体原因,例如权限不足或文件格式不正确。
三、配置MySQL客户端通过SSL连接
服务端启用SSL之后,客户端需要显式指定SSL模式才能建立加密连接。MySQL 5.7及以上版本提供--ssl-mode参数,可选值包括DISABLED、PREFERRED、REQUIRED、VERIFY_CA和VERIFY_IDENTITY。默认值是PREFERRED,即优先尝试SSL,但如果服务端不支持则回退到明文。为了确保安全,建议至少设置为REQUIRED,强制要求加密。
命令行客户端连接时可以使用以下参数。其中--ssl-ca指定客户端信任的CA证书路径,用于验证服务端证书。如果使用VERIFY_CA或VERIFY_IDENTITY模式,必须提供该参数。如果不想验证证书,只要求加密通道,可以使用--ssl-mode=REQUIRED而不指定--ssl-ca。
mysql -h 192.168.1.100 -u dbuser -p \ --ssl-mode=REQUIRED \ --ssl-ca=/etc/mysql/certs/ca.pem
对于Java应用,如果使用JDBC连接MySQL,需要在连接URL中加入SSL相关参数。常用的参数包括useSSL、requireSSL和verifyServerCertificate。useSSL=true表示启用SSL,requireSSL=true表示要求加密连接,verifyServerCertificate=false表示不验证服务器证书。生产环境建议将verifyServerCertificate设置为true,并通过truststore导入CA证书。
String url = "jdbc:mysql://192.168.1.100:3306/test?useSSL=true&requireSSL=true&verifyServerCertificate=false";
Properties props = new Properties();
props.setProperty("user", "dbuser");
props.setProperty("password", "secret");
Connection conn = DriverManager.getConnection(url, props);
如果使用其他编程语言或客户端工具,原理基本一致,都是通过连接参数指定SSL模式以及CA证书路径。例如Python的pymysql库可以通过ssl参数传入ca证书,Navicat等图形化工具在连接配置中勾选Use SSL并选择证书文件。无论使用哪种客户端,都应该避免使用DISABLED模式,防止在不知情的情况下回退到明文连接。
四、验证SSL连接是否真正生效
客户端成功建立连接后,并不代表连接一定使用了加密。MySQL提供了多个状态变量和命令用于确认当前会话的SSL状态。最直接的方式是在MySQL客户端中执行SHOW STATUS LIKE 'Ssl_cipher',如果返回的Value不为空,说明当前会话使用了SSL加密,返回的是协商出的加密套件名称。如果Value为空,则说明连接没有启用SSL。
SHOW STATUS LIKE 'Ssl_cipher'; SHOW STATUS LIKE 'Ssl_version';
还可以在登录后的客户端中使用\s命令查看连接信息,输出中会包含SSL字段,显示Cipher in use等信息。对于已经建立的连接,也可以通过performance_schema.session_status表查询SSL相关状态。这些验证手段在做自动化运维或合规审计时非常有用,可以将SSL状态写入监控指标,确保所有数据库连接都符合加密要求。
需要注意的是,SSL加密会带来一定的CPU开销,尤其是在大量小查询的场景下,加解密操作会消耗额外的计算资源。不过在现代硬件上,这个开销通常不超过10%,对于大多数业务而言,用少量性能换取数据安全是完全值得的。如果对性能极其敏感,可以考虑只在跨网络或非信任链路上启用SSL,而在本机socket连接中关闭SSL。
五、常见配置错误与排查思路
证书文件权限问题是导致SSL配置失败最常见的原因之一。MySQL服务进程通常以mysql系统账户运行,如果证书目录或私钥文件的所有者是root且权限为600,mysql用户将无法读取,导致服务启动时SSL加载失败。正确的做法是将证书目录的所有者设置为mysql,或者至少保证mysql用户对证书文件有读取权限。对于私钥文件,可以设置为mysql用户可读、其他用户无权限。
另一个高频错误是证书与私钥不匹配。如果服务器证书是由一个CA签署的,但配置中指定了错误的CA证书,或者服务器私钥与证书公钥不对应,客户端握手时会报出证书验证错误。可以通过openssl命令校验证书和私钥是否匹配,例如计算两者的模数是否一致。
openssl x509 -noout -modulus -in server-cert.pem | openssl md5 openssl rsa -noout -modulus -in server-key.pem | openssl md5
如果客户端启用了VERIFY_IDENTITY模式,还必须确保证书中的Common Name或Subject Alternative Name与连接使用的主机名完全一致。例如使用IP地址连接时,证书的CN必须是该IP地址,否则会被视为身份验证失败。在企业环境中,建议使用SAN扩展字段同时包含主机名和IP地址,以兼容不同的连接方式。
双向认证配置虽然更安全,但复杂度也更高。需要在服务端配置ssl-ca、ssl-cert、ssl-key的基础上,额外为每个客户端签发证书,并让客户端在连接时提供自己的客户端证书和私钥。服务端可以通过参数要求客户端必须提供有效证书,否则拒绝连接。双向认证适用于对安全要求极高的金融、政务等场景,普通业务使用单向SSL并强制客户端验证CA即可满足大多数安全需求。
MySQL SSL配置安全连接加密传输修改时间:2026-08-25 08:09:41