MySQL 支持多种 TLS 协议和密码,并允许配置允许用于加密连接的协议和密码。也可以确定当前会话使用哪个协议和密码。
MySQL 8.4 支持 TLSv1.2 和 TLSv1.3 协议用于连接。要使用 TLSv1.3,MySQL 服务器和客户端应用程序都必须使用 OpenSSL 1.1.1 或更高版本编译。组复制组件从 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 协议。这对于仅支持较低协议版本的旧版 MySQL 来说可能不可行。例如,在 MySQL 5.6.46 之前,TLSv1 是唯一支持的协议,因此即使客户端来自支持更高协议版本的较新 MySQL 版本,尝试连接到 5.6.46 之前的服务器也会失败。在这种情况下,可能需要升级到支持更多 TLS 版本的 MySQL 版本。
- 系统范围内的主机配置
-
假设 MySQL 配置允许 TLSv1、TLSv1.1 和 TLSv1.2,但您的主机系统配置仅允许使用 TLSv1.2 或更高版本的连接。在这种情况下,您无法建立使用 TLSv1 或 TLSv1.1 的 MySQL 连接,即使 MySQL 配置为允许它们,因为主机系统不允许它们。
如果 MySQL 配置允许 TLSv1、TLSv1.1 和 TLSv1.2,但您的主机系统配置仅允许使用 TLSv1.3 或更高版本的连接,您将无法建立任何 MySQL 连接,因为 MySQL 允许的任何协议都不被主机系统允许。
对 TLSv1 和 TLSv1.1 连接协议的支持已在 MySQL 8.0 中弃用并删除。有关背景信息,请参阅 IETF 备忘录 弃用 TLSv1.0 和 TLSv1.1。建议使用更安全的 TLSv1.2 和 TLSv1.3 协议进行连接。TLSv1.3 需要 MySQL 服务器和客户端应用程序都使用 OpenSSL 1.1.1 编译。
由于协议版本过旧,分别发布于 1996 年和 2006 年,因此已移除对 TLSv1 和 TLSv1.1 的支持。所使用的算法薄弱且过时。除非您正在使用非常旧版本的 MySQL Server 或连接器,否则您不太可能使用 TLSv1.0 或 TLSv1.1 进行连接。MySQL 连接器和客户端默认情况下会选择可用的最高 TLS 版本。
在不支持 TLSv1 和 TLSv1.1 连接协议的版本中,支持 --tls-version
选项以指定与 MySQL 服务器连接的 TLS 协议的客户端(包括 MySQL Shell)无法与协议设置为 TLSv1 或 TLSv1.1 建立 TLS/SSL 连接。如果客户端尝试使用这些协议进行连接,则对于 TCP 连接,连接将失败,并将错误返回给客户端。对于套接字连接,如果 --ssl-mode
设置为 REQUIRED
,则连接将失败,否则连接将建立,但 TLS/SSL 将被禁用。
有关更多信息,请参见 MySQL 8.4 是否支持 TLS 1.0 和 1.1?
在服务器端,tls_version
系统变量的值决定了 MySQL 服务器允许用于加密连接的 TLS 协议。 tls_version
值适用于来自客户端的连接、此服务器实例为源的常规源/副本复制连接、组复制组通信连接以及此服务器实例为捐赠者的组复制分布式恢复连接。管理连接接口的配置方式类似,但使用 admin_tls_version
系统变量(请参见 第 7.1.12.2 节,“管理连接管理”)。此讨论也适用于 admin_tls_version
。
tls_version
值是一个或多个用逗号分隔的 TLS 协议版本的列表,不区分大小写。默认情况下,此变量列出了用于编译 MySQL 和 MySQL Server 版本的 SSL 库支持的所有协议。因此,默认设置如 表 8.13,“MySQL Server TLS 协议默认设置” 所示。
表 8.13 MySQL Server TLS 协议默认设置
MySQL Server 版本 | tls_version 默认设置 |
---|---|
MySQL 8.0.15 及更低版本 |
|
MySQL 8.0.16 和 MySQL 8.0.17 |
组复制不支持 TLSv1.3 |
MySQL 8.0.18 到 MySQL 8.0.25 |
组复制支持 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 协议。选项值的格式与前面描述的 tls_version
系统变量相同(一个或多个用逗号分隔的协议版本的列表)。
对于此服务器实例为副本的源/副本复制连接,CHANGE REPLICATION SOURCE TO
语句的 SOURCE_TLS_VERSION
选项指定副本允许用于与源连接的 TLS 协议。选项值的格式与前面描述的 tls_version
系统变量相同。请参见 第 19.3.1 节,“设置复制以使用加密连接”。
可以为 SOURCE_TLS_VERSION
指定的协议取决于 SSL 库。此选项独立于服务器 tls_version
值,不受其影响。例如,充当副本的服务器可以配置为将 tls_version
设置为 TLSv1.3,以只允许使用 TLSv1.3 的传入连接,但也可以配置为将 SOURCE_TLS_VERSION
设置为 TLSv1.2,以只允许 TLSv1.2 用于传出的副本与源的连接。
对于此服务器实例为启动分布式恢复的加入成员(即,客户端)的组复制分布式恢复连接,group_replication_recovery_tls_version
系统变量指定客户端允许哪些协议。同样,此选项独立于服务器 tls_version
值,不受其影响,该值适用于此服务器实例为捐赠者时。组复制服务器通常在整个组成员资格期间既作为捐赠者也作为加入成员参与分布式恢复,因此应设置这两个系统变量。请参见 第 20.6.2 节,“使用安全套接字层 (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)
关于漏洞的禁止也适用于其他配置环境,例如,客户端或副本。
除非您打算禁用加密连接,否则允许的协议列表不应为空。如果将 TLS 版本参数设置为空字符串,则无法建立加密连接
tls_version
:服务器不允许加密的传入连接。--tls-version
:客户端不允许与服务器建立加密的传出连接。SOURCE_TLS_VERSION
:副本不允许与源建立加密的传出连接。group_replication_recovery_tls_version
:加入成员不允许与分布式恢复连接建立加密连接。
默认密码集适用于加密连接,可以通过显式配置允许的密码来覆盖它。在建立连接期间,连接的双方必须允许一些通用的密码,否则连接将失败。在双方通用的允许的密码中,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
的 TLS_AES_128_CCM_8_SHA256
会生成弃用警告。
要显式配置允许的 TLSv1.3 密码套件,请设置以下参数。在每种情况下,配置值都是零个或多个用冒号分隔的密码套件名称的列表。
在服务器端,使用
tls_ciphersuites
系统变量。如果未设置此变量,则其默认值为NULL
,这意味着服务器允许默认密码套件集。如果将变量设置为空字符串,则不会启用任何密码套件,并且无法建立加密连接。在客户端,使用
--tls-ciphersuites
选项。如果未设置此选项,则客户端允许默认密码套件集。如果将选项设置为空字符串,则不会启用任何密码套件,并且无法建立加密连接。对于常规的源/副本复制连接,如果此服务器实例为源,请使用
tls_ciphersuites
系统变量。如果此服务器实例为副本,请使用CHANGE REPLICATION SOURCE TO
语句的SOURCE_TLS_CIPHERSUITES
选项。请参见 第 19.3.1 节,“设置复制以使用加密连接”。对于组复制组成员,对于组复制组通信连接以及此服务器实例作为捐赠者的组复制分布式恢复连接,请使用
tls_ciphersuites
系统变量。对于此服务器实例作为加入成员的组复制分布式恢复连接,请使用group_replication_recovery_tls_ciphersuites
系统变量。请参阅 第 20.6.2 节,“使用安全套接字层 (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 服务器的 SSL 证书自动生成过程不会生成 ECDSA 签名证书,它仅生成 RSA 签名证书。除非您拥有 ECDSA 证书,否则不要选择 ECDSA 密码。
对于使用 TLS.v1.3 的加密连接,MySQL 使用 SSL 库默认密码套件列表。
对于使用 TLSv1.2 及之前版本的 TLS 协议的加密连接,MySQL 在与服务器系统变量 --ssl-cipher
和 --admin-ssl-cipher
一起使用时,会将以下默认密码列表传递给 SSL 库。
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 可用,则会尽可能使用它。(这意味着服务器和客户端配置都必须允许 TLSv1.3,并且两者还必须允许某些与 TLSv1.3 兼容的加密密码。)否则,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
为了获得更好的安全性,请使用具有至少 2048 位 RSA 密钥的证书。
如果服务器和客户端没有共同的允许协议,以及没有共同的与协议兼容的密码,则服务器将终止连接请求。示例
如果服务器配置为
tls_version=TLSv1.1,TLSv1.2
对于使用
--tls-version=TLSv1
调用的客户端以及仅支持 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 库,最终由该库决定从提供的列表中实际启用哪些协议。有关 SSL 库如何处理此问题的信息,请参阅 MySQL 源代码和 OpenSSL SSL_CTX_new()
文档。
要确定当前客户端会话使用哪种加密 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 |
+---------------+---------------------------+
如果连接未加密,则两个变量都为空值。