有多个配置参数可用来指示是否使用加密连接,并指定适当的证书和密钥文件。本节提供了关于配置服务器和客户端以使用加密连接的一般指导:
加密连接也可以在其他上下文中使用,如下所述:
-
在源服务器和副本服务器之间的复制中。见 第 19.3.1 节,“设置复制以使用加密连接”。
-
在组复制服务器之间。见 第 20.6.2 节,“使用安全套接字层 (SSL) 保护组通信连接”。
-
通过基于 MySQL C API 的客户端程序。见 支持加密连接。
创建所需证书和密钥文件的说明可在 第 8.3.3 节,“创建 SSL 和 RSA 证书和密钥” 中找到。
在服务器端,--ssl
选项指定服务器允许但不需要加密连接。该选项默认启用,因此无需明确指定。
要要求客户端使用加密连接,启用 require_secure_transport
系统变量。见 配置加密连接 as 强制。
以下系统变量在服务器端指定服务器在允许客户端建立加密连接时使用的证书和密钥文件:
-
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
目录中的演示证书和密钥文件来测试您的设置。
服务器执行证书和密钥文件自动发现。如果没有明确的加密连接选项除了 --ssl
(可能与 ssl_cipher
配置加密连接),服务器尝试在启动时自动启用加密连接支持:
-
如果服务器在数据目录中发现有效的证书和密钥文件
ca.pem
、server-cert.pem
和server-key.pem
,它将启用客户端加密连接支持。(文件不需要自动生成;重要的是它们具有这些名称并且有效。) -
如果服务器在数据目录中找不到有效的证书和密钥文件,它将继续执行,但不支持加密连接。
如果服务器自动启用加密连接支持,它将在错误日志中写入一条注释。如果服务器发现 CA 证书是自签名的,它将在错误日志中写入一条警告。(证书是自签名的,如果服务器自动创建或使用 mysql_ssl_rsa_setup 手动创建。)
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 上下文。这项功能可能有助于避免重新启动已经运行了很长时间的 MySQL 服务器,其 SSL 证书已经过期。
要创建初始TLS上下文,服务器使用启动时的上下文相关系统变量的值。为了暴露上下文值,服务器还初始化了一组对应的状态变量。下表显示了定义TLS上下文的系统变量和暴露当前活动上下文值的对应状态变量。
表 8.12 服务器主连接接口TLS上下文的系统和状态变量
System Variable Name | Corresponding Status Variable Name |
---|---|
ssl_ca |
Current_tls_ca |
ssl_capath |
Current_tls_capath |
ssl_cert |
Current_tls_cert |
ssl_cipher |
Current_tls_cipher |
ssl_crl |
Current_tls_crl |
ssl_crlpath |
Current_tls_crlpath |
ssl_key |
Current_tls_key |
tls_ciphersuites |
Current_tls_ciphersuites |
tls_version |
Current_tls_version |
这些活动TLS上下文值也暴露在性能架构 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 上下文,但是性能架构 tls_channel_status
表公开了主接口和管理接口的 TLS 属性。请参阅 第 29.12.22.9 节,“The tls_channel_status 表”。
更新主接口 TLS 上下文具有以下效果:
-
更新更改了主连接接口上新的连接的 TLS 上下文。
-
更新还更改了管理接口上的新的连接的 TLS 上下文,除非为该接口配置了非默认的 TLS 参数值。
-
更新不影响其他启用的服务器插件或组件(如 Group Replication 或 X Plugin):
-
要将主接口重新配置应用于 Group Replication 的组通信连接,请执行
STOP GROUP_REPLICATION
,然后执行START GROUP_REPLICATION
以停止和重新启动 Group Replication。 -
X Plugin 在插件初始化时初始化其 TLS 上下文,如 第 22.5.3 节,“使用 X Plugin 的加密连接” 所述。该上下文后不再更改。
-
默认情况下,RELOAD TLS
操作将回滚并且不生效,如果配置值不允许创建新的 TLS 上下文。以前的上下文值将继续用于新的连接。如果给出了可选的 NO ROLLBACK ON ERROR
子句,并且无法创建新的上下文,则不会回滚。相反,将生成警告,并且加密将被禁用新的连接在该语句应用的接口上。
启用或禁用连接接口上的加密连接的选项仅在启动时生效。例如,--ssl
和 --admin-ssl
选项仅在启动时影响主接口和管理接口是否支持加密连接。这些选项在运行时被忽略,并且对 ALTER INSTANCE RELOAD TLS
的操作没有影响。例如,您可以使用 --ssl=OFF
启动服务器以禁用主接口上的加密连接,然后重新配置 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 证书,请使用
--ssl-ca
(或--ssl-capath
),并指定--ssl-mode=VERIFY_CA
。 -
要启用主机名身份验证,还可以使用
--ssl-mode=VERIFY_IDENTITY
而不是--ssl-mode=VERIFY_CA
。
使用 VERIFY_IDENTITY
的主机名身份验证不适用于使用 mysql_ssl_rsa_setup 自动生成或手动创建的自签名证书(见 第 8.3.3.1 节,“使用 MySQL 创建 SSL 和 RSA 证书和密钥”)。这些自签名证书不包含服务器名称作为公共名称值。
MySQL 还提供了这些客户端加密连接控制选项:
-
--ssl-cipher
:连接加密的允许密码列表。 -
--ssl-crl
:包含证书撤销列表的文件路径名。(--ssl-crlpath
类似,但指定了证书撤销列表文件目录的路径名。) -
--tls-version
、--tls-ciphersuites
:允许的加密协议和密码套件;见 第 8.3.2 节,“加密连接 TLS 协议和密码”。
根据 MySQL 帐户的加密要求,客户端可能需要指定某些选项以连接到 MySQL 服务器。
假设您想使用没有特殊加密要求的帐户或使用 CREATE USER
语句创建的帐户,包括 REQUIRE SSL
子句。假设服务器支持加密连接,客户端可以使用加密连接到 MySQL 服务器,而不需要 --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 服务器实例使用 SSL 证书具有 extendedKeyUsage
扩展(X.509 v3 扩展),则扩展密钥使用必须包括客户端身份验证 (clientAuth
)。如果 SSL 证书仅指定了服务器身份验证 (serverAuth
) 和其他非客户端证书目的,证书验证将失败,客户端连接到 MySQL 服务器实例将失败。 MySQL 服务器生成的 SSL 证书(如 第 8.3.3.1 节,“使用 MySQL 创建 SSL 和 RSA 证书和密钥” 中所述)中没有 extendedKeyUsage
扩展,使用 openssl 命令按照 第 8.3.3.2 节,“使用 openssl 创建 SSL 证书和密钥” 中的说明创建的 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
...
从 MySQL 8.1.0 开始,MySQL 服务器支持 tls-certificates-enforced-validation
系统变量,该变量启用服务器公钥证书文件、证书颁发机构(CA)证书文件和证书撤销列表文件的验证,在服务器启动时:
mysqld --tls-certificates-enforced-validation
如果设置为 ON
,服务器在启动时停止执行,如果证书无效。服务器通过提供有效的调试消息、错误消息或两者来通知 DBA,具体取决于证书的状态。这项功能可能有助于避免重新启动 MySQL 服务器,该服务器已经运行了很长时间,以至于其 SSL 证书已经过期。
类似地,当您执行 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 语法 for 变量赋值”。
启用 require_secure_transport
后,客户端连接到服务器时需要使用某种形式的安全传输,服务器仅允许使用 SSL 的 TCP/IP 连接或 Unix 中的套接字文件连接(在 Windows 中为共享内存连接)。服务器拒绝非安全连接尝试,这些尝试将失败并显示 ER_SECURE_TRANSPORT_REQUIRED
错误。
要调用客户端程序,以便在服务器不要求加密的情况下要求加密连接,请使用 --ssl-mode
选项值 REQUIRED
、VERIFY_CA
或 VERIFY_IDENTITY
。例如:
mysql --ssl-mode=REQUIRED
mysqldump --ssl-mode=VERIFY_CA
mysqladmin --ssl-mode=VERIFY_IDENTITY
要配置 MySQL 帐户,以便只能在加密连接下使用,请在创建帐户时包括 REQUIRE
子句,指定所需的加密特征。例如,要要求加密连接和有效的 X.509 证书,请使用 REQUIRE X509
:
CREATE USER 'jeffrey'@'localhost' REQUIRE X509;
有关 REQUIRE
子句的更多信息,请参阅 第 15.7.1.3 节,“CREATE USER 语句”。
要修改现有的帐户,以便没有加密要求,请使用 ALTER USER
语句。