身份认证插件
在使用客户端登录MySQL8.0 时,经常会遇到下面这个报错:
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded
ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
- mysql_native_password
- caching_sha2_password
Note:
As of MySQL 8.0.34, the mysql_native_password authentication plugin is deprecated and subject to removal in a future version of MySQL.
-- 查看默认身份默认插件
show global variables like "%auth%";
-- 查看当前使用的身份认证插件
SELECT USER,PLUGIN FROM mysql.`user` ;
+------------------+-----------------------+
| USER | PLUGIN |
+------------------+-----------------------+
| mysql.infoschema | caching_sha2_password |
| mysql.session | caching_sha2_password |
| mysql.sys | caching_sha2_password |
| root | caching_sha2_password |
+------------------+-----------------------+
--修改用户的身份认证插件
CREATE USER 'baiding01'@'%' IDENTIFIED BY '123456';
--会清空密码
ALTER USER 'baiding01'@'%' IDENTIFIED WITH mysql_native_password;
--正确修改身份认证插件
ALTER USER 'baiding01'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
CREATE USER 'baiding01'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
CREATE USER 'baiding01'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'password';
安全连接 SSL (Secure Socket Layer)
为了更方便支持安全连接,从mysql 5.7.28开始使用 OpenSSL 编译的 MySQL 服务在启动时会自动生成缺失的 SSL 和 RSA 证书及密钥文件(在datadir目录下)。
服务器端配置
SSL 证书
在启动时,如果启用了 auto_generate_certs 系统变量,未指定除--ssl之外的SSL选项,并且数据目录中缺少服务器端SSL文件,则服务器会自动在数据目录中生成服务器端和客户端的SSL证书和密钥文件。
文件 | 描述 |
---|---|
server-cert.pem | 服务器端的SSL证书文件。它包含了服务器的公钥以及由可信的证书颁发机构(CA)签发的身份验证信息。客户端会用它来验证服务器的身份,确保正在与之通信的是预期的服务器。 |
server-key.pem | 服务器端的私钥文件。私钥必须保密,仅服务器知道。服务器使用它来解密客户端发送的加密数据,并对自己发送的数据进行加密。 |
client-cert.pem | 客户端的SSL证书文件。如果SSL通信要求双向认证(即服务器也需要验证客户端的身份),这个证书就包含了客户端的公钥和身份验证信息。 |
client-key.pem | 客户端的私钥文件。与服务器端的私钥类似,客户端的私钥也必须保密。客户端使用它来解密服务器发送的加密数据,并对自己发送的数据进行加密。 |
ca.pem | 证书颁发机构(CA)的根证书文件。它包含了CA的公钥,用于验证由该CA签发的所有证书的真实性。在SSL通信中,服务器和客户端都会使用这个根证书来验证对方的证书是否有效。 |
ca-key.pem | 证书颁发机构(CA)的私钥文件。CA使用这个私钥来对其签发的证书进行数字签名。这个文件必须非常安全,因为如果泄露,攻 击者可以伪造证书。 |
查看当前基础环境
--查看默认数据目录
ls -l *.pem
--查看SSL是否启用
mysql> show variables like '%ssl%';
+-------------------------------------+-----------------+
| Variable_name | Value |
+-------------------------------------+-----------------+
| have_openssl | YES |
| have_ssl | YES | # 启动ssl
| performance_schema_show_processlist | OFF |
| ssl_ca | ca.pem |
| ssl_capath | |
| ssl_cert | server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | server-key.pem |
+-------------------------------------+-----------------+
或
mysql> SELECT * FROM performance_schema.tls_channel_status\G
*************************** 1. row ***************************
CHANNEL: mysql_main
PROPERTY: Enabled
VALUE: Yes
*************************** 2. row ***************************
CHANNEL: mysql_main
PROPERTY: ssl_accept_renegotiates
VALUE: 0
*************************** 3. row ***************************
CHANNEL: mysql_main
PROPERTY: Ssl_accepts
VALUE: 2
...
*************************** 29. row ***************************
CHANNEL: mysql_admin
PROPERTY: Enabled
VALUE: No
--查看当前连接是否加密
mysql> SHOW SESSION STATUS LIKE 'Ssl_cipher';
或
mysql> status
或
mysql> \s
客户端配置
-
使用未加密连接
--默认root用户,使用sock文件登录,默认是非加密方式 [mysql@db1 ~]$ /usr/local/mysql8038/bin/mysql -uroot -S /mysql/8038/tmp/mysql.sock root@(none)>\s -------------- /usr/local/mysql8038/bin/mysql Ver 8.0.38 for Linux on x86_64 (MySQL Community Server - GPL) Connection id: 13 Current database: Current user: root@localhost SSL: Not in use Current pager: stdout
--业务用户sha2user,使用sock文件登录,默认是非加密方式 root@(none)> CREATE USER 'sha2user'@'%' IDENTIFIED BY 'passwd123'; root@(none)> GRANT SELECT ON *.* TO 'sha2user'@'%'; [mysql@db1 ~]$ /usr/local/mysql8038/bin/mysql -usha2user -ppasswd123 -S /mysql/8038/tmp/mysql.sock sha2user@(none)>\s -------------- /usr/local/mysql/bin/mysql Ver 14.14 Distrib 5.7.32-35, for Linux (x86_64) using 6.0 Connection id: 14 Current database: Current user: sha2user@localhost SSL: Not in use
--业务用户,使用IP+端口登录(之所以能登录成功,是因为利用了之前登录的缓存信息)。 C:\Users>mysql -usha2user -ppasswd123 -h192.168.2.100 -P8038 --ssl-mode=DISABLED mysql> \s -------------- mysql Ver 8.3.0 for Win64 on x86_64 (MySQL Community Server - GPL) Connection id: 29 Current database: Current user: sha2user@192.168.2.1 SSL: Not in use 在服务器上清除用户的缓存信息 root@(none)>flush privileges; 在客户端使用非安全方式登录 C:\Users>mysql -usha2user -ppasswd123 -h192.168.2.100 -P8038 --ssl-mode=DISABLED mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
-
显示使用加密连接
#--ssl-mode=PREFERRED 默认行为,client 端尝试使用加密进行连接,如果无法构建加密连接,则会退回到未加密的连接 C:\Users>mysql -usha2user -ppasswd123 -h192.168.2.100 -P8038 --ssl-mode=PREFERRED mysql> \s -------------- mysql Ver 8.3.0 for Win64 on x86_64 (MySQL Community Server - GPL) Connection id: 38 Current database: Current user: sha2user@192.168.2.1 SSL: Cipher in use is TLS_AES_128_GCM_SHA256 Using delimiter: ; #--ssl-mode=REQUIRED Client 端需要加密连接,如果无法构建连接,则 Client 端将失败 C:\Users>mysql -usha2user -ppasswd123 -h192.168.2.100 -P8038 --ssl-mode=REQUIRED mysql> \s -------------- mysql Ver 8.3.0 for Win64 on x86_64 (MySQL Community Server - GPL) Connection id: 39 Current database: Current user: sha2user@192.168.2.1 SSL: Cipher in use is TLS_AES_128_GCM_SHA256 Using delimiter: ; #--ssl-mode=VERIFY_CA,指定需要验证 CA 证书,因为这个 CA 证书是自签发的,所以不在浏览器和操作系统的可信任区,则必须要将 CA 证书拷贝到客户端,并指定 CA 证书文件 C:\Users>mysql -usha2user -ppasswd123 -h192.168.2.100 -P8038 --ssl-ca=D:\SSL\ca.pem mysql> \s -------------- mysql Ver 8.3.0 for Win64 on x86_64 (MySQL Community Server - GPL) Connection id: 40 Current database: Current user: sha2user@192.168.2.1 SSL: Cipher in use is TLS_AES_128_GCM_SHA256 Using delimiter: ; #对于使用 REQUIRE X509 子句创建的帐户,客户端必须指定 --ssl-cert 和 --ssl-key。 CREATE USER 'baiding2024'@'%' IDENTIFIED BY '123456' REQUIRE X509 ; GRANT SELECT ON *.* TO 'baiding2024'@'%'; mysql -ubaiding2024 -h192.168.2.100 -P8038 --ssl-cert=D:\SSL\client-cert.pem --ssl-key=D:\SSL\client-key.pem
参数 值 说明 --ssl-mode PREFERRED 默认行为,client 端尝试使用加密进行连接,如果无法构建加密连接,则会退回到未加密的连接 REQUIRED Client 端需要加密连接,如果无法构建连接,则 Client 端将失败 DISABLED Client 端使用未加密的连接 VERIFY_CA Client 端需要加密连接,并且还对 CA 证书进行验证 VERIFY_IDENTITY Client 端需要加密的连接,并且还针对 CA 证书和其证书中的服务器主机名执行验证。主机名身份验证VERIFY_IDENTITY 不适用于由服务器自动创建或使用 mysql_ssl_rsa_setup 手动创建的自签名CA证书。
MySQL SSL 连接中的握手过程
- 客户端发起 ssl 连接请求;
- MySQL Server 发送数字证书 server-cert.pem 给客户端(server-cert.pem包含:服务器公钥、CA签名信息);
- 客户端使用CA 证书 ca.pem(由于这是 MySQL 自签名的CA证书,无法从操作系统的可信任区获取,所以事先必须在客户端本地保存 CA 证书文件)中的 CA 公钥解密 server-cert.pem 中的签名,进行验证;
- 验证通过后,生成对称密钥,使用 server-cert.pem 中的公钥加密“对称密钥”,发送给 MySQL Server;
- MySQL Server 使用自己保留的私钥 server-key.pem 解密,得到“对称密钥”;
- 接下来传输数据则使用“对称密钥”进加密和解密。
如果仅指定 --ssl-mode=REQUIRED,不指定 --ssl-mode=VERIFY_CA 或者 --ssl-mode=VERIFY_IDENTITY,则不需要步骤3。
强制客户端以加密方式登录
--启用变量 require_secure_transport
root@(none)>show global variables like "require_secure_transport";
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| require_secure_transport | OFF |
+--------------------------+-------+
1 row in set (2.98 sec)
root@(none)>set global require_secure_transport=ON;
Query OK, 0 rows affected (0.20 sec)
root@(none)>show global variables like "require_secure_transport";
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| require_secure_transport | ON |
+--------------------------+-------+
1 row in set (0.40 sec)
root@(none)>
# 在本机通过 mysql.sock 方式登录,默认是已非加密方式登录
[mysql@db1 ~]$ /usr/local/mysql8038/bin/mysql -uroot -S /mysql/8038/tmp/mysql.sock --ssl-mode=DISABLED
root@(none)>\s
--------------
Connection id: 50
Current database:
Current user: root@localhost
SSL: Not in use
# --ssl-mode=DISABLED 以显示的非加密方式登录,无论是否存在登录缓存,直接抛出异常
C:\Users>mysql -ubaiding01 -p123456 -h192.168.2.100 -P8038 --ssl-mode=DISABLED
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.
强制单独用户加密登录
-- REQUIRE SSL 用户只能已加密方式登录
mysql> CREATE USER 'baiding01'@'%' IDENTIFIED BY '123456' REQUIRE SSL ;
mysql> GRANT SELECT ON *.* TO 'baiding01'@'%';
-- REQUIRE X509 具有REQUIRE X509子句的用户,客户端必须指定--ssl-key 和--ssl-cert选项才能连接。
mysql> CREATE USER 'baiding02'@'%' IDENTIFIED BY '123456' REQUIRE X509 ;
mysql> GRANT SELECT ON *.* TO 'baiding02'@'%';
mysql -ubaiding2024 -h192.168.2.100 -P8038 --ssl-cert=D:\SSL\client-cert.pem --ssl-key=D:\SSL\client-key.pem
RSA密钥对交换密码的非加密连接
RSA 证书
sha256_password_auto_generate_rsa_keys
or caching_sha2_password_auto_generate_rsa_keys
这两个系统变量是相关的,但它们控制的是自动生成RSA密钥对文件。
文件 | 变量 | 描述 |
---|---|---|
public_key.pem | caching_sha2_password_public_key_path | 公钥文件,它包含了公钥,可以被任何人获取和使用。公钥的主要作用是加密数据或验证数字签名。在公钥加密中,只有对应的私钥才能解密用公钥加密的数据。 |
private_key.pem | caching_sha2_password_private_key_path | 私钥文件,它包含了私钥,必须严格保密,只有密钥的所有者才能使用。私钥的主要作用是解密用公钥加密的数据或生成数字签名。 |
#对于这次由 baiding01 发起的连接尝试,服务器判断 caching_sha2_password 是合适的认证插件并调用它(因为在创建用户时指定了该插件)。插件发现连接未加密,因此要求使用 RSA 加密来传输密码。然而,服务器并未将公钥发送给客户端,而客户端也未提供公钥,因此无法加密密码,连接失败。
mysql -ubaiding01 -p123456 -h 192.168.2.100 -P8038 --ssl-mode=DISABLED
mysql -ubaiding01 -p123456 -h 192.168.2.100 -P8038 --ssl-mode=DISABLED --get-server-public-key
mysql -ubaiding01 -p123456 -h 192.168.2.100 -P8038 --ssl-mode=DISABLED --server-public-key-path=file_name
总结
变量 | 身份认证插件 | 说明 | |
---|---|---|---|
--ssl=ON | caching_sha2_password | 支持加密登录 <br />支持非加密登陆 | 可以通过mysql.sock以非加密方式登录<br />可以利用登录缓存以非加密方式登录<br />可以使用RSA方式登录 |
--ssl=ON<br />--require_secure_transport | caching_sha2_password | 强制客户端以加密方式登录 | 可以通过mysql.sock以非加密方式登录 |
--ssl=ON<br />--REQUIRE SSL | caching_sha2_password | 针对单独用户强制以加密方式登录 | 只能以加密方式登录<br />即使通过sock方式也只能以加密方式登录 |