【问题标题】:Update user password in Mysql 5.7在 Mysql 5.7 中更新用户密码
【发布时间】:2015-11-19 09:26:48
【问题描述】:

我写了一个安装脚本,用这个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 的命令?我想使用散列字符串而不是明文密码来更新密码。

【问题讨论】:

    标签: authentication root mysql-5.7


    【解决方案1】:

    从 mysql 5.7 开始,用户表中不再有密码字段。它现在称为 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';
    

    希望对您有所帮助。

    【讨论】:

    • 好的,谢谢 mdamia,但是有没有办法同时使用 mysql 5.7 和 5.6?我想使用一个独特的脚本来安装...可以吗?
    • @Tobia,没问题,我不是一个很好的脚本,但我认为你可以使用这样的东西来获取 mysql 的版本 dpkg -l | grep mysql-server* 然后你可以使用正则表达式来获取 mysql 的版本和根据正则表达式结果执行脚本。
    • 我必须运行“FLUSH PRIVILEGES;”在更新的密码生效之前。
    • FLUSH PRIVILEGES 给出“用于验证用户 'root'@'localhost' 的插件 'auth_socket' 未加载。目前没有人可以使用此帐户登录。”每次运行时都在 /var/log/mysql/error.log 文件中。所以它实际上不起作用......
    【解决方案2】:

    首先看你指定的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';
    

    【讨论】:

    • 使用 MySQL 5.7.16ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'%'
    【解决方案3】:

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

    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/

    【讨论】:

      【解决方案4】:

      我在 Mysql 5.7.22 中使用此命令重置为空密码

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

      【讨论】:

      • 谢谢,这似乎是 5.7.22 的唯一方法
      • 是的,但它在 mysql 安全、skip-grant-tables 模式下不起作用 - 没有办法重置它吗? ERROR 1290 (HY000): MySQL 服务器使用 --skip-grant-tables 选项运行,因此无法执行此语句
      • 使用 mysqld_safe --skip-grant-tables 然后 FLUSH PRIVILEGES 前后似乎可以做到这一点。
      【解决方案5】:

      对于服务器版本: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';
      

      【讨论】:

        【解决方案6】:

        我不是 MySQL 权威,但根据 MySQL 当前的 5.7 文档,当前接受且最受好评的答案中的建议让我觉得不明智。 (这可能是由于时间的流逝——问题和@mdamia 的答案都是在 2015 年发布的。)

        @Tobia 的问题链接的MySQL 5.7.6 (2015-03-09, Milestone 16) release notes 说“ALTER USER 现在是分配密码的首选语句。”

        这个问题确实询问了一个命令是否可以同时用于 MySQL 5.6 和 5.7,但鉴于 MySQL >= 5.7.6 实现的 ALTER USER 语法提供了安全性增强,我会在它的时候使用更新的语法可用。如果我仍然必须操作 MySQL

        @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 表的“插件”字段。对于 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 代替 @987654341 中的 BY 来完成的@声明:

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

        当使用AS 而不是BYALTER USER documentation says 时,密码字符串“假定已采用身份验证插件所需的格式,并按原样存储在 mysql.user 表中。”如果插件需要散列值,“该值必须以适合插件的格式进行散列。否则,插件无法使用该值,并且不会发生客户端连接的正确身份验证。” 身份证。


        当前接受的答案建议使用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 语句相比,这些语句已被弃用和/或不鼓励。

        SET PASSWORD ... = PASSWORD(&lt;cleartext&gt;)“自 MySQL 5.7.6 起已弃用,并将在未来的 MySQL 版本中删除”,根据the SET PASSWORD documentation

        SET PASSWORD ... = 'auth_string' 语法(,省略了PASSWORD(str) 加密函数)“未被弃用,但 ALTER USER 是帐户更改的首选语句,包括分配密码。” Id. 另见 Removal and Deprecation in MySQL 5.7:

        我们已弃用 SET PASSWORD 语法和 PASSWORD() 函数。修改了现有的 ALTER USER 语句以涵盖已弃用的功能。 PASSWORD() 函数最初是作为手动更新 mysql.user 表的一种方式引入的。这通常是一个坏主意,我们希望将管理用户身份验证属性的任务专门留给使用 ALTER USER 语句,该语句自动确定应该使用哪个身份验证插件,然后相应地调整密码算法。

        如手册所述,UPDATE 在日志记录方面似乎不如ALTER PASSWORD 安全。该手册指出UPDATE 语句按原样写入日志,对具有日志读取权限的任何人都可见。 [1]相比之下,手册指出,当 MySQL 将 ALTER USER ... IDENTIFIED BY ... 语句(以及 SET PASSWORD 语句)写入日志时,它会重写包含的密码,因此它们不会“按字面意思显示”。 [1]

        至少在大多数情况下。 SET PASSWORDALTER USER 的文档警告说,“在某些情况下”[2] 也可以使用可见密码记录这些语句,尽管可能并非在所有情况下都像 UPDATE 那样明显。

        1:参见MySQL 5.7 manual on password logging(“特别是,mysql.user 系统表中引用文字密码的 INSERT 或 UPDATE 语句按原样记录,因此您应该避免此类语句。(不鼓励直接修改授权表,无论如何。)”)

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


        免责声明:我只是在今天阅读 MySQL 手册后分享我的解释。我还没有测试 MySQL 以何种格式记录哪些密码更改语句的行为。

        【讨论】:

          【解决方案7】:

          在带有 mysqld 版本 8.0.19 的 Ubuntu 19.10 上,上述方法都不适合我。 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.'
          

          【讨论】:

            【解决方案8】:

            这是我唯一的方法: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';
            

            【讨论】:

              猜你喜欢
              • 2017-07-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-02-12
              • 1970-01-01
              • 2016-04-27
              • 1970-01-01
              相关资源
              最近更新 更多