0x00 问题起因
为了方便操作数据库,我部署了 phpMyAdmin。但在使用 root 用户登录的时候,却提示:
mysqli_real_connect(): (hy000/1698): access denied for user ‘root’@’localhost’
0x01 解决方案
在检索了相关文章和资料后,了解到 MySQL 5.7+ 的版本,由于在安全机制上有一定的改动,因此默认情况下,命令行需要使用 sudo
来登录 root 用户。
StackExchange 上,用户 Rael Gugelmin Cunha 提供了一种解决方案,思路是:创建一个赋予了足够权限的新用户。1
具体步骤如下:
1、创建用户,并使用密码认证:
1 | CREATE USER 'new_user'@'localhost' IDENTIFIED BY 'your_password'; |
2、赋予权限
1 | GRANT ALL PRIVILEGES ON *.* TO 'new_user'@'localhost' WITH GRANT OPTION; |
但是我觉得 WITH GRANT OPTION
可有可无。
3、刷新权限
1 | FLUSH PRIVILEGES; |
0x02 新的问题
创建用户后,我成功地使用新用户,通过 phpMyAdmin 登录了数据库。然而,同时我却发现,root 用户也能登录了。
为什么创建了新用户后,root 用户也能登录了?
0x03 MySQL 安全组件和插件
我开始摸索,MySQL 5.7+ 版本的 root 用户的安全机制上,到底在哪里出现了变动。
1. Socket Peer-Credential Authentication
同样是在 StackExchange 上,用户 Todor 提到:
If you install 5.7 and don’t provide a password to the
root
user, it will use theauth_socket
plugin. That plugin doesn’t care and doesn’t need a password. It just checks if the user is connecting using a UNIX socket and then compares the username.2
在没有给 root 用户设置新密码前,root 用户默认使用 auth_socket
安全插件3。auth_socket
通过检查当前用户是否使用 UNIX socket 并比较用户名来进行认证。
在 user
表中,就记录有相关的信息:
1 | MariaDB [(none)]> select user,host,plugin from mysql.user; |
换言之,对于我当前的 root 用户登录数据库,如果使用 unix_socket
安全插件,那就只需要:
1 | sudo mysql |
2. Native Authentication
在此之前,我都是使用 mysql_native_password
这种较为传统的方式。
而且平时,我习惯在 MySQL 环境中使用 SET PASSWORD
命令修改密码:
1 | SET PASSWORD for root@localhost = password('new_password') |
在执行完命令后,用户相应的 plugin
就会变成 mysql_native_password
,并在 FLUSH PRIVILEGES
后生效。
0x04 为什么之前没有发现
想来想去,应该就是自己当时在**修改了 root 密码之后,没有及时 FLUSH PRIVILEGES
**,且平时一直在用 sudo mysql -u root -p
登录数据库,所以没有意识到这些问题。
0x05 另外的解决方案
所以,除了创建新用户之外,把用户的安全认证方式从 UNIX_socket
修改成 mysql_native_password
也是一种办法。
因此可以通过一行命令来实现:
1 | ALTER USER 'root'@'localhost' IDENTIFIED BY 'your_password'; |
当然,这种情况下,也可以设置一个空密码。如果修改 root 用户时,提示权限不足,可检查下是否是 sudo mysql
登录的。
参考链接
[1] askubuntu, Cannot enter phpmyadmin as root (MySQL 5.7)
[2] askubuntu, can’t login as mysql user root from normal user account in ubuntu 16.04
[3] Oracle, MySQL 8.0 Reference Manual