文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  配置 MySQL 使用加密连接

8.3.1 配置 MySQL 使用加密连接

有几个配置参数可用于指示是否使用加密连接,并指定相应的证书和密钥文件。本节提供有关为加密连接配置服务器和客户端的一般指导

加密连接也可以在其他上下文中使用,如以下附加章节中所述

有关创建任何必需的证书和密钥文件的说明,请参阅 第 8.3.3 节“创建 SSL 和 RSA 证书和密钥”

加密连接的服务器端启动配置

要要求客户端使用加密连接进行连接,请启用 require_secure_transport 系统变量。请参阅 将加密连接配置为强制性

服务器端的这些系统变量指定服务器在允许客户端建立加密连接时使用的证书和密钥文件

  • ssl_ca:证书颁发机构 (CA) 证书文件的路径名。(ssl_capath 类似,但指定 CA 证书文件目录的路径名。)

  • ssl_cert:服务器公钥证书文件的路径名。此证书可以发送到客户端,并根据其拥有的 CA 证书进行身份验证。

  • ssl_key:服务器私钥文件的路径名。

例如,要启用服务器以进行加密连接,请在 my.cnf 文件中使用以下行启动它,并根据需要更改文件名

[mysqld]
ssl_ca=ca.pem
ssl_cert=server-cert.pem
ssl_key=server-key.pem

要另外指定客户端需要使用加密连接,请启用 require_secure_transport 系统变量

[mysqld]
ssl_ca=ca.pem
ssl_cert=server-cert.pem
ssl_key=server-key.pem
require_secure_transport=ON

每个证书和密钥系统变量都以 PEM 格式命名一个文件。如果您需要创建所需的证书和密钥文件,请参阅 第 8.3.3 节“创建 SSL 和 RSA 证书和密钥”。使用 OpenSSL 编译的 MySQL 服务器可以在启动时自动生成缺少的证书和密钥文件。请参阅 第 8.3.3.1 节“使用 MySQL 创建 SSL 和 RSA 证书和密钥”。或者,如果您有 MySQL 源代码分发版,则可以使用其 mysql-test/std_data 目录中的演示证书和密钥文件来测试您的设置。

服务器执行证书和密钥文件自动发现。如果没有给出配置加密连接的显式加密连接选项,则服务器会在启动时尝试自动启用加密连接支持

  • 如果服务器在数据目录中找到名为 ca.pemserver-cert.pemserver-key.pem 的有效证书和密钥文件,它将启用对客户端加密连接的支持。(这些文件不需要自动生成;重要的是它们具有这些名称并且有效。)

  • 如果服务器在数据目录中找不到有效的证书和密钥文件,它将继续执行,但不支持加密连接。

如果服务器自动启用加密连接支持,它会向错误日志写入一条记录。如果服务器发现 CA 证书是自签名的,它会向错误日志写入一条警告。(如果证书是由服务器自动创建的,则该证书是自签名的。)

MySQL 还提供以下系统变量,用于服务器端加密连接控制

如果服务器无法从用于服务器端加密连接控制的系统变量创建有效的 TLS 上下文,则服务器将在不支持加密连接的情况下执行。

加密连接的服务器端运行时配置和监控

tls_xxxssl_xxx 系统变量是动态的,可以在运行时设置,而不仅仅是在启动时设置。如果使用 SET GLOBAL 更改,则新值仅在服务器重新启动之前有效。如果使用 SET PERSIST 更改,则新值也会延续到后续服务器重新启动。请参阅第 15.7.6.1 节“用于变量赋值的 SET 语法”。但是,对这些变量的运行时更改不会立即影响新连接的 TLS 上下文,如本节后面所述。

除了允许对 TLS 上下文相关系统变量进行运行时更改之外,服务器还允许对用于新连接的实际 TLS 上下文进行运行时更新。此功能可能很有用,例如,为了避免重新启动运行时间过长且其 SSL 证书已过期的 MySQL 服务器。

为了创建初始 TLS 上下文,服务器使用上下文相关系统变量在启动时的值。为了公开上下文值,服务器还会初始化一组对应的状态变量。下表显示了定义 TLS 上下文的系统变量和公开当前活动上下文值的对应状态变量。


这些活动的 TLS 上下文值也作为属性在 Performance Schema tls_channel_status 表中公开,以及任何其他活动 TLS 上下文的属性。

