8.3.2 加密连接 TLS 协议和密码
MySQL 支持多种 TLS 协议和加密算法,并且可以配置哪些协议和加密算法用于加密连接。还可以确定当前会话使用的协议和加密算法。
MySQL 8.4 支持 TLSv1.2 和 TLSv1.3 协议的连接。要使用 TLSv1.3,MySQL 服务器和客户端应用程序都必须使用 OpenSSL 1.1.1 或更高版本编译。Group Replication 组件从 MySQL 8.0.18 开始支持 TLSv1.3(详见第20.6.2节,“使用安全套接字层(SSL)保护组通信”)。
MySQL 8.4 不支持老的 TLSv1 和 TLSv1.1 协议。
允许的 TLS 协议可以在服务器端和客户端配置,包括支持的 TLS 协议子集。两侧配置必须至少包含一个共同的协议或连接尝试不能协商使用协议。详见连接 TLS 协议协商。
主机系统可能只允许某些 TLS 协议,这意味着 MySQL 连接不能使用主机不允许的协议,即使 MySQL 本身允许它们。解决这个问题的一种方法包括以下:
-
更改系统全局主机配置以允许额外的 TLS 协议。请参阅操作系统文档,例如您的系统可能有一个
/etc/ssl/openssl.cnf
文件,其中包含将 TLS 协议限制到 TLSv1.3 或更高版本的行:[system_default_sect] MinProtocol = TLSv1.3
将值设置为较低协议版本或
None
使系统更加宽松。这一解决方案的缺点是允许较低(不安全)协议可能会导致安全后果。 -
如果您不能或不想更改主机系统的TLS配置,改变MySQL应用程序使用更高(更加安全)的TLS协议,这可能对older版本的MySQL无效,因为它们只支持低版本的协议。例如,TLSv1是MySQL 5.6.46之前唯一支持的协议,因此,即使客户端来自新版本的MySQL,但也无法连接到pre-5.6.46服务器。在这种情况下,升级到支持更多TLS版本的MySQL版本可能是必要的。
- System-wide host configuration
-
-
假设MySQL配置允许使用TLSv1、TLSv1.1和TLSv1.2,但是主机系统配置只允许使用TLSv1.2或更高版本。在这种情况下,即使MySQL配置允许它们,但也无法建立使用TLSv1或TLSv1.1的连接,因为主机系统不允许它们。
-
如果MySQL配置允许使用TLSv1、TLSv1.1和TLSv1.2,但是主机系统配置只允许使用TLSv1.3或更高版本,那么您无法建立任何MySQL连接,因为MySQL允许的协议都被主机系统拒绝。
-
TLSv1和TLSv1.1连接协议的支持在MySQL 8.0中被弃用了,背景信息请参阅弃用TLSv1.0和TLSv1.1。建议使用更加安全的TLSv1.2和TLSv1.3协议,TLSv1.3要求MySQL服务器和客户端应用程序都编译了OpenSSL 1.1.1。
由于TLSv1和TLSv1.1协议版本太老,于1996年和2006年发布,算法弱且过时。除非您使用非常老的MySQL Server或连接器,您不太可能使用TLSv1.0或TLSv1.1建立连接。MySQL连接器和客户端默认选择最高可用的TLS版本。
在不支持TLSv1和TLSv1.1连接协议的版本中,支持--tls-version
选项的客户端,包括MySQL Shell,无法使用TLS/SSL连接,设置为TLSv1或TLSv1.1时。对于TCP连接,如果--ssl-mode
设置为REQUIRED
,连接失败;否则连接建立,但TLS/SSL禁用。
更多信息,请参见MySQL 8.4是否支持TLS 1.0和1.1?
在服务器端,tls_version
系统变量的值确定了 MySQL 服务器允许的加密连接协议。该tls_version
值适用于来自客户端、普通源/副本复制连接、Group Replication 组通信连接和 Group Replication 分布式恢复连接,且该服务器实例为源的连接。管理连接接口配置类似,但使用admin_tls_version
系统变量(见第 7.1.12.2 节,“管理连接管理”)。本讨论也适用于admin_tls_version
。
该tls_version
值是由逗号分隔的 TLS 协议版本列表,不区分大小写。默认情况下,这个变量列出了 SSL 库编译 MySQL 和 MySQL 服务器版本支持的所有协议。默认设置如表 8.13,“MySQL 服务器 TLS 协议默认设置”所示。
表 8.13 MySQL 服务器 TLS 协议默认设置
MySQL Server Release | tls_version Default Setting |
---|---|
MySQL 8.0.15 及以下版本 |
|
MySQL 8.0.16 和 MySQL 8.0.17 |
Group Replication 不支持 TLSv1.3 |
MySQL 8.0.18 到 MySQL 8.0.25 |
Group Replication 支持 TLSv1.3 |
MySQL 8.0.26 和 MySQL 8.0.27 |
TLSv1 和 TLSv1.1 已弃用 |
MySQL 8.0.28 及以上 |
|
要确定tls_version
的运行时值,使用以下语句:
mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| tls_version | TLSv1.2,TLSv1.3 |
+---------------+-----------------------+
要更改tls_version
的值,在服务器启动时设置。例如,为了允许使用TLSv1.2或TLSv1.3协议的连接,但禁止使用不安全的TLSv1和TLSv1.1协议的连接,可以在服务器my.cnf
文件中添加以下行:
[mysqld]
tls_version=TLSv1.2,TLSv1.3
为了更进一步限制,仅允许TLSv1.3连接,设置tls_version
如下:
[mysqld]
tls_version=TLSv1.3
tls_version
可以在运行时更改。见服务器端实时配置和监控加密连接。
在客户端,--tls-version
选项指定了客户程序允许的服务器连接协议。该选项值的格式与前面描述的tls_version
系统变量相同(一个或多个逗号分隔的协议版本列表)。
对于源/副本复制连接,其中这个服务器实例是副本,SOURCE_TLS_VERSION
选项在CHANGE REPLICATION SOURCE TO
语句中指定副本允许的TLS协议连接到源服务器。该选项值的格式与tls_version
系统变量之前描述的一致。见第19.3.1节,“使用加密连接设置复制”。
可以指定的TLS协议取决于SSL库。这选项独立于服务器tls_version
值。例如,一个作为副本的服务器可以配置tls_version
设置为TLSv1.3,以便只允许使用TLSv1.3的 incoming 连接,同时也可以配置SOURCE_TLS_VERSION
设置为TLSv1.2,以便只允许 TLSv1.2 的出站副本连接到源服务器。
在 Group Replication 分布式恢复连接中,作为客户端的服务器实例(即加入成员)时,group_replication_recovery_tls_version
系统变量指定了客户端允许的协议。再次强调,这个选项独立于服务器tls_version
值,该值在这个服务器实例作为捐赠者时生效。一个 Group Replication 服务器通常在其组成员身份中既是捐赠者又是加入成员,因此这两个系统变量都应该被设置。见第20.6.2节,“使用 Secure Socket Layer (SSL) 安全地组通信连接”。
TLS 协议配置影响了给定的连接使用的协议,见连接 TLS 协议协商。
允许的协议应该选择不留下“空隙”。例如,这些服务器配置值没有空隙:
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)
禁止空隙的限制也适用于其他配置上下文,例如客户端或副本。
除非你想禁用加密连接,permit 的协议列表不能为空。如果你将 TLS 版本参数设置为空字符串,则无法建立加密连接:
-
tls_version
:服务器不允许加密的 incoming 连接。 -
--tls-version
:客户端不允许加密的 outgoing 连接到服务器。 -
SOURCE_TLS_VERSION
:副本不允许加密的 outgoing 连接到源服务器。 -
group_replication_recovery_tls_version
:加入成员不允许加密连接到分布式恢复连接。
对加密连接应用默认的加密套件,可以通过明确配置 permit 的加密套件来override。建立连接时,连接两端都必须允许某个共同的加密套件,否则连接失败。两端共有的加密套件中,SSL 库选择支持提供证书的最高优先级的加密套件。
指定使用 TLS 协议到 TLSv1.2 的加密连接的加密套件或加密套件:
-
在服务器端设置
ssl_cipher
系统变量,在客户端程序中使用--ssl-cipher
选项。 -
对于普通的源/副本复制连接,如果这个服务器实例是源,设置
ssl_cipher
系统变量。如果这个服务器实例是副本,使用CHANGE REPLICATION SOURCE TO
语句的SOURCE_SSL_CIPHER
选项。详见第19.3.1节,“使用加密连接设置复制”. -
对于群组复制成员,群组通信连接和分布式恢复连接,如果这个服务器实例是捐赠者,设置
ssl_cipher
系统变量。如果这个服务器实例是加入成员,使用group_replication_recovery_ssl_cipher
系统变量。详见第20.6.2节,“使用安全套接字层(SSL)加密群组通信连接”.
对于使用 TLSv1.3 加密连接的加密连接,OpenSSL 1.1.1 及更高版本支持以下加密套件,这些加密套件默认情况下通过服务器系统变量--tls-ciphersuites
或 --admin-tls-ciphersuites
启用:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_CCM_SHA256
在 MySQL 8.4 中,使用--tls-ciphersuites
或 --admin-tls-ciphersuites
生成弃用警告。
要明确配置 TLSv1.3 加密套件,设置以下参数。在每个情况下,配置值是零或多个以冒号分隔的加密套件名称。
-
在服务器端,使用
tls_ciphersuites
系统变量。如果这个变量没有设置,它的默认值是NULL
,这意味着服务器允许默认的加密套件。如果变量设置为空字符串,那么不启用任何加密套件,无法建立加密连接。 -
在客户端,使用
--tls-ciphersuites
选项。如果这个选项没有设置,客户端允许默认的加密套件。如果选项设置为空字符串,那么不启用任何加密套件,无法建立加密连接。 -
对于常规源/副本复制连接,where这个服务器实例是源服务器,可以使用
tls_ciphersuites
系统变量。where这个服务器实例是副本服务器,可以使用CHANGE REPLICATION SOURCE TO
语句中的SOURCE_TLS_CIPHERSUITES
选项。见第19.3.1节,“使用加密连接设置复制”. -
对于Group Replication组成员,用于Group Replication组通信连接和Group Replication分布式恢复连接,where这个服务器实例是捐赠服务器,可以使用
tls_ciphersuites
系统变量。用于Group Replication分布式恢复连接,where这个服务器实例是加入成员,可以使用group_replication_recovery_tls_ciphersuites
系统变量。见第20.6.2节,“使用Secure Socket Layer(SSL)安全组通信连接”.
加密套件支持要求MySQL服务器和客户端应用程序都编译使用OpenSSL 1.1.1或更高版本。
某个加密算法可能只与特定的TLS协议工作,这影响了TLS协议协商过程。见连接TLS协议协商。
要确定某个服务器支持的加密算法,检查会话值Ssl_cipher_list
状态变量:
SHOW SESSION STATUS LIKE 'Ssl_cipher_list';
Ssl_cipher_list
状态变量列出了可能的SSL加密算法(非SSL连接为空)。如果MySQL支持TLSv1.3,值包括可能的TLSv1.3加密套件。
ECDSA加密算法只能与使用ECDSA数字签名的SSL证书结合工作,不与使用RSA证书结合工作。MySQL Server的自动生成SSL证书过程不生成ECDSA签名证书,只生成RSA签名证书。除非您有可用的ECDSA证书,否则不要选择ECDSA加密算法。
用于TLS.v1.3加密连接时,MySQL使用SSL库默认加密套件列表。
用于TLS协议到TLSv1.2的加密连接时,MySQL将以下默认加密列表传递给SSL库,以便与服务器系统变量--ssl-cipher
和--admin-ssl-cipher
一起使用。
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305
ECDHE-ECDSA-AES256-CCM
ECDHE-ECDSA-AES128-CCM
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES256-CCM
DHE-RSA-AES128-CCM
DHE-RSA-CHACHA20-POLY1305
这些加密限制在这里:
-
以下加密算法已弃用,使用服务器系统变量
--ssl-cipher
和--admin-ssl-cipher
时产生警告:ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 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 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
如果服务器以使用任何前述受限加密算法或加密算法类别的证书启动ssl_cert
系统变量,服务器将以不支持加密连接方式启动。
MySQL 在双方都可用的最高TLS协议版本和加密算法中进行连接尝试。协商过程取决于编译服务器和客户端使用的SSL库、TLS协议和加密算法配置,以及使用的密钥大小:
-
为了成功建立连接,服务器和客户端的TLS协议配置必须允许某个协议。
-
类似地,服务器和客户端的加密算法配置也必须允许某个加密算法。给定的加密算法可能只与特定TLS协议兼容,所以协商过程不会选择不兼容的协议。
-
如果 TLSv1.3 可用,MySQL 就会使用。如果不可以,MySQL 将继续遍历可用的协议,使用 TLSv1.2,如果可能,然后是其他的。协议的选择顺序是从安全性高到低,不同的配置顺序不会影响选择结果。例如,无论
tls_version
的值是TLSv1,TLSv1.1,TLSv1.2,TLSv1.3
还是TLSv1.3,TLSv1.2,TLSv1.1,TLSv1
,协议选择顺序都是相同的。 -
TLSv1.2 不支持所有 512 位或更小的密钥大小的加密算法。要使用这个协议,可以在服务器端设置
ssl_cipher
系统变量,或者在客户端使用--ssl-cipher
客户端选项来指定加密算法名称:AES128-SHA AES128-SHA256 AES256-SHA AES256-SHA256 CAMELLIA128-SHA CAMELLIA256-SHA DES-CBC3-SHA DHE-RSA-AES256-SHA RC4-MD5 RC4-SHA SEED-SHA
-
为了更好的安全性,使用 RSA 密钥大小至少 2048 位的证书。
如果服务器和客户端都没有共同的协议和加密算法,服务器将终止连接请求。示例:
-
如果服务器配置了
tls_version=TLSv1.1,TLSv1.2
:-
使用
--tls-version=TLSv1
的客户端和老版本客户端都无法连接。 -
类似地,配置了
SOURCE_TLS_VERSION = 'TLSv1'
的副本或支持 TLSv1 的较旧副本的连接尝试都失败。
-
-
如果服务器配置了
tls_version=TLSv1
,或是较旧的服务器只支持 TLSv1:-
使用
--tls-version=TLSv1.1,TLSv1.2
命令行选项的客户端也会失败。 -
类似地,配置了
SOURCE_TLS_VERSION = 'TLSv1.1,TLSv1.2'
的副本也会失败。
-
MySQL 允许指定支持的协议列表。这一列表将直接传递给底层 SSL 库,并且最终由该库决定从提供的列表中实际启用的协议。请查看 MySQL 源代码和 OpenSSL SSL_CTX_new()
文档,以了解 SSL 库如何处理这个问题。
要确定当前客户端会话使用的加密 TLS 协议和加密算法,可以检查Ssl_version
和 Ssl_cipher
状态变量的值:
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 |
+---------------+---------------------------+
如果连接不加密,那么这两个变量都为空。