在 Mysql 5.7 中更新用户密码

Update user password in Mysql 5.7

我写了一个安装脚本来使用这个 SQL 命令更改 root 密码:

UPDATE user SET password='*C563415623144561...' WHERE user='root';

这不适用于 Mysql 5.7: http://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-6.html#mysqld-5-7-6-account-management

我的问题是:如何将此命令更改为另一个兼容 5.6 和 5.7 版本 Mysql 的命令?我想用散列字符串而不是明文密码更新密码。

自 mysql 5.7 起,用户 table 中不再有密码字段。现在称为 authentication_string。您可以像这样更改或设置密码:

set password for 'jeff'@'localhost' = PASSWORD('mypass'); // this automatically hashes the password

如果您想使用您的查询,只需将 password 更改为 authentication_string,它就会起作用。

UPDATE user SET authentication_string='*C563415623144561...' WHERE user='root@localhost';

希望对您有所帮助。

首先查看您指定的mysql版本安全策略。

show variables like '%validate_password%';

如果您愿意,可以更改此政策

set variable_name=new_value;

正在更改适当的用户密码。

MySQL 5.7.5 及更早版本:

SET PASSWORD FOR 'user_name' = PASSWORD('new_password');

MySQL 5.7.6及以后版本:

alter user 'user_name' identified by 'new_password';

鉴于 'SET PASSWORD FOR = PASSWORD('')' 在 mysql 5.7 中已弃用。如果没有正确完成,您甚至可能会在系统日志中出现以下错误。

The plugin 'auth_socket' used to authenticate user 'root'@'localhost' is not loaded. Nobody can currently login using this account.

我建议使用下面的命令。

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mypass';

https://www.percona.com/blog/2016/03/16/change-user-password-in-mysql-5-7-with-plugin-auth_socket/

我在 Mysql 5.7.22

中使用此命令重置为空密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';

对于服务器版本:5.7.25 - MySQL 社区服务器 (GPL)。使用下面的查询,因为密码不再有效并被替换为 authentication_string

UPDATE user SET authentication_string = PASSWORD('yourpassword'), password_last_changed = NULL
WHERE user.Host = 'localhost' AND user.User = 'username';

我没有 MySQL 权限,但根据 MySQL 当前的 5.7 文档,我认为当前接受和最受支持的答案中的建议是不可取的。 (这可能是由于时间的推移——这个问题和@mdamia 的回答都是在 2015 年发布的。)

@Tobia 的问题链接的 MySQL 5.7.6 (2015-03-09, Milestone 16) release notes 说 "ALTER USER is now the preferred statement for assigning passwords."

这个问题确实询问了一个命令是否可以同时用于 MySQL 5.6 和 5.7,但是考虑到 MySQL >= 5.7.6 提供的 ALTER USER 语法提供安全性增强,我会在可用时使用更新的语法。如果我仍然必须运行 MySQL < 5.7.6 安装,我会限制在这些情况下使用旧的和 deprecated/discouraged password-updating 语法。

@Carlos Alberto García Guardia 和@Venkat Kotra 在他们的回答中建议的 ALTER USER 语句在我看来是用于 MySQL >= 5.7.6 的正确语法。两个例子(改编自他们的答案和 ALTER USER documentation for MySQL 5.7)::

ALTER USER '<username>'@'localhost'
  IDENTIFIED BY '<new_cleartext_password>';

ALTER USER '<username>'@'localhost'
  IDENTIFIED WITH <auth_plugin>
  BY '<new_cleartext_password>';

上面的第二个示例包含一个可选的 WITH 子句来指定 authentication plugin。指定的插件被写入 mysql.user table 的 "plugin" 字段。对于 MySQL 身份验证插件的历史和未来背景,我发现这些 MySQL 服务器团队博客帖子很有帮助:

  1. "Protecting MySQL Passwords With the sha256_password Plugin"

  2. "New Default Authentication Plugin: caching_sha2_password"

在回答@Tobia 关于如何以散列格式而不是明文形式将新密码传递给 MySQL 的问题时,MySQL ALTER USER 文档表明这是通过使用 AS 代替 ALTER USER 语句中的 BY

ALTER USER '<username>'@'localhost'
  IDENTIFIED WITH <auth_plugin>
  AS '<new_hashed_password_value>';