要在运行时重新配置 TLS 上下文,请使用以下过程

  1. 将应更改的每个 TLS 上下文相关系统变量设置为其新值。

  2. 执行 ALTER INSTANCE RELOAD TLS。此语句从 TLS 上下文相关系统变量的当前值重新配置活动的 TLS 上下文。它还设置上下文相关的状态变量以反映新的活动上下文值。该语句需要 CONNECTION_ADMIN 权限。

  3. 执行 ALTER INSTANCE RELOAD TLS 之后建立的新连接将使用新的 TLS 上下文。现有连接不受影响。如果应终止现有连接,请使用 KILL 语句。

由于重新配置过程的工作方式,每对系统变量和状态变量的成员可能会暂时具有不同的值

  • ALTER INSTANCE RELOAD TLS 之前的系统变量更改不会更改 TLS 上下文。此时,这些更改对新连接没有影响,并且相应的上下文相关系统变量和状态变量可能具有不同的值。这使您可以对各个系统变量进行任何所需的更改,然后在所有系统变量更改完成后,使用 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 上下文的通道(接口)。请参阅第 15.1.5 节“ALTER INSTANCE 语句”。没有状态变量来公开管理接口 TLS 上下文,但 Performance Schema tls_channel_status 表公开了主接口和管理接口的 TLS 属性。请参阅第 29.12.22.9 节“tls_channel_status 表”

更新主接口 TLS 上下文具有以下效果

  • 更新将更改用于主连接接口上的新连接的 TLS 上下文。

  • 更新还会更改用于管理接口上的新连接的 TLS 上下文,除非为该接口配置了一些非默认 TLS 参数值。

  • 更新不会影响其他启用的服务器插件或组件(如组复制或 X 插件)使用的 TLS 上下文

默认情况下,如果配置值不允许创建新的 TLS 上下文,则 RELOAD TLS 操作将回滚并报错,并且不会产生任何效果。先前的上下文值将继续用于新连接。如果给出了可选的 NO ROLLBACK ON ERROR 子句并且无法创建新的上下文,则不会发生回滚。相反,会生成警告,并且会为该语句适用的接口上的新连接禁用加密。

加密连接的客户端配置

有关与建立加密连接相关的客户端选项的完整列表,请参阅加密连接的命令选项

默认情况下,如果服务器支持加密连接,MySQL 客户端程序会尝试建立加密连接,并可通过 --ssl-mode 选项进行进一步控制

  • 在没有 --ssl-mode 选项的情况下,客户端会尝试使用加密进行连接,如果无法建立加密连接,则回退到未加密的连接。这也是使用显式 --ssl-mode=PREFERRED 选项时的行为。

  • 使用 --ssl-mode=REQUIRED 时,客户端需要加密连接,如果无法建立加密连接,则会失败。

  • 使用 --ssl-mode=DISABLED 时,客户端将使用未加密的连接。

  • 使用 --ssl-mode=VERIFY_CA--ssl-mode=VERIFY_IDENTITY 时,客户端需要加密连接,并且还会根据服务器 CA 证书(使用 VERIFY_IDENTITY 时)及其证书中的服务器主机名执行验证。

重要

如果其他默认设置保持不变,则默认设置 --ssl-mode=PREFERRED 将生成加密连接。但是,为了帮助防止复杂的中间人攻击,客户端验证服务器的身份非常重要。设置 --ssl-mode=VERIFY_CA--ssl-mode=VERIFY_IDENTITY 比默认设置更能帮助防止此类攻击。VERIFY_CA 使客户端检查服务器的证书是否有效。VERIFY_IDENTITY 使客户端检查服务器的证书是否有效,并使客户端检查客户端使用的主机名是否与服务器证书中的标识匹配。要实现其中一种设置,您必须首先确保服务器的 CA 证书对您环境中使用它的所有客户端都可靠可用,否则会导致可用性问题。因此,它们不是默认设置。

如果在服务器端启用了 require_secure_transport 系统变量以使服务器需要加密连接,则尝试建立未加密的连接将失败。请参阅将加密连接配置为必需

客户端上的以下选项标识了客户端在建立与服务器的加密连接时使用的证书和密钥文件。它们类似于服务器端使用的 ssl_cassl_certssl_key 系统变量,但 --ssl-cert--ssl-key 标识了客户端公钥和私钥。

  • --ssl-ca:证书颁发机构 (CA) 证书文件的路径名。如果使用此选项,则必须指定与服务器使用的证书相同的证书。(--ssl-capath 类似,但指定的是 CA 证书文件目录的路径名。)

  • --ssl-cert:客户端公钥证书文件的路径名。

  • --ssl-key:客户端私钥文件的路径名。

为了获得相对于默认加密提供的额外安全性,客户端可以提供与服务器使用的证书相匹配的 CA 证书,并启用主机名身份验证。这样,服务器和客户端都信任同一个 CA 证书,并且客户端可以验证它所连接的主机是否是预期的主机。

