目录
一.踩坑原因
在华为云上部署nacos,启动时报错:
2022-03-30 14:18:29,490 INFO Tomcat initialized with port(s): 8848 (http)
2022-03-30 14:18:30,201 INFO Root WebApplicationContext: initialization completed in 6256 ms
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:371)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:523)
报错重点:
Caused by: com.mysql.cj.exceptions.CJException: Public Key Retrieval is not allowed
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
二.踩坑之前
我的华为云:
[root@hecs-xxxxxx ~]# lsb_release -a
LSB Version: n/a
Distributor ID: HuaweiCloudEulerOS
Description: Huawei Cloud EulerOS release 1.0 (x86_64)
Release: 1.0
Codename: x86_64
[root@hecs-341889 ~]#
nacos版本 1.3.4 自带的connector-java 是 8.0.21
mysql版本 8.0.28
三.报错原因
根据cause by 内容搜索得知以下内容
Name | Default | Description |
---|---|---|
Allow Public Key Retrieval, AllowPublicKeyRetrieval | false | If the user account uses sha256_password authentication, the password must be protected during transmission; TLS is the preferred mechanism for this, but if it is not available then RSA public key encryption will be used. To specify the server’s RSA public key, use the ServerRSAPublicKeyFile connection string setting, or set AllowPublicKeyRetrieval=True to allow the client to automatically request the public key from the server. Note that AllowPublicKeyRetrieval=True could allow a malicious proxy to perform a MITM attack to get the plaintext password, so it is False by default and must be explicitly enabled. |
如果用户使用了 sha256_password 认证,密码在传输过程中必须使用 TLS 协议保护,但是如果 RSA 公钥不可用,可以使用服务器提供的公钥;可以在连接中通过 ServerRSAPublicKeyFile 指定服务器的 RSA 公钥,或者AllowPublicKeyRetrieval=True参数以允许客户端从服务器获取公钥;但是需要注意的是 AllowPublicKeyRetrieval=True可能会导致恶意的代理通过中间人攻击(MITM)获取到明文密码,所以默认是关闭的,必须显式开启.
四.解决方案
1.方案一
在url 后加 &allowPublicKeyRetrieval=true
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=root
如官方文档所述此方案有风险。
2.方案二
之前,MySQL的密码认证插件是“mysql_native_password”,而mysql5.8开始将caching_sha2_password作为默认的身份验证插件。因为当前有很多数据库工具和链接包都不支持“caching_sha2_password”,可以通过改回了“mysql_native_password”认证插件。
① 通过命令更改root用户的身份认证方式
ALTER USER ‘root’@‘localhost’ IDENTIFIED WITH mysql_native_password BY ‘你的密码’;
flush privileges;
② 修改配置文件 my.cnf
在/etc/my.cnf中把default-authentication-plugin=mysql_native_password前的#去掉;
[root@hecs-xxxxxx ~]# cat /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html
[mysqld]
#
......
default-authentication-plugin=mysql_native_password
service mysqld restart
重启mysql服务