支持的连接TLS协议
MySQL支持使用TLSv1,TLSv1.1,TLSv1.2和TLSv1.3协议的加密连接,这些协议按从低到高的顺序列出。实际允许连接的协议集受多种因素影响:

MySQL配置。可以在服务器端和客户端上都配置允许的TLS协议,以仅包括支持的TLS协议的子集。双方的配置必须至少包含一个共同的协议,否则连接尝试无法协商要使用的协议。有关详细信息,请参见 连接TLS协议协商。

系统范围的主机配置。主机系统可能只允许某些TLS协议,这意味着即使MySQL本身允许它们,MySQL连接也不能使用不允许的协议:

假设MySQL配置允许TLSv1,TLSv1.1和TLSv1.2,但是您的主机系统配置仅允许使用TLSv1.2或更高版本的连接。在这种情况下,即使将MySQL配置为允许使用TLSv1或TLSv1.1的MySQL连接,也无法建立,因为主机系统不允许它们。

如果MySQL配置允许TLSv1,TLSv1.1和TLSv1.2,但是您的主机系统配置仅允许使用TLSv1.3或更高版本的连接,则您将无法建立MySQL连接,因为主机不允许MySQL允许的协议系统。

此问题的解决方法包括:

更改系统范围的主机配置,以允许其他TLS协议。请查阅操作系统文档以获取指示。例如,您的系统可能具有一个/etc/ssl/openssl.cnf包含以下行的文件,以将TLS协议限制为TLSv1.2或更高版本:

[system_default_sect]
MinProtocol = TLSv1.2
将值更改为较低的协议版本或 None使系统更宽松。这种解决方法的缺点是,允许较低(较不安全)的协议可能会带来不利的安全后果。

如果您不能或不想更改主机系统TLS配置,请更改MySQL应用程序以使用主机系统允许的更高(更安全)的TLS协议。对于仅支持较低协议版本的MySQL的较早版本可能无法实现。例如,TL​​Sv1是MySQL 5.6.46之前唯一受支持的协议,因此,即使客户端来自支持更高协议版本的较新MySQL版本,尝试连接到5.6.46之前的服务器的尝试也会失败。在这种情况下,可能需要升级到支持其他TLS版本的MySQL版本。

SSL库。如果SSL库不支持特定协议,则MySQL以及下面讨论中指定该协议的任何部分均不适用。

注意
TLSv1.3协议的支持自MySQL 8.0.16起(对于组复制组件自MySQL 8.0.18起)。此外,要使用TLSv1.3,必须使用OpenSSL 1.1.1或更高版本来编译MySQL服务器和客户端应用程序。

连接TLS协议配置
在服务器端,tls_version系统变量的值 确定MySQL服务器允许进行加密连接的TLS协议。的 tls_version该值适用于来自客户端的连接,以该服务器实例为主的常规主/从复制连接,组复制组通信连接以及以该服务器实例为施主的组复制分布式恢复连接。变量值是该列表中一个或多个逗号分隔协议版本的列表(不区分大小写):TLSv1,TLSv1.1,TLSv1.2和(如果可用)TLSV1.3。默认情况下,此变量列出用于编译MySQL的SSL库支持的所有协议。要确定tls_version运行时的值,请使用以下语句:

mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| tls_version | TLSv1,TLSv1.1,TLSv1.2 |
+---------------+-----------------------+
要更改的值 tls_version,请在服务器启动时进行设置。例如,要允许使用TLSv1.1或TLSv1.2协议的连接但禁止使用安全性较低的TLSv1协议的连接,请在服务器my.cnf文件中使用以下几行 :

[mysqld]
tls_version=TLSv1.1,TLSv1.2
为了更加严格并且仅允许TLSv1.2连接,请设置tls_version如下:

[mysqld]
tls_version=TLSv1.2
从MySQL 8.0.16开始,tls_version也可以在运行时进行更改。请参阅 加密连接的服务器端运行时配置。

在客户端,该 --tls-version选项指定客户端程序允许与服务器连接的TLS协议。选项值的格式与tls_version前面描述的系统变量的格式相同(一个或多个逗号分隔的协议版本的列表)。

对于以该服务器实例为从属服务器的主/从复制连接,该 语句的MASTER_TLS_VERSION 选项CHANGE MASTER TO指定复制从属服务器允许与主服务器连接的TLS协议。选项值的格式与tls_version前面描述的系统变量相同 。请参见 第17.3.1节“设置复制以使用加密的连接”。

可以指定的协议 MASTER_TLS_VERSION取决于SSL库。此选项独立于服务器tls_version值,不受服务器值的影响 。例如,可以将充当复制从属的服务器配置为 tls_version设置为TLSv1.3,以仅允许使用TLSv1.3的传入连接,也可以MASTER_TLS_VERSION将其配置为设置为TLSv1.2,以仅允许TLSv1.2进行出站从属连接给主人。

对于此服务器实例是启动分布式恢复的加入成员的组复制分布式恢复连接(即客户端), group_replication_recovery_tls_version 系统变量指定客户端允许哪些协议。此选项与服务器tls_version值无关,不受服务器值的影响,该值在此服务器实例是施主时适用。组复制服务器通常在其组成员身份过程中既作为捐赠者也作为加入成员参与分布式恢复,因此应同时设置这两个系统变量。请参见 第18.5.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:客户端不允许加密的传出连接到服务器。