注意

使用 VERIFY_IDENTITY 进行主机名身份验证不适用于由服务器自动创建的自签名证书(请参阅 第 8.3.3.1 节“使用 MySQL 创建 SSL 和 RSA 证书和密钥”)。此类自签名证书不包含作为通用名称值的服务器名称。

MySQL 还提供以下用于客户端加密连接控制的选项:

根据客户端使用的 MySQL 帐户的加密要求,客户端可能需要指定某些选项才能使用加密连接到 MySQL 服务器。

假设您想使用没有特殊加密要求的帐户或使用包含 REQUIRE SSL 子句的 CREATE USER 语句创建的帐户进行连接。假设服务器支持加密连接,则客户端可以使用加密连接,而无需 --ssl-mode 选项,或者使用显式 --ssl-mode=PREFERRED 选项。

mysql

或者

mysql --ssl-mode=PREFERRED

对于使用 REQUIRE SSL 子句创建的帐户,如果无法建立加密连接,则连接尝试将失败。对于没有特殊加密要求的帐户,如果无法建立加密连接,则尝试将回退到未加密的连接。要防止回退并在无法获得加密连接时失败,请像这样连接:

mysql --ssl-mode=REQUIRED

如果帐户具有更严格的安全要求,则必须指定其他选项才能建立加密连接。

  • 对于使用 REQUIRE X509 子句创建的帐户,客户端必须至少指定 --ssl-cert--ssl-key。此外,建议使用 --ssl-ca(或 --ssl-capath),以便可以验证服务器提供的公共证书。例如(在一行中输入命令):

    mysql --ssl-ca=ca.pem
          --ssl-cert=client-cert.pem
          --ssl-key=client-key.pem
  • 对于使用 REQUIRE ISSUERREQUIRE SUBJECT 子句创建的帐户,加密要求与 REQUIRE X509 相同,但证书必须分别与帐户定义中指定的颁发者或使用者相匹配。

有关 REQUIRE 子句的其他信息,请参阅 第 15.7.1.3 节“CREATE USER 语句”

MySQL 服务器可以生成客户端证书和密钥文件,客户端可以使用这些文件连接到 MySQL 服务器实例。请参阅 第 8.3.3 节“创建 SSL 和 RSA 证书和密钥”

重要

如果连接到 MySQL 服务器实例的客户端使用带有 extendedKeyUsage 扩展名(X.509 v3 扩展名)的 SSL 证书,则扩展密钥用法必须包含客户端身份验证(clientAuth)。如果仅针对服务器身份验证(serverAuth)和其他非客户端证书用途指定了 SSL 证书,则证书验证将失败,并且客户端与 MySQL 服务器实例的连接将失败。MySQL 服务器生成的 SSL 证书中没有 extendedKeyUsage 扩展名(如 第 8.3.3.1 节“使用 MySQL 创建 SSL 和 RSA 证书和密钥” 中所述),并且使用 openssl 命令创建的 SSL 证书遵循 第 8.3.3.2 节“使用 openssl 创建 SSL 证书和密钥” 中的说明。如果您使用以其他方式创建的自己的客户端证书,请确保任何 extendedKeyUsage 扩展名都包含客户端身份验证。

要防止使用加密并覆盖其他 --ssl-xxx 选项,请使用 --ssl-mode=DISABLED 调用客户端程序。

mysql --ssl-mode=DISABLED

要确定与服务器的当前连接是否使用加密,请检查 Ssl_cipher 状态变量的会话值。如果该值为空,则连接未加密。否则,连接已加密,并且该值指示加密密码。例如:

mysql> SHOW SESSION STATUS LIKE 'Ssl_cipher';
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| Ssl_cipher    | DHE-RSA-AES128-GCM-SHA256 |
+---------------+---------------------------+

对于 mysql 客户端,另一种方法是使用 STATUS\s 命令并检查 SSL 行。

mysql> \s
...
SSL: Not in use
...

或者

mysql> \s
...
SSL: Cipher in use is DHE-RSA-AES128-GCM-SHA256
...

配置证书验证强制执行

--tls-certificates-enforced-validation 选项用于在服务器启动时启用对服务器公钥证书文件、证书颁发机构 (CA) 证书文件和证书吊销列表文件的验证。

mysqld --tls-certificates-enforced-validation

如果设置为 ON,则服务器会在证书无效的情况下停止执行启动。服务器通过提供有效的调试消息、错误消息或两者兼有(取决于证书的状态)来通知 DBA。例如,此功能可能有助于避免重新启动运行时间过长且其 SSL 证书已过期的 MySQL 服务器。