当使用 AS 而不是 BYALTER USER documentation says、密码字符串时 "is assumed to be already in the format the authentication plugin requires, and is stored as is in the mysql.user table." 如果插件需要散列值,"the value must be hashed in a format appropriate for the plugin. Otherwise, the value is not usable by the plugin and correct authentication of client connections will not occur." Id.


当前接受的答案建议使用 SET PASSWORD ... PASSWORD() 语句或 UPDATE 语句(前者以明文形式传递新密码,后者以散列格式传递):

SET PASSWORD 
  FOR '<username>'@'localhost' = 
  PASSWORD('<mypass_in_cleartext>');

UPDATE mysql.user
  SET authentication_string='<mypass_as_hash>'
  WHERE User='<username>';

与当前首选的 ALTER USER 语句相比,这些语句已弃用 and/or 不鼓励。

SET PASSWORD ... = PASSWORD(<cleartext>)"is deprecated as of MySQL 5.7.6 and will be removed in a future MySQL release",根据the SET PASSWORD documentation.

SET PASSWORD ... = 'auth_string'语法(,省略了PASSWORD(str)加密函数)"is not deprecated, but ALTER USER is the preferred statement for account alterations, including assigning passwords."Id. See also Removal and Deprecation in MySQL 5.7:

We have deprecated the SET PASSWORD syntax and the PASSWORD() function. The existing ALTER USER statement is modified to cover the deprecated functionality. The PASSWORD() function was originally introduced as a way to manually update the mysql.user table. This is generally a bad idea and we want to leave the task of managing user authentication properties exclusively to using the ALTER USER statement which automatically determines which authentication plugin should be used and then adjusts the password algorithm accordingly.

如手册所述,在日志记录方面,UPDATE 似乎不如 ALTER PASSWORD 安全。手册指出 UPDATE 语句按原样写入日志,任何对日志具有读取权限的人都可以看到。[1]相反,手册指出,当 MySQL 将 ALTER USER ... IDENTIFIED BY ... 语句(以及 SET PASSWORD 语句)写入日志时,它会重写包含的密码,因此它们会 "not appear literally"。[1]

至少在大多数情况下。 SET PASSWORDALTER USER 的文档警告说,这些语句也可以使用可见密码 "under some circumstances"、[2] 进行记录,尽管可能并非在所有情况下都如此 UPDATE.

1:参见 MySQL 5.7 manual on password logging ("In particular, INSERT or UPDATE statements for the mysql.user system table that refer to literal passwords are logged as is, so you should avoid such statements. (Direct modification of grant tables is discouraged, anyway.)")

2:见MySQL 5.7 SET PASSWORD documentation and MySQL 5.7 ALTER USER documentation


免责声明:我只是分享我今天阅读 MySQL 手册后的理解。我还没有测试 MySQL 关于它以什么格式记录什么 password-altering 语句的行为。

在 Ubuntu 19.10 和 mysqld 版本 8.0.19 上,上述 none 对我有用。此处给出的说明 https://linuxconfig.org/how-to-reset-root-mysql-mariadb-password-on-ubuntu-20-04-focal-fossa-linux 有效。是针对MariaDB的,不使用MariaDB也是一样的。两个关键点是:函数 password() 在 mysqld 8.0+ 中被删除,并且由于某种原因,mysqld 的 unix 套接字不是使用 --skip-grant-tables 创建的选项。因此,您必须使用这些修改后的指令:

$ sudo systemctl stop mysql
$ sudo mkdir -p /var/run/mysqld
$ sudo chown mysql:mysql /var/run/mysqld
$ sudo /usr/sbin/mysqld --skip-grant-tables --skip-networking &

检查守护进程 mysqld 是 运行:

$ ps aux | grep mysqld

如果是运行,则启动mysql并修改密码

$ mysql -u root

> FLUSH PRIVILEGES;
> USE mysql; 
> ALTER USER 'root'@'localhost' IDENTIFIED BY 'N3w_p@ssw0rD.';
> quit

重要提示:在您(重新)启动 mysqld 之前,您需要终止当前进程。仅以正常方式停止它是行不通的。

$ sudo pkill mysqld
$ sudo systemctl start mysql

那你可以测试一下:

$ mysql -u root --password='N3w_p@ssw0rD.'

这是对我来说唯一的方法:mysql Ver 14.14 Distrib 5.7.30

UPDATE user SET authentication_string = PASSWORD('YourPassword'), password_last_changed = NULL
WHERE user.Host = 'localhost' AND user.User = 'YourUsername';