MySQL 支持使用 TLS (Transport Layer Security,传输层安全性) 协议在客户端和服务器之间进行加密连接。
TLS 有时被称为 SSL (Secure Sockets Layer,安全套接字层) ,但是 MySQL 实际上并不使用 SSL 协议进行加密连接,因为它的加密很弱。
MySQL 支持由 OpenSSL 提供的加密连接。
默认情况下,如果服务器支持加密连接,则 MySQL 程序会尝试使用加密连接,如果无法建立加密连接,则会退回到未加密连接。
MySQL 在每个连接的基础上执行加密,并且可以对指定用户强制使用加密连接。
概要
TLS 协议
- 使用加密算法来确保可以信任通过公共网络接收的数据
- 它具有检测数据更改、丢失或重放的机制
- 合并了使用 X.509 标准提供身份验证的算法
X.509 标准
- X.509 使得识别 Internet 上的某人成为可能
- 从根本上说,应该有一个称为证书颁发机构 (或 CA) 的实体,它将实体电子证书分配给需要它们的任何人。
- 证书依赖于具有两个加密密钥 (公钥和私钥) 的非对称加密算法。
- 证书所有者可以将证书出示给另一方作为身份证明。
- 证书由其所有者的公钥组成
- 使用此公钥加密的任何数据都只能使用相应私钥来解密
配置加密连接
服务器端启动配置
- 系统变量
- 启用 SSL
- ssl
- 控制服务器是否允许加密连接。默认已启用。
- require_secure_transport
- 要求客户端使用加密连接
- ssl
- 证书和密钥文件
- ssl_ca
- 证书颁发机构 (CA) 证书文件
- ssl_capath
- CA 证书文件目录
- ssl_cert
- 服务器公钥证书文件
- 可以将此证书发送到客户端,并根据其拥有的 CA 证书进行身份验证
- ssl_key
- 服务器私钥文件
- ssl_ca
- 服务器端加密连接控制
如果服务器无法通过系统变量为服务器端加密连接控制创建有效的 TLS 上下文,则服务器将不使用加密连接。
- ssl_crl
- 包含证书吊销列表的文件的路径名
- ssl_crlpath
- 指定证书吊销列表文件目录的路径名
- ssl_cipher
- 连接加密的允许密码列表
- tls_version, tls_ciphersuites
- 服务器允许哪种加密协议和密码套件进行加密连接
- ssl_crl
- 启用 SSL
- 服务器使用的证书和密钥文件
[mysqld] ssl_ca=ca.pem ssl_cert=server-cert.pem ssl_key=server-key.pem require_secure_transport=ON
- 文件格式
- .pem
- 自签名证书
- 由服务器自动创建的,或者是使用 mysql_ssl_rsa_setup 手动创建的证书。
- 换句话说,就是自己创建的证书,而不是权威机构颁发的证书。
- 服务器会自动发现证书和密钥文件
- 如果未显式指定证书和密钥文件 (除 ssl 和 ssl_cipher),则服务器将在启动时自动启用加密连接
- 发现过程
- 如果服务器在数据目录中发现名为 ca.pem,server-cert.pem 和 server-key.pem 的有效证书和密钥文件,则将启用加密连接
- 如果服务器在数据目录中找不到有效的证书和密钥文件,则不使用加密连接
- 错误日志中的记录
- 如果服务器自动启用加密连接支持,它将在错误日志中写入注释。
- 如果服务器发现 CA 证书是自签名的,它将在错误日志中写入警告
- 文件格式
服务器端动态配置和监控
- 系统变量
- ssl_ca
- ssl_capath
- ssl_cert
- ssl_cipher
- ssl_crl
- ssl_crlpath
- ssl_key
- tls_ciphersuites
- tls_version
- 状态变量
- Current_tls_xxx
- 与上面的系统变量相对应
- Current_tls_xxx
- 性能表
- performance_schema.tls_channel_status
mysql> select * from performance_schema.tls_channel_status limit 10; +------------+--------------------------+--------+ | CHANNEL | PROPERTY | VALUE | +------------+--------------------------+--------+ | mysql_main | Enabled | Yes | | mysql_main | Ssl_accept_renegotiates | 0 | | mysql_main | Ssl_accepts | 0 | | mysql_main | Ssl_callback_cache_hits | 0 | | mysql_main | Ssl_client_connects | 0 | | mysql_main | Ssl_connect_renegotiates | 0 | | mysql_main | Ssl_ctx_verify_depth | -1 | | mysql_main | Ssl_ctx_verify_mode | 5 | | mysql_main | Current_tls_ca | ca.pem | | mysql_main | Current_tls_capath | | +------------+--------------------------+--------+
- performance_schema.tls_channel_status
- 配置过程
- 设置 TLS 相关的系统变量
- 服务器为管理连接接口实现了独立的连接加密配置。
- 重新加载 TLS 系统变量和状态变量
mysql> ALTER INSTANCE RELOAD TLS
- 所需权限
- CONNECTION_ADMIN
- 由于重新配置过程的工作方式,每对系统变量和状态变量的成员可能暂时具有不同的值
在 ALTER INSTANCE RELOAD TLS 之前即使更改了 TLS 系统变量,也不会对新连接造成影响,此时就会导致相应的系统和状态变量具有不同的值。
在 ALTER INSTANCE RELOAD TLS 之后,相应的系统变量和状态变量具有相同的值。
-
在某些情况下,
ALTER INSTANCE RELOAD TLS
本身可能足以重新配置 TLS 上下文,而无需更改任何系统变量假设 ssl_cert 命名的文件中的证书已过期。用未过期的证书替换现有文件内容并执行 ALTER INSTANCE RELOAD TLS 足以读取新文件内容并将其用于新连接。
-
此外,
ALTER INSTANCE RELOAD TLS
扩展了 FOR CHANNEL 子句- 该子句允许指定要为其重新加载 TLS 上下文的通道 (接口)
- 查看
- performance_schema.tls_channel_status
- 默认情况下,如果配置值不允许创建新的 TLS 上下文,则 RELOAD TLS 操作会回滚并显示错误
如果给出了可选的 NO ROLLBACK ON ERROR 子句,并且无法创建新的上下文,则不会发生回滚。而是会生成一条警告,并对该语句所应用的接口上的新连接禁用加密。
- 所需权限
- 设置 TLS 相关的系统变量
客户端的配置
默认情况下,如果服务器支持加密连接,则 MySQL 客户端程序会尝试建立加密连接,并通过 –ssl-mode 选项提供进一步的控制。
- 系统变量
- require_secure_transport
- 服务器端配置,要求客户端必须使用加密连接
- require_secure_transport
- 客户端选项
- 启用 SSL
- –ssl-mode
- 控制客户端的加密连接
- 选项值
- PREFFERED
- (默认) 客户端尝试使用加密进行连接,如果无法建立加密连接,则会退回到未加密的连接
- 如果未指定 –ssl-mode 选项,也是如此
- REQUIRED
- 客户端需要加密的连接,如果无法建立则失败
- DISABLED
- 客户端使用未加密的连接
- VERIFY_CA
- 客户端需要加密的连接,并且对服务器 CA 证书进行验证
- VERIFY_IDENTITY
- 客户端需要加密的连接,并且对其证书中的服务器主机名进行验证
- PREFFERED
- –ssl-mode
- 客户端使用的证书和密钥文件
- –ssl-capath
- 指定 CA 证书文件目录的路径名
- –ssl-ca
- 证书颁发机构 (CA) 证书文件
- 如果使用此选项,则必须指定服务器使用的相同证书
- –ssl-cert
- 客户端公钥证书文件
- –ssl-key
- 客户端私钥文件
- –ssl-capath
- 客户端加密连接控制
- –ssl-crlpath
- 指定证书吊销列表文件目录的路径名
- –ssl-cipher
- 连接加密的允许密码列表
- –ssl-crl
- 包含证书吊销列表的文件的路径名
- –tls-version, –tls-ciphersuites
- 服务器允许哪种加密协议和密码套件进行加密连接
- –ssl-crlpath
- 启用 SSL
- 进一步提高安全性
为了获得更高的安全性,客户端可以指定 CA 证书,并启用主机名身份验证。
通过这种方式,服务器和客户端将他们的信任放在相同的 CA 证书中,并且客户端验证它所连接的主机是否是预期的主机。- 指定 CA 证书
- –ssl-ca, –ssl-capath
- –ssl-mode = VERIFY_CA
- 启用主机名身份验证
- –ssl-mode = VERIFY_IDENTITY
- 使用 VERIFY_IDENTITY 进行的主机名身份验证不适用于自签名证书。此类自签名证书不包含服务器名称作为通用名称值。
- 指定 CA 证书
- 配置示例
- 对于使用 REQUIRE SSL 子句创建的账户
mysql or mysql --ssl-mode=PREFERRED
- 对于使用 REQUIRE X509 子句创建的帐户
mysql --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem
- 客户端必须至少指定 –ssl-cert 和 –ssl-key
- 另外,建议使用 –ssl-ca 或 –ssl-capath ,以便可以验证服务器提供的公共证书
- 明确指定需要加密连接,避免回退到未加密连接
mysql --ssl-mode=REQUIRED
- 对于使用 REQUIRE ISSUER 或 REQUIRE SUBJECT 子句创建的帐户
- 加密要求与 REQUIRE X509 相同,但是证书必须分别与帐户定义中指定的问题或主题匹配。
- 禁用加密连接
mysql --ssl-mode=DISABLED
- 对于使用 REQUIRE SSL 子句创建的账户
- 查看与服务器的连接是否加密
- 状态变量
- Ssl_cipher
mysql> SHOW SESSION STATUS LIKE 'Ssl_cipher'; +---------------+---------------------------+ | Variable_name | Value | +---------------+---------------------------+ | Ssl_cipher | DHE-RSA-AES128-GCM-SHA256 | +---------------+---------------------------+
- Ssl_cipher
- 客户端命令
- STATUS, \s
mysql> \s ... SSL: Not in use or mysql> \s ... SSL: Cipher in use is DHE-RSA-AES128-GCM-SHA256
- STATUS, \s
- 状态变量
强制使用加密连接
分为以下控制级别:
- 要求客户端使用加密连接
- 系统变量
- require_secure_transport=ON
- 启用此变量后,要求与服务器的客户端连接使用安全传输
- 服务器拒绝不安全的连接尝试,该尝试失败并显示 ER_SECURE_TRANSPORT_REQUIRED 错误
- require_secure_transport=ON
- 系统变量
- 调用单个客户端程序以要求加密连接
- 选项
- –ssl-mode
- 使用选项值:REQUIRED,VERIFY_CA 或 VERIFY_IDENTITY
mysql --ssl-mode=REQUIRED mysqldump --ssl-mode=VERIFY_CA mysqladmin --ssl-mode=VERIFY_IDENTITY
- 使用选项值:REQUIRED,VERIFY_CA 或 VERIFY_IDENTITY
- –ssl-mode
- 选项
- 将单个 MySQL 帐户配置为仅在加密连接上可用
- 在创建帐户的 CREATE USER 语句中包括 REQUIRE 子句,并在该子句中指定所需的加密特征
CREATE USER 'jeffrey'@'localhost' REQUIRE X509;
- 如果将普通账户改为加密账户,使用 ALTER USER 语句
- 在创建帐户的 CREATE USER 语句中包括 REQUIRE 子句,并在该子句中指定所需的加密特征
加密连接 TLS 协议和密码
MySQL 支持使用 TLSv1,TLSv1.1,TLSv1.2 和 TLSv1.3 协议的加密连接,安全性依次增加。
影响因素
实际受支持的协议受多种因素影响。
- MySQL 配置
- 可以在服务器端和客户端上都配置允许的 TLS 协议。双方的配置必须至少包含一个共同的协议,否则连接尝试无法协商要使用的协议。
- 系统范围的主机配置
- 主机系统可能仅允许某些 TLS 协议,这意味着即使 MySQL 本身允许它们,连接也可能失败
假设 MySQL 配置允许 TLSv1,TLSv1.1 和 TLSv1.2,但是主机系统配置仅允许使用 TLSv1.2 或更高版本的连接。在这种情况下,即使将 MySQL 配置为允许使用 TLSv1 或 TLSv1.1 的 MySQL 连接,也无法建立。
如果 MySQL 配置允许 TLSv1,TLSv1.1 和 TLSv1.2,但是主机系统配置仅允许使用 TLSv1.3 或更高版本的连接,则无法建立 MySQL 连接。
-
解决方法
- 更改系统范围的主机配置,以允许其他 TLS 协议
shell> vim /etc/ssl/openssl.cnf [system_default_sect] MinProtocol = TLSv1.2
Note: 将值更改为较低的协议版本或 “” 会使系统更宽松。缺点就是不安全。
-
更改 MySQL 应用程序以使用主机系统允许的更高的 TLS 协议
- 更改系统范围的主机配置,以允许其他 TLS 协议
- 主机系统可能仅允许某些 TLS 协议,这意味着即使 MySQL 本身允许它们,连接也可能失败
-
SSL 库
- 如果 SSL 库不支持特定协议,则 MySQL 以及下面讨论中指定该协议的任何部分均不适用
- TLSv1.3 协议的支持
- MySQL 版本最低是 8.0.16
- OpenSSL 版本最低是 1.1.1
连接 TLS 协议配置
- 系统变量
- tls_version
- MySQL 服务器允许进行加密连接的 TLS 协议
-
协议列表
[mysqld] tls_version=TLSv1.1,TLSv1.2
TLSv1,TLSv1.1,TLSv1.2 和 TLSV1.3TLSv1,TLSv1.1 已弃用,将来会删除。建议使用 TLSv1.2 和 TLSv1.3。
-
不区分大小写
-
多个协议之间使用逗号分隔
-
避免在列表中留下漏洞,协议应该连续
# 正确示例 tls_version=TLSv1,TLSv1.1,TLSv1.2,TLSv1.3 tls_version=TLSv1.1,TLSv1.2,TLSv1.3 tls_version=TLSv1.2,TLSv1.3 tls_version=TLSv1.3 # 错误示例 tls_version=TLSv1,TLSv1.2 (TLSv1.1 is missing) tls_version=TLSv1.1,TLSv1.3 (TLSv1.2 is missing)
- 如果设置为 “”,则无法建立加密连接
-
默认情况下,此变量列出用于编译 MySQL 的 SSL 库支持的所有协议
-
对于复制
- CHANGE REPLICATION SOURCE TO
- 选项
- SOURCE_TLS_VERSION
- 选项
CHANGE MASTER TO选项MASTER_TLS_VERSION
- CHANGE REPLICATION SOURCE TO
- 对于组复制的分布式恢复连接
- group_replication_recovery_tls_version
- 指定客户端允许哪些协议
- group_replication_recovery_tls_version
- admin_tls_version
- 管理连接接口允许进行加密连接的 TLS 协议
- tls_version
连接密码配置
在建立连接的过程中,连接的两端必须允许使用某些共同的密码,否则连接将失败。
在双方通用的允许密码中,SSL 库选择所提供证书支持的具有最高优先级的密码。
- 系统变量
- ssl_cipher
- 允许的密码
- 对于复制
- CHANGE REPLICATION SOURCE TO
- 选项
- SOURCE_SSL_CIPHER
- 选项
CHANGE MASTER TO选项MASTER_SSL_CIPHER
- CHANGE REPLICATION SOURCE TO
- 对于组复制的分布式恢复连接
- group_replication_recovery_ssl_cipher
- tls_ciphersuites
- 允许的密码套件
-
默认值
- 对于使用 TLSv1.3 的加密连接,OpenSSL 1.1.1 和更高版本支持以下密码套件,默认情况下启用前三个密码套件
TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_CCM_SHA256 TLS_AES_128_CCM_8_SHA256
- 如果未设置此变量,则其默认值为 NULL,这意味着服务器允许使用默认的密码套件集
- 对于使用 TLSv1.3 的加密连接,OpenSSL 1.1.1 和更高版本支持以下密码套件,默认情况下启用前三个密码套件
-
对于复制
- CHANGE REPLICATION SOURCE TO
- 选项
- SOURCE_TLS_CIPHERSUITES
- 选项
CHANGE MASTER TO选项MASTER_TLS_CIPHERSUITES
- CHANGE REPLICATION SOURCE TO
- 对于组复制的分布式恢复连接
- group_replication_recovery_tls_ciphersuites
- ssl_cipher
- 查看服务器支持的密码
- 状态变量
- Ssl_cipher_list
SHOW SESSION STATUS LIKE 'Ssl_cipher_list';
- Ssl_cipher_list
- TLSv1.2 以前的 TLS 协议,默认密码列表
ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-DSS-AES128-SHA256 DHE-DSS-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-DSS-AES256-SHA256 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES128-SHA DHE-RSA-AES128-SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA DHE-RSA-AES256-SHA AES128-GCM-SHA256 DH-DSS-AES128-GCM-SHA256 ECDH-ECDSA-AES128-GCM-SHA256 AES256-GCM-SHA384 DH-DSS-AES256-GCM-SHA384 ECDH-ECDSA-AES256-GCM-SHA384 AES128-SHA256 DH-DSS-AES128-SHA256 ECDH-ECDSA-AES128-SHA256 AES256-SHA256 DH-DSS-AES256-SHA256 ECDH-ECDSA-AES256-SHA384 AES128-SHA DH-DSS-AES128-SHA ECDH-ECDSA-AES128-SHA AES256-SHA DH-DSS-AES256-SHA ECDH-ECDSA-AES256-SHA DHE-RSA-AES256-GCM-SHA384 DH-RSA-AES128-GCM-SHA256 ECDH-RSA-AES128-GCM-SHA256 DH-RSA-AES256-GCM-SHA384 ECDH-RSA-AES256-GCM-SHA384 DH-RSA-AES128-SHA256 ECDH-RSA-AES128-SHA256 DH-RSA-AES256-SHA256 ECDH-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES128-SHA DHE-RSA-AES128-SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA DHE-RSA-AES256-SHA AES128-SHA DH-DSS-AES128-SHA ECDH-ECDSA-AES128-SHA AES256-SHA DH-DSS-AES256-SHA ECDH-ECDSA-AES256-SHA DH-RSA-AES128-SHA ECDH-RSA-AES128-SHA DH-RSA-AES256-SHA ECDH-RSA-AES256-SHA DES-CBC3-SHA
- 这些密码受到适当限制
- 以下密码受到永久限制
!DHE-DSS-DES-CBC3-SHA !DHE-RSA-DES-CBC3-SHA !ECDH-RSA-DES-CBC3-SHA !ECDH-ECDSA-DES-CBC3-SHA !ECDHE-RSA-DES-CBC3-SHA !ECDHE-ECDSA-DES-CBC3-SHA
- 下列类别的密码受到永久限制
!aNULL !eNULL !EXPORT !LOW !MD5 !DES !RC2 !RC4 !PSK !SSLv3
- 以下密码受到永久限制
- 如果使用了受限制的密码启动服务器,则服务器将禁用对加密连接的支持
- 这些密码受到适当限制
- 状态变量
协商过程
MySQL 中的连接尝试协商使用双方都可以使用的最高 TLS 协议版本,并且双方都可以使用协议兼容的加密密码。
如果服务器和客户端没有共同的允许协议,并且没有共同的协议兼容密码,则服务器将终止连接请求。
协商过程取决于多种因素:
- 为了成功进行连接,服务器和客户端
- TLS 协议配置必须允许某些通用协议
- 加密密码配置必须允许一些共同的密码
- 如果 TLSv1.3 可用,会优先使用
这意味着服务器和客户端配置都必须允许 TLSv1.3,并且都必须允许某些与 TLSv1.3 兼容的加密密码。
否则,MySQL 会继续浏览可用协议列表,并在可能的情况下使用 TLSv1.2,依此类推。
- 协商顺序与配置协议的顺序无关
- TLSv1.2 不适用于密钥大小为512位或更小的所有密码
-
为了获得更好的安全性,请使用 RSA 密钥大小至少为2048位的证书
查看 TLS 协议和密码
-
状态变量
- Ssl_version
- Ssl_cipher
- 性能表
- performance_schema.session_status
mysql> SELECT * FROM performance_schema.session_status WHERE VARIABLE_NAME IN ('Ssl_version','Ssl_cipher'); +---------------+---------------------------+ | VARIABLE_NAME | VARIABLE_VALUE | +---------------+---------------------------+ | Ssl_cipher | DHE-RSA-AES128-GCM-SHA256 | | Ssl_version | TLSv1.2 | +---------------+---------------------------+
- performance_schema.session_status
创建 SSL 和 RSA 证书和密钥
SSL 证书和密钥文件使 MySQL 支持使用 SSL 的加密连接。
RSA 密钥文件使 MySQL 支持通过 sha256_password 或 caching_sha2_password 插件认证的帐户通过未加密的连接进行安全的密码交换。
使用 MySQL 创建
使用 MySQL 自身生成的文件降低了 SSL 的使用障碍,但是生成的证书是自签名的,不安全。
- 自动生成 SSL 和 RSA 文件
对于使用 OpenSSL 编译的 MySQL 发行版,MySQL 服务器具有在启动时自动生成丢失的 SSL 和 RSA 文件的功能。
- 系统变量
- auto_generate_certs
- 控制服务器启动时自动生成缺失的证书和文件
- sha256_password_auto_generate_rsa_keys
- 控制服务器启动时自动生成 RSA 密钥对
- caching_sha2_password_auto_generate_rsa_keys
- 控制服务器启动时自动生成 RSA 密钥对
- auto_generate_certs
- 自动生成 SSL 文件
- 服务器在数据目录中检查以下 SSL 文件
ca.pem server-cert.pem server-key.pem
- 如果存在这些文件中的任何一个,则服务器不会创建 SSL 文件。否则,它将创建它们以及一些其他文件
ca.pem Self-signed CA certificate ca-key.pem CA private key server-cert.pem Server certificate server-key.pem Server private key client-cert.pem Client certificate client-key.pem Client private key
- 如果存在这些文件中的任何一个,则服务器不会创建 SSL 文件。否则,它将创建它们以及一些其他文件
- 如果服务器自动生成 SSL 文件,它将使用 ca.pem,server-cert.pem 和 server-key.pem 文件的名称来设置相应的系统变量
- ssl_ca
- ssl_cert
- ssl_key
- 服务器在数据目录中检查以下 SSL 文件
- 自动生成 RSA 密钥对
- 前提
- 启用了系统变量
- sha256_password_auto_generate_rsa_keys
- caching_sha2_password_auto_generate_rsa_keys
- 未指定 RSA 选项
- 数据目录中缺少 RSA 文件
- 启用了系统变量
-
服务器在数据目录中检查以下 RSA 文件
private_key.pem Private member of private/public key pair public_key.pem Public member of private/public key pair
- 如果存在这些文件中的任何一个,则服务器不会创建 RSA 文件。否则,它将创建它们。
- 如果服务器自动生成 RSA 文件,它将使用其名称来设置相应的系统变量
- sha256_password_private_key_path, sha256_password_public_key_path
- caching_sha2_password_private_key_path, caching_sha2_password_public_key_path
- 前提
- 系统变量
- 使用 mysql_ssl_rsa_setup 手动生成 SSL 和 RSA 文件
MySQL 发行版包括 mysql_ssl_rsa_setup 实用程序,可以手动调用该实用程序以生成 SSL 和 RSA 文件。这要求 openssl 命令可用。
mysql_ssl_rsa_setup [options]
- SSL 和 RSA 文件特征
- SSL 和 RSA 密钥的大小为 2048 位
-
生成的 CA 证书是自签名的
- 使用 sha256WithRSAEncryption 签名算法,使用 CA 证书和密钥对 SSL 服务器和客户端证书进行签名。
- SSL 证书通用名称
- SSL 证书使用以下通用名称 (CN) 格式
ca.pem: MySQL_Server_suffix_Auto_Generated_CA_Certificate server-cert.pm: MySQL_Server_suffix_Auto_Generated_Server_Certificate client-cert.pm: MySQL_Server_suffix_Auto_Generated_Client_Certificate
- 名称后缀
[root@yingzai_23 data]$ openssl x509 -text -in ca.pem ... Issuer: CN = MySQL_Server_8.0.23_Auto_Generated_CA_Certificate
- 基于 MySQL 版本号
- mysql_ssl_rsa_setup 程序的选项
- –suffix
- 指定生成证书的后缀
- –suffix
- mysql_ssl_rsa_setup 程序的选项
- 对于服务器生成的文件,如果结果 CN 值超过64个字符,则名称的 _suffix 部分将被省略
- 基于 MySQL 版本号
- SSL 证书使用以下通用名称 (CN) 格式
-
SSL 证书内容
- SSL 文件的国家 (C) ,州或省 (ST) ,组织 (O) ,组织单位名称 (OU) 和电子邮件地址的值为空白。
-
每个证书/密钥对的 SSL 文件具有不同的序列号(serial number):ca 是1,server 是2,client 是3
[root@yingzai_23 data]$ openssl x509 -text -in ca.pem Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) # 序列号 Signature Algorithm: sha256WithRSAEncryption Issuer: CN = MySQL_Server_8.0.23_Auto_Generated_CA_Certificate Validity Not Before: Feb 26 14:37:41 2021 GMT Not After : Feb 24 14:37:41 2031 GMT Subject: CN = MySQL_Server_8.0.23_Auto_Generated_CA_Certificate Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:97:0a:40:fd:ef:23:93:a1:2b:0b:42:f7:89:4f: ... Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha256WithRSAEncryption
- 有效期
- 由服务器或 mysql_ssl_rsa_setup 创建的 SSL 文件从生成之日起有效期为十年
- RSA 文件不会过期
- 文件权限
- 服务器自动创建的文件归运行服务器的帐户所有
- 使用 mysql_ssl_rsa_setup 创建的文件归调用该程序的用户所有
- 在类 Unix 的系统上,证书文件的文件访问模式为 644,密钥文件的文件访问模式为 600。
- 查看 SSL 证书的内容
openssl x509 -text -in ca.pem openssl x509 -text -in server-cert.pem openssl x509 -text -in client-cert.pem
- 检查 SSL 证书到期信息
- 状态变量
mysql> show status like 'ssl_server_not%'; +-----------------------+--------------------------+ | Variable_name | Value | +-----------------------+--------------------------+ | Ssl_server_not_after | Feb 24 14:37:41 2031 GMT | | Ssl_server_not_before | Feb 26 14:37:41 2021 GMT | +-----------------------+--------------------------+
- Ssl_server_not_after
- 证书到期日期
- Ssl_server_not_before
- 证书创建日期
- Ssl_server_not_after
- 状态变量
- SSL 和 RSA 文件特征
使用 openssl 创建
- 创建 SSL 证书和密钥
- 无论使用哪种方法生成证书和密钥文件,用于服务器和客户端证书/密钥的通用名称都必须与用于 CA 证书的通用名称不同。
- 否则,证书和密钥文件不适用于使用 OpenSSL 编译的服务器,并报错
ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)
- 否则,证书和密钥文件不适用于使用 OpenSSL 编译的服务器,并报错
- 示例
- 在 Unix 上从命令行创建 SSL 文件
# Create clean environment rm -rf newcerts mkdir newcerts && cd newcerts # Create CA certificate openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 3600 \ -key ca-key.pem -out ca.pem # Create server certificate, remove passphrase, and sign it # server-cert.pem = public key, server-key.pem = private key openssl req -newkey rsa:2048 -days 3600 \ -nodes -keyout server-key.pem -out server-req.pem openssl rsa -in server-key.pem -out server-key.pem openssl x509 -req -in server-req.pem -days 3600 \ -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem # Create client certificate, remove passphrase, and sign it # client-cert.pem = public key, client-key.pem = private key openssl req -newkey rsa:2048 -days 3600 \ -nodes -keyout client-key.pem -out client-req.pem openssl rsa -in client-key.pem -out client-key.pem openssl x509 -req -in client-req.pem -days 3600 \ -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
- 在 Unix 上使用脚本创建 SSL 文件
DIR=`pwd`/openssl PRIV=DIR/private mkdirDIR PRIVDIR/newcerts cp /usr/share/ssl/openssl.cnf DIR replace ./demoCADIR -- DIR/openssl.cnf # Create necessary files:database, serial andnew_certs_dir # directory (optional) touch DIR/index.txt echo "01">DIR/serial # # Generation of Certificate Authority(CA) # openssl req -new -x509 -keyout PRIV/cakey.pem -outDIR/ca.pem \ -days 3600 -config DIR/openssl.cnf # Sample output: # Using configuration from /home/jones/openssl/openssl.cnf # Generating a 1024 bit RSA private key # ................++++++ # .........++++++ # writing new private key to '/home/jones/openssl/private/cakey.pem' # Enter PEM pass phrase: # Verifying password - Enter PEM pass phrase: # ----- # You are about to be asked to enter information to be # incorporated into your certificate request. # What you are about to enter is what is called a Distinguished Name # or a DN. # There are quite a few fields but you can leave some blank # For some fields there will be a default value, # If you enter '.', the field will be left blank. # ----- # Country Name (2 letter code) [AU]:FI # State or Province Name (full name) [Some-State]:. # Locality Name (eg, city) []: # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB # Organizational Unit Name (eg, section) []: # Common Name (eg, YOUR name) []:MySQL admin # Email Address []: # # Create server request and key # openssl req -new -keyoutDIR/server-key.pem -out \ DIR/server-req.pem -days 3600 -configDIR/openssl.cnf # Sample output: # Using configuration from /home/jones/openssl/openssl.cnf # Generating a 1024 bit RSA private key # ..++++++ # ..........++++++ # writing new private key to '/home/jones/openssl/server-key.pem' # Enter PEM pass phrase: # Verifying password - Enter PEM pass phrase: # ----- # You are about to be asked to enter information that will be # incorporated into your certificate request. # What you are about to enter is what is called a Distinguished Name # or a DN. # There are quite a few fields but you can leave some blank # For some fields there will be a default value, # If you enter '.', the field will be left blank. # ----- # Country Name (2 letter code) [AU]:FI # State or Province Name (full name) [Some-State]:. # Locality Name (eg, city) []: # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB # Organizational Unit Name (eg, section) []: # Common Name (eg, YOUR name) []:MySQL server # Email Address []: # # Please enter the following 'extra' attributes # to be sent with your certificate request # A challenge password []: # An optional company name []: # # Remove the passphrase from the key # openssl rsa -in DIR/server-key.pem -outDIR/server-key.pem # # Sign server cert # openssl ca -cert DIR/ca.pem -policy policy_anything \ -outDIR/server-cert.pem -config DIR/openssl.cnf \ -infilesDIR/server-req.pem # Sample output: # Using configuration from /home/jones/openssl/openssl.cnf # Enter PEM pass phrase: # Check that the request matches the signature # Signature ok # The Subjects Distinguished Name is as follows # countryName :PRINTABLE:'FI' # organizationName :PRINTABLE:'MySQL AB' # commonName :PRINTABLE:'MySQL admin' # Certificate is to be certified until Sep 13 14:22:46 2003 GMT # (365 days) # Sign the certificate? [y/n]:y # # # 1 out of 1 certificate requests certified, commit? [y/n]y # Write out database with 1 new entries # Data Base Updated # # Create client request and key # openssl req -new -keyout DIR/client-key.pem -out \DIR/client-req.pem -days 3600 -config DIR/openssl.cnf # Sample output: # Using configuration from /home/jones/openssl/openssl.cnf # Generating a 1024 bit RSA private key # .....................................++++++ # .............................................++++++ # writing new private key to '/home/jones/openssl/client-key.pem' # Enter PEM pass phrase: # Verifying password - Enter PEM pass phrase: # ----- # You are about to be asked to enter information that will be # incorporated into your certificate request. # What you are about to enter is what is called a Distinguished Name # or a DN. # There are quite a few fields but you can leave some blank # For some fields there will be a default value, # If you enter '.', the field will be left blank. # ----- # Country Name (2 letter code) [AU]:FI # State or Province Name (full name) [Some-State]:. # Locality Name (eg, city) []: # Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB # Organizational Unit Name (eg, section) []: # Common Name (eg, YOUR name) []:MySQL user # Email Address []: # # Please enter the following 'extra' attributes # to be sent with your certificate request # A challenge password []: # An optional company name []: # # Remove the passphrase from the key # openssl rsa -inDIR/client-key.pem -out DIR/client-key.pem # # Sign client cert # openssl ca -certDIR/ca.pem -policy policy_anything \ -out DIR/client-cert.pem -configDIR/openssl.cnf \ -infiles DIR/client-req.pem # Sample output: # Using configuration from /home/jones/openssl/openssl.cnf # Enter PEM pass phrase: # Check that the request matches the signature # Signature ok # The Subjects Distinguished Name is as follows # countryName :PRINTABLE:'FI' # organizationName :PRINTABLE:'MySQL AB' # commonName :PRINTABLE:'MySQL user' # Certificate is to be certified until Sep 13 16:45:17 2003 GMT # (365 days) # Sign the certificate? [y/n]:y # # # 1 out of 1 certificate requests certified, commit? [y/n]y # Write out database with 1 new entries # Data Base Updated # # Create a my.cnf file that you can use to test the certificates # cat<DIR/my.cnf [client] ssl-ca=DIR/ca.pem ssl-cert=DIR/client-cert.pem ssl-key=DIR/client-key.pem [mysqld] ssl_ca=DIR/ca.pem ssl_cert=DIR/server-cert.pem ssl_key=DIR/server-key.pem EOF
- 在 Windows 上创建 SSL 文件
- 略
- 在 Unix 上从命令行创建 SSL 文件
- 验证证书和密钥
shell> openssl verify -CAfile ca.pem server-cert.pem client-cert.pem server-cert.pem: OK client-cert.pem: OK
- 查看证书内容
openssl x509 -text -in ca.pem openssl x509 -text -in server-cert.pem openssl x509 -text -in client-cert.pem
- 无论使用哪种方法生成证书和密钥文件,用于服务器和客户端证书/密钥的通用名称都必须与用于 CA 证书的通用名称不同。
- 创建 RSA 密钥
- 创建 RSA 密钥对文件
openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -pubout -out public_key.pem
Note: 这些命令创建 2048 位密钥。
-
然后设置密钥文件的访问模式
chmod 400 private_key.pem chmod 444 public_key.pem
- 私钥只能由服务器读取,而公钥可以自由分发给客户端用户
- 创建 RSA 密钥对文件