有几个配置参数可用于指示是否使用加密连接,并指定适当的证书和密钥文件。本节提供有关为加密连接配置服务器和客户端的一般指导。
加密连接也可以在其他上下文中使用,如以下附加章节所述:
在源和副本复制服务器之间。参见 第 19.3.1 节“将复制设置为使用加密连接”。
在组复制服务器之间。参见 第 20.6.2 节“使用安全套接字层 (SSL) 保护组通信连接”。
通过基于 MySQL C API 的客户端程序。参见 对加密连接的支持。
有关创建任何所需证书和密钥文件的说明,请参见 第 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.pem
、server-cert.pem
和server-key.pem
的有效证书和密钥文件,则会启用客户端加密连接支持。(这些文件不需要自动生成;重要的是它们具有这些名称并且有效。)如果服务器在数据目录中未找到有效的证书和密钥文件,它将继续执行,但不支持加密连接。
如果服务器自动启用加密连接支持,它会向错误日志写入一条注释。如果服务器发现 CA 证书是自签名的,它会向错误日志写入一条警告。(如果证书是由服务器自动创建的,则该证书是自签名的。)
MySQL 还提供以下系统变量,用于控制服务器端加密连接
ssl_cipher
:允许用于连接加密的密码列表。ssl_crl
:包含证书吊销列表的文件的路径名。(ssl_crlpath
类似,但指定证书吊销列表文件目录的路径名。)tls_version
、tls_ciphersuites
:服务器允许用于加密连接的加密协议和密码套件;请参阅 第 8.3.2 节“加密连接 TLS 协议和密码”。例如,您可以配置tls_version
以防止客户端使用安全性较低的协议。
如果服务器无法从服务器端加密连接控制的系统变量创建有效的 TLS 上下文,则服务器将在不支持加密连接的情况下执行。
tls_
和 xxx
ssl_
系统变量是动态的,可以在运行时设置,而不仅仅是在启动时设置。如果使用 xxx
SET GLOBAL
更改,则新值仅在服务器重新启动之前有效。如果使用 SET PERSIST
更改,则新值也会延续到后续的服务器重新启动。请参阅 第 15.7.6.1 节“用于变量赋值的 SET 语法”。但是,对这些变量的运行时更改不会立即影响新连接的 TLS 上下文,如本节稍后所述。
除了允许对与 TLS 上下文相关的系统变量进行运行时更改之外,服务器还允许对用于新连接的实际 TLS 上下文进行运行时更新。例如,此功能可能有助于避免重新启动已运行很长时间且其 SSL 证书已过期的 MySQL 服务器。
为了创建初始 TLS 上下文,服务器使用与上下文相关的系统变量在启动时的值。为了公开上下文值,服务器还会初始化一组相应的status 变量。下表显示了定义 TLS 上下文的系统变量和公开当前活动上下文值的相应状态变量。
这些活动的 TLS 上下文值也作为 Performance Schema tls_channel_status
表中的属性公开,以及任何其他活动的 TLS 上下文的属性。
要在运行时重新配置 TLS 上下文,请使用以下步骤
将应更改的每个与 TLS 上下文相关的系统变量设置为其新值。
执行
ALTER INSTANCE RELOAD TLS
。此语句从与 TLS 上下文相关的系统变量的当前值重新配置活动的 TLS 上下文。它还设置与上下文相关的状态变量以反映新的活动上下文值。该语句需要CONNECTION_ADMIN
权限。执行
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 上下文相关的系统变量中获取其设置),您必须执行
STOP GROUP_REPLICATION
,然后执行START GROUP_REPLICATION
来停止并重新启动组复制。X 插件在插件初始化时初始化其 TLS 上下文,如 第 22.5.3 节“将加密连接与 X 插件结合使用” 中所述。此上下文此后不会更改。
默认情况下,如果配置值不允许创建新的 TLS 上下文,则 RELOAD TLS
操作将回滚并报错,并且不会产生任何影响。以前的上下文值将继续用于新连接。如果给出了可选的 NO ROLLBACK ON ERROR
子句并且无法创建新的上下文,则不会发生回滚。相反,会生成警告,并且将为语句适用的接口上的新连接禁用加密。
启用或禁用连接接口上的加密连接的选项仅在启动时有效。例如,--tls-version
和 --admin-tls-version
选项仅在启动时影响主接口和管理接口是否支持这些 TLS 版本。此类选项将被忽略,并且对运行时 ALTER INSTANCE RELOAD TLS
的操作没有影响。例如,您可以设置 tls_version=''
以在主接口上禁用加密连接的情况下启动服务器,然后重新配置 TLS 并执行 ALTER INSTANCE RELOAD TLS
以在运行时启用加密连接。
有关与建立加密连接相关的客户端选项的完整列表,请参阅 加密连接的命令选项。
默认情况下,如果服务器支持加密连接,则 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_ca
、ssl_cert
和 ssl_key
系统变量,但 --ssl-cert
和 --ssl-key
标识客户端公钥和私钥
--ssl-ca
:证书颁发机构 (CA) 证书文件的路径名。 如果使用此选项,则必须指定服务器使用的相同证书。 (--ssl-capath
类似,但指定的是 CA 证书文件目录的路径名。)--ssl-cert
:客户端公钥证书文件的路径名。--ssl-key
:客户端私钥文件的路径名。
为了获得相对于默认加密提供的额外安全性,客户端可以提供与服务器使用的 CA 证书相匹配的 CA 证书并启用主机名身份验证。 这样,服务器和客户端就会信任同一个 CA 证书,并且客户端会验证它连接到的主机是否是预期的主机
要指定 CA 证书,请使用
--ssl-ca
(或--ssl-capath
),并指定--ssl-mode=VERIFY_CA
。要同时启用主机名身份验证,请使用
--ssl-mode=VERIFY_IDENTITY
而不是--ssl-mode=VERIFY_CA
。
使用 VERIFY_IDENTITY
进行主机名身份验证不适用于服务器自动创建的自签名证书(请参阅第 8.3.3.1 节“使用 MySQL 创建 SSL 和 RSA 证书和密钥”)。 此类自签名证书不包含作为通用名称值的服务器名称。
MySQL 还为客户端加密连接控制提供以下选项
--ssl-cipher
:允许用于连接加密的密码列表。--ssl-crl
:包含证书吊销列表的文件的路径名。 (--ssl-crlpath
类似,但指定的是证书吊销列表文件目录的路径名。)--tls-version
、--tls-ciphersuites
:允许的加密协议和密码套件;请参阅第 8.3.2 节“加密连接 TLS 协议和密码”。
根据客户端使用的 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 ISSUER
或REQUIRE 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 Server 生成的 SSL 证书中没有 extendedKeyUsage
扩展名(如第 8.3.3.1 节“使用 MySQL 创建 SSL 和 RSA 证书和密钥”中所述),并且按照第 8.3.3.2 节“使用 openssl 创建 SSL 证书和密钥”中的说明使用 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
错误。
要调用客户端程序以使其需要加密连接(无论服务器是否需要加密),请使用值为 REQUIRED
、VERIFY_CA
或 VERIFY_IDENTITY
的 --ssl-mode
选项。例如
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
语句。