MySQL 8.0 参考手册  / 第 6 章 安全  / 6.3 使用加密连接  /  6.3.2 加密连接 TLS 协议和密码

6.3.2 加密连接 TLS 协议和密码

MySQL 支持多种 TLS 协议和密码,并允许配置允许加密连接的协议和密码。还可以确定当前会话使用的协议和密码。

支持的连接 TLS 协议

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

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

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

    • 假设 MySQL 配置允许 TLSv1、TLSv1.1 和 TLSv1.2,但您的主机系统配置只允许使用 TLSv1.2 或更高版本的连接。在这种情况下,您无法建立使用 TLSv1 或 TLSv1.1 的 MySQL 连接,即使 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 也不支持,并且以下讨论中指定该协议的任何部分都不适用。

    • 当使用 OpenSSL 1.0.1 或更高版本编译时,MySQL 支持 TLSv1、TLSv1.1 和 TLSv1.2 协议。

    • 使用 yaSSL 编译时,MySQL 支持 TLSv1 和 TLSv1.1 协议。

    笔记

    仅在 MySQL 5.7.28 之前,可以使用 yaSSL 作为 OpenSSL 的替代方案来编译 MySQL。从 MySQL 5.7.28 开始,删除了对 yaSSL 的支持,所有 MySQL 构建都使用 OpenSSL。

连接 TLS 协议配置

在服务器端, tls_version系统变量的值决定了 MySQL 服务器允许哪些 TLS 协议进行加密连接。该 tls_version值适用于来自使用常规源/副本复制的客户端和副本服务器的连接。变量值是此列表中一个或多个以逗号分隔的协议版本的列表(不区分大小写):TLSv1、TLSv1.1、TLSv1.2。默认情况下,此变量列出了用于编译 MySQL 的 SSL 库支持的所有协议(TLSv1,TLSv1.1,TLSv1.2对于 OpenSSL,TLSv1,TLSv1.1对于 yaSSL)。要在运行时确定 的值 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如下(假设您的服务器是使用 OpenSSL 编译的,因为 yaSSL 不支持 TLSv1.2):

[mysqld]
tls_version=TLSv1.2
笔记

从 MySQL 5.7.35 开始,TLSv1 和 TLSv1.1 连接协议已弃用,并且在未来的 MySQL 版本中将删除对它们的支持。请参阅 弃用的 TLS 协议

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

对于源/副本复制, MASTER_TLS_VERSION该语句的选项 CHANGE MASTER TO指定副本服务器允许哪些 TLS 协议连接到源。tls_version 选项值的格式与前面描述的系统变量的格式相同。请参阅 第 16.3.8 节,“设置复制以使用加密连接”

可以指定的协议 MASTER_TLS_VERSION取决于 SSL 库。tls_version此选项独立于服务器值且不受其影响 。例如,作为副本的服务器可以配置 tls_version为 TLSv1.2 以仅允许使用 TLSv1.2 的传入连接,也可以配置MASTER_TLS_VERSION为 TLSv1.1 以仅允许 TLSv1.1 用于传出副本连接来源。

TLS 协议配置会影响给定连接使用的协议,如 连接 TLS 协议协商中所述。

应选择允许的协议,例如不要在列表中留下 漏洞。例如,这些服务器配置值没有漏洞:

tls_version=TLSv1,TLSv1.1,TLSv1.2
tls_version=TLSv1.1,TLSv1.2
tls_version=TLSv1.2

这个值确实有漏洞,不应该被使用:

tls_version=TLSv1,TLSv1.2       (TLSv1.1 is missing)

对空洞的禁止也适用于其他配置上下文,例如客户端或副本。

除非您打算禁用加密连接,否则允许的协议列表不应为空。如果将 TLS 版本参数设置为空字符串,则无法建立加密连接:

  • tls_version: 服务器不允许加密传入连接。

  • --tls-version:客户端不允许到服务器的加密传出连接。

  • MASTER_TLS_VERSION:副本不允许到源的加密传出连接。

弃用的 TLS 协议

从 MySQL 5.7.35 开始,TLSv1 和 TLSv1.1 连接协议已弃用,对它们的支持可能会在未来的 MySQL 版本中删除。(有关背景信息,请参阅 IETF 备忘录 弃用 TLSv1.0 和 TLSv1.1。)建议使用更安全的 TLSv1.2 和 TLSv1.3 协议建立连接。TLSv1.3 要求 MySQL 服务器和客户端应用程序都使用 OpenSSL 1.1.1 或更高版本进行编译。

在服务器端,此弃用具有以下影响:

  • 如果tls_version在服务器启动期间为系统变量分配了一个包含已弃用的 TLS 协议的值,则服务器会将每个已弃用协议的警告写入错误日志。

  • 如果客户端使用已弃用的 TLS 协议成功连接,则服务器会将警告写入错误日志。