同样,当您执行 ALTER INSTANCE RELOAD TLS 语句以在运行时更改 TLS 上下文时,如果验证失败,则不会使用新的服务器和 CA 证书文件。在这种情况下,服务器将继续使用旧证书。有关动态更改 TLS 上下文的更多信息,请参阅 加密连接的服务器端运行时配置和监控

验证 CA 证书

对于使用服务器主接口的连接:

  • 如果指定了 --ssl_ca,则服务器将验证相应的 CA 证书,并向 DBA 发出相应的警告消息。

  • 如果指定了 --ssl_capath,则服务器将验证相应文件夹中的所有 CA 证书,并向 DBA 发出相应的警告消息。

  • 如果未指定 SSL 参数,则默认情况下,服务器将验证数据目录中存在的 CA 证书,并向 DBA 发出相应的警告消息。

对于使用服务器管理接口的连接:

  • 如果指定了 --admin_ssl_ca,则服务器将验证相应的 CA 证书,并向 DBA 发出相应的警告消息。

  • 如果指定了 --admin_ssl_capath,则服务器将验证相应文件夹中的所有 CA 证书,并向 DBA 发出相应的警告消息。

  • 如果未指定管理 SSL 参数,则默认情况下,服务器将验证数据目录中存在的 CA 证书,并向 DBA 发出相应的警告消息。

验证服务器证书

对于使用服务器主接口的连接:

  • 如果未指定 --ssl_cert,则服务器将验证默认数据目录中的服务器证书。

  • 如果给定了 --ssl_cert,则服务器将验证服务器证书,并考虑 --ssl_crl(如果指定)。

  • 如果 DBA 设置了命令行选项来验证证书,则服务器会在证书无效的情况下停止,并向 DBA 显示相应的错误消息。否则,服务器将向 DBA 发出警告消息,并且服务器将启动。

对于使用服务器管理接口的连接:

  • 如果未指定 --admin_ssl_cert,则服务器将验证默认数据目录中的服务器证书。

  • 如果给定了 --admin_ssl_cert,则服务器将验证服务器证书,并考虑 --admin_ssl_crl(如果指定)。

  • 如果 DBA 设置了命令行选项来验证证书,则服务器会在证书无效的情况下停止,并向 DBA 显示相应的错误消息。否则,服务器将向 DBA 发出警告消息,并且服务器将启动。

将加密连接配置为强制性连接

对于某些 MySQL 部署,使用加密连接可能不仅是可取的,而且是强制性的(例如,为了满足监管要求)。本节讨论使您能够执行此操作的配置设置。可以使用以下级别的控制:

  • 您可以将服务器配置为要求客户端使用加密连接进行连接。

  • 您可以调用单个客户端程序来要求加密连接,即使服务器允许但不强制要求加密也是如此。

  • 您可以将单个 MySQL 帐户配置为仅通过加密连接才能使用。

要要求客户端使用加密连接进行连接,请启用 require_secure_transport 系统变量。例如,将以下几行代码放入服务器 my.cnf 文件中:

[mysqld]
require_secure_transport=ON

或者,要在运行时设置并持久化该值,请使用以下语句:

SET PERSIST require_secure_transport=ON;

SET PERSIST 用于为正在运行的 MySQL 实例设置值。它还会保存该值,以便在后续服务器重启时使用。请参阅 第 15.7.6.1 节 “SET 语法用于变量赋值”

启用 require_secure_transport 后,与服务器的客户端连接需要使用某种形式的安全传输,并且服务器仅允许使用 SSL 的 TCP/IP 连接,或使用套接字文件(在 Unix 上)或共享内存(在 Windows 上)的连接。服务器会拒绝不安全的连接尝试,这些尝试会失败并显示 ER_SECURE_TRANSPORT_REQUIRED 错误。

要调用客户端程序以使其需要加密连接(无论服务器是否需要加密),请使用 --ssl-mode 选项值 REQUIREDVERIFY_CAVERIFY_IDENTITY。例如

mysql --ssl-mode=REQUIRED
mysqldump --ssl-mode=VERIFY_CA
mysqladmin --ssl-mode=VERIFY_IDENTITY

要将 MySQL 帐户配置为仅可通过加密连接使用,请在创建该帐户的 CREATE USER 语句中包含 REQUIRE 子句,并在该子句中指定所需的加密特征。例如,要要求加密连接和使用有效的 X.509 证书,请使用 REQUIRE X509

CREATE USER 'jeffrey'@'localhost' REQUIRE X509;

有关 REQUIRE 子句的其他信息,请参阅 第 15.7.1.3 节“CREATE USER 语句”

要修改没有加密要求的现有帐户,请使用 ALTER USER 语句。