MASTER_TLS_VERSION注意:复制从属服务器不允许与主服务器进行加密的传出连接。

连接密码配置
一组默认密码适用于加密连接,可以通过显式配置允许的密码来覆盖这些密码。在建立连接的过程中,连接的两端必须允许使用某些共同的密码,否则连接将失败。在双方通用的允许密码中,SSL库选择所提供证书支持的具有最高优先级的密码。

要指定适用于使用TLSv1.2之前使用TLS协议的加密连接的一个或多个密码,请执行以下操作:

该--ssl-cipher选项可用于服务器和客户端程序。

对于以该服务器实例为主服务器的常规主/从复制连接,请使用该 --ssl-cipher选项。如果此服务器实例是从属服务器MASTER_SSL_CIPHER,请为该CHANGE MASTER TO语句使用 选项 。请参见 第17.3.1节“设置复制以使用加密的连接”。

对于组复制组成员,对于组复制组通信连接以及该服务器实例是施主的组复制分布式恢复连接,请使用该 --ssl-cipher选项。对于此服务器实例是加入成员的组复制分布式恢复连接,请使用 group_replication_recovery_ssl_cipher 系统变量。请参见 第18.5.2节“组复制安全套接字层(SSL)支持”。

对于使用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
要明确配置允许的TLSv1.3密码套件,请设置以下参数。在每种情况下,配置值都是零个或多个冒号分隔的密码套件名称的列表。

在服务器端,使用 tls_ciphersuites系统变量。如果未设置此变量,则其默认值为 NULL,这意味着服务器允许使用默认的密码套件集。如果将变量设置为空字符串,则不会启用任何密码套件,并且无法建立加密连接。

在客户端,使用 --tls-ciphersuites选项。如果未设置此选项,则客户端允许使用默认的密码套件集。如果该选项设置为空字符串,则不会启用任何密码套件,并且无法建立加密连接。

对于以该服务器实例为主服务器的常规主/从复制连接,请使用 tls_ciphersuites系统变量。如果此服务器实例是从属服务器MASTER_TLS_CIPHERSUITES,请为该CHANGE MASTER TO语句使用 选项 。请参见 第17.3.1节“设置复制以使用加密的连接”。

对于组复制组成员,组复制组通信连接以及该服务器实例是施主的组复制分布式恢复连接,请使用 tls_ciphersuites系统变量。对于此服务器实例是加入成员的组复制分布式恢复连接,请使用 group_replication_recovery_tls_ciphersuites 系统变量。请参见 第18.5.2节“组复制安全套接字层(SSL)支持”。

注意
自从MySQL 8.0.16起,就可以使用密码套件支持,但是需要使用OpenSSL 1.1.1或更高版本来编译MySQL服务器和客户端应用程序。

在MySQL 8.0.16到8.0.18中,该语句的 MASTER_TLS_CIPHERSUITES选项 CHANGE MASTER TO和 group_replication_recovery_tls_ciphersuites 系统变量不可用。在这些版本中,如果将TLSv1.3用于主/从复制连接,或者在组复制中用于分布式恢复(受MySQL 8.0.18支持),则复制主服务器或组复制施主服务器必须允许至少使用一个TLSv1 .3默认情况下启用的密码套件。从MySQL 8.0.19开始,您可以使用这些选项来配置对任何密码套件选择的客户端支持,如果需要的话,仅包括非默认密码套件。

给定的密​​码只能与特定的TLS协议一起使用,这会影响TLS协议的协商过程。请参阅 连接TLS协议协商。

要确定给定服务器支持的密码,请检查Ssl_cipher_list状态变量的会话值 :

SHOW SESSION STATUS LIKE 'Ssl_cipher_list';
的Ssl_cipher_list状态变量列出了可能的SSL密码(空非SSL连接)。如果MySQL支持TLSv1.3,则该值包括可能的TLSv1.3密码套件。

对于使用TLS.v1.3的加密连接,MySQL使用SSL库默认密码套件列表。

对于直到TLSv1.2一直使用TLS协议的加密连接,MySQL会将以下默认密码列表传递给SSL库。

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

如果--ssl-cert使用指定使用前面任何受限密码或密码类别的证书的 选项启动服务器,则服务器将在禁用加密连接的情况下启动。

连接TLS协议协商
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显式指定密码名称:

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客户端以及仅支持TLSv1的旧客户端,连接尝试将失败 。

同样,对于配置了的复制从属服务器MASTER_TLS_VERSION = 'TLSv1'以及仅支持TLSv1的较旧的从属服务器,连接尝试将失败。

如果服务器配置为 tls_version=TLSv1或为仅支持TLSv1的较旧服务器:

对于使用调用的客户端,连接尝试失败 --tls-version=TLSv1.1,TLSv1.2。

同样,对于配置了的复制从属,连接尝试也会失败MASTER_TLS_VERSION = 'TLSv1.1,TLSv1.2'。

MySQL允许指定要支持的协议列表。此列表直接向下传递到基础SSL库,最终由该库决定,它实际上从提供的列表中启用了哪些协议。请参阅MySQL源代码和OpenSSL SSL_CTX_new() 文档,以获取有关SSL库如何处理此信息的信息。

监视当前会话TLS协议和密码
要确定当前会话使用哪种加密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                   |
+---------------+---------------------------+

如果连接未加密,则两个变量的值为空。