在客户端,弃用没有明显效果。如果配置为允许弃用的 TLS 协议,则客户端不会发出警告。这包括:

  • --tls-version支持指定用于连接到 MySQL 服务器的 TLS 协议 的选项的客户端程序 。

  • 使副本能够为与源服务器的连接指定 TLS 协议的语句。(CHANGE MASTER TO有一个 MASTER_TLS_VERSION选项。)

连接密码配置

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

要为加密连接指定一个或多个密码,请ssl_cipher在服务器端设置系统变量,并使用 --ssl-cipher客户端程序的选项。

对于源/副本复制连接,此服务器实例是源,设置 ssl_cipher系统变量。如果此服务器实例是副本,请使用 语句的MASTER_SSL_CIPHER选项 。CHANGE MASTER TO请参阅 第 16.3.8 节,“设置复制以使用加密连接”

给定的密​​码可能仅适用于特定的 TLS 协议,这会影响 TLS 协议协商过程。请参阅 连接 TLS 协议协商

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

SHOW SESSION STATUS LIKE 'Ssl_cipher_list';

status 变量列出了可能的Ssl_cipher_listSSL 密码(对于非 SSL 连接为空)。可用密码集取决于您的 MySQL 版本以及 MySQL 是使用 OpenSSL 还是 yaSSL 编译的,以及(对于 OpenSSL)用于编译 MySQL 的库版本。

笔记

ECDSA 密码只能与使用 ECDSA 进行数字签名的 SSL 证书结合使用,而不能与使用 RSA 的证书结合使用。MySQL Server 的 SSL 证书自动生成过程不会生成 ECDSA 签名证书,它只会生成 RSA 签名证书。除非您有可用的 ECDSA 证书,否则不要选择 ECDSA 密码。

MySQL 将默认密码列表传递给 SSL 库。

MySQL 将此默认密码列表传递给 OpenSSL:

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

MySQL 将此默认密码列表传递给 yaSSL:

DHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA
AES128-RMD
DES-CBC3-RMD
DHE-RSA-AES256-RMD
DHE-RSA-AES128-RMD
DHE-RSA-DES-CBC3-RMD
AES256-SHA
RC4-SHA
RC4-MD5
DES-CBC3-SHA
DES-CBC-SHA
EDH-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC-SHA
AES128-SHA:AES256-RMD

从 MySQL 5.7.10 开始,这些密码限制已经到位:

  • 以下密码永久受限:

    !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 协议,因此除非也有兼容的密码,否则不会选择可用于协商过程的协议。

  • 如果服务器和客户端使用 OpenSSL 编译,则尽可能使用 TLSv1.2。如果服务器和客户端之一或两者都使用 yaSSL 编译,则尽可能使用 TLSv1.1。(可能意味着服务器和客户端配置都必须允许指定的协议,并且都必须允许一些协议兼容的加密密码。)否则,MySQL 继续通过可用协议列表,从更安全的协议到更不安全的协议。协商顺序与配置协议的顺序无关。例如,谈判顺序是相同的,无论是否 tls_version的值为 TLSv1,TLSv1.1,TLSv1.2TLSv1.2,TLSv1.1,TLSv1

    笔记

    在 MySQL 5.7.10 之前,MySQL 仅支持 TLSv1,用于 OpenSSL 和 yaSSL,并且不存在用于指定允许哪些 TLS 协议的系统变量或客户端选项。

  • 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 位的证书。

If the server and client do not have a permitted protocol in common, and a protocol-compatible cipher in common, the server terminates the connection request. Examples:

  • If the server is configured with tls_version=TLSv1.1,TLSv1.2:

    • Connection attempts fail for clients invoked with --tls-version=TLSv1, and for older clients that support only TLSv1.

    • Similarly, connection attempts fail for replicas configured with MASTER_TLS_VERSION = 'TLSv1', and for older replicas that support only TLSv1.

  • If the server is configured with tls_version=TLSv1 or is an older server that supports only TLSv1:

    • Connection attempts fail for clients invoked with --tls-version=TLSv1.1,TLSv1.2.

    • Similarly, connection attempts fail for replicas configured with MASTER_TLS_VERSION = 'TLSv1.1,TLSv1.2'.

MySQL permits specifying a list of protocols to support. This list is passed directly down to the underlying SSL library and is ultimately up to that library what protocols it actually enables from the supplied list. Please refer to the MySQL source code and the OpenSSL SSL_CTX_new() documentation for information about how the SSL library handles this.

Monitoring Current Client Session TLS Protocol and Cipher

要确定当前客户端会话使用哪种加密 TLS 协议和密码,请检查 Ssl_versionSsl_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                   |
+---------------+---------------------------+

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