暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL 8.0 新特性----账户/安全相关

数据库知多少 2021-04-26
1162

MySQL 8.0 新特性----账户/安全相关

在MySQL数据库8.0的新特性中增加了账户和安全方面的内容,用户管理中新增了角色,默认的密码加密方式也由之前的sha1改为了sha2。并且新增了操作系统认证机制,管理数据库更方便了。我们来通过实验来看一看吧。


数据库信息

Current user: root@localhost

SSL:         Not in use

Server version: 8.0.18 MySQL Community Server - GPL

Protocol version: 10

Connection:  Localhost via UNIX socket

1:用户及角色


MYSQL用户管理

    1.1 用户的创建、授权在8.0中发生了改变

        在5.7版本数据库中:

        通过grant语句可以正常创建用户;

    root@localhost [(none)]> grant all privileges on *.* to mysql@'localhost' identified by 'mysql1234';
    Query OK, 0 rows affected, 2 warnings (0.00 sec)
    root@localhost [(none)]> 
    复制

           我们看下warnings是什么:

      root@localhost [(none)]> show warnings;
      +---------+------+------------------------------------------------------------------------------------------------------------------------------------+
      | Level | Code | Message |
      +---------+------+------------------------------------------------------------------------------------------------------------------------------------+
      | Warning | 1285 | MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work |
      | Warning | 1287 | Using GRANT for creating new user is deprecated and will be removed in future release. Create new user with CREATE USER statement. |
      +---------+------+------------------------------------------------------------------------------------------------------------------------------------+
      2 rows in set (0.00 sec)
      复制

              5.7版本中通过warning的方式告知我们以后的版本中grant方式来创建新用户的方式会被废弃掉,建议使用create user的方式。


               在8.0 版本数据库中:        

        root@localhost [(none)]> grant all privileges on *.* to test@'localhost' identified by 'mysql12341234';
        ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by 'mysql12341234'' at line 1
        复制

                   啊哦,直接报错了。看来以前的grant创建用户的方式是被废弃掉了。

        在8.0中,创建用户需要分别用两条语句来完成:

          root@localhost [(none)]> create user test@'localhost' identified by 'mysql12341234';
          Query OK, 0 rows affected (0.00 sec)
          root@localhost [(none)]> 


          root@localhost [(none)]> grant all privileges on *.* to test@'localhost';
          Query OK, 0 rows affected, 1 warning (0.01 sec)
          复制

                  回收权限

            root@localhost [(none)]> revoke all privileges on *.*  from test@'localhost';
            Query OK, 0 rows affected (0.00 sec)
            复制

                    再次查看权限:

              root@localhost [(none)]> show grants for test@'localhost';
              +------------------------------------------+
              | Grants for test@localhost |
              +------------------------------------------+
              | GRANT USAGE ON *.* TO `test`@`localhost` |
              +------------------------------------------+
              1 row in set (0.00 sec)
              复制

                      之前授予的权限已经被回收掉了;

              2:安全加密


              1.2 用户密码的加密

                      在MySQL8.0中,默认的身份认证插件也由mysql_native_password改为了caching_sha2_password,且默认的加密方式是sha2.

                root@localhost [(none)]> select user,host,plugin from mysql.user;
                +------------------+-----------+-----------------------+
                | user | host | plugin |
                +------------------+-----------+-----------------------+
                | mysql.infoschema | localhost | caching_sha2_password |
                | mysql.session | localhost | caching_sha2_password |
                | mysql.sys | localhost | caching_sha2_password |
                | root | localhost | mysql_native_password |
                | test | localhost | mysql_native_password |
                +------------------+-----------+-----------------------+
                5 rows in set (0.00 sec)
                复制

                        root用户和test用户的认证插件是进行过调整,使用的还是之前老的认证插件,mysql.infoschema 和mysql.session、mysql.sys都是系统默认创建的,用户的认证插件都是caching_sha2_password 。

                            如果将8.0已有的sha2密码修改为sha1的模式,有两种方法可以实现:

                方法1: 创建/修改用户的时候指定认证插件

                  root@localhost [(none)]> ALTER USER 'test'@'localhost' IDENTIFIED WITH mysql_native_password by 'mysql1234';
                  Query OK, 0 rows affected (0.01 sec)
                  复制

                  方法2:调整配置文件my.cnf

                    [mysql@Tdongkf base8018]$ cat mysql/my3307/my.cnf |grep pass
                    default_authentication_plugin = mysql_native_password
                    [mysql@Tdongkf base8018]$


                    root@localhost [(none)]> show variables like 'default_authentication_plugin%';
                    +-------------------------------+-----------------------+
                    | Variable_name | Value |
                    +-------------------------------+-----------------------+
                    | default_authentication_plugin | mysql_native_password |
                    +-------------------------------+-----------------------+
                    1 row in set (0.00 sec)
                    复制

                    这样,创建用户的时候默认就是使用mysql_native_password认证插件了。

                    但是,建议在8.0中使用caching_sha2_password 认证协议,caching_sha2_password 实现SHA-256密码散列,但使用缓存来解决连接时的延迟问题。 它还支持更多连接协议,并且不需要针对基于RSA密钥对的密码交换功能进行OpenSSL连接。并且提供比mysql_native_password更安全的密码加密和更好的性能。


                    1.3 用户密码的过期时间

                            在mysql5.7或8.0版本中,是禁用自动密码过期的。

                            可以通过如下命令来查看:

                      +---------------------------+-------+
                      | Variable_name | Value |
                      +---------------------------+-------+
                      | default_password_lifetime | 0 |
                      +---------------------------+-------+
                      1 row in set (0.00 sec)
                      复制

                              如果值default_password_lifetime正整数N,则表示允许的密码的过期要求,则密码必须每N天进行更改。这个参数是可以动态设置并保存的

                              MySQL允许限制重复使用以前的密码。可以根据密码更改次数、已用时间或两者来建立重用限制。账户的密码历史由过去分配的密码组成。要全局建立密码重用策略,请使用password_history和password_reuse_interval系统变量。


                      3:角色


                      1.4 用户角色

                              角色是一组权限的集合。像用户帐户一样,角色可以拥有授予和撤销的权限,可以授予给用户帐户角色,即授予该帐户与每个角色相关的权限。用户被授予角色权限后,该用户拥有该角色所有的权限。

                      MySQL提供的角色管理功能

                      • CREATE ROLE、DROP ROLE      角色创建和删除;

                      • GRANT、 REVOKE                     用户和角色分配和撤销权限;

                      • SHOW GRANTS                         显示用户和角色的权限和角色分配;

                      • SET DEFAULT ROLE                   指定哪些帐户角色默认处于活动状态;

                      • SET ROLE                                   更改当前会话中的活动角色。

                      • CURRENT_ROLE()                      显示当前会话中的活动角色。

                              创建角色,请使用CREATE ROLE:

                        root@localhost [(none)]> create role app_read,app_write;
                        Query OK, 0 rows affected (0.01 sec)


                        root@localhost [mysql]> select user,host from mysql.user;
                        +------------------+-----------+
                        | user | host |
                        +------------------+-----------+
                        | app_read | % |
                        | app_write | % |
                        | mysql.infoschema | localhost |
                        | mysql.session | localhost |
                        | mysql.sys | localhost |
                        | root | localhost |
                        | test | localhost |
                        +------------------+-----------+
                        7 rows in set (0.00 sec)
                        复制

                                为角色分配权限,使用与用户分配权限相同的语法执行:

                          root@localhost [mysql]> grant create on mysql.* to app_read;
                          Query OK, 0 rows affected (0.01 sec)


                          root@localhost [mysql]> show grants for app_read;
                          +---------------------------------------------+
                          | Grants for app_read@% |
                          +---------------------------------------------+
                          | GRANT USAGE ON *.* TO `app_read`@`%` |
                          | GRANT CREATE ON `mysql`.* TO `app_read`@`%` |
                          +---------------------------------------------+
                          2 rows in set (0.00 sec)
                          复制

                                  撤消角色或角色权限

                            正如可以授权某个用户的角色一样,可以从账户中撤销这些角色:

                            root@localhost [mysql]> revoke  create on mysql.*  from app_read;
                            Query OK, 0 rows affected (0.00 sec)


                            root@localhost [mysql]> show grants for app_read;
                            +--------------------------------------+
                            | Grants for app_read@% |
                            +--------------------------------------+
                            | GRANT USAGE ON *.* TO `app_read`@`%` |
                            +--------------------------------------+
                            1 row in set (0.00 sec)
                            复制

                              REVOKE可以用于角色修改角色权限。这不仅影响角色本身权限,还影响任何授予该角色的用户权限。从角色中撤销权限会影响到该角色中任何用户的权限

                                  删除角色

                              要删除角色,请使用DROP ROLE:

                              root@localhost [mysql]> drop role app_read,app_write;
                              Query OK, 0 rows affected (0.00 sec)
                              复制

                                删除角色会从授权它的每个帐户中撤销该角色。

                              4:基于操作系统的认证


                                      最后我们来谈谈操作系统认证:

                              在ORACLE、SQL Server等商业数据库中,都提供了两种认证方式:一种是操作系统身份认证,另一种是数据库身份认证。在最新的MySQL8.0版本中,MySQL也引入了操作系统身份认证。也是基于插件进行的验证。

                              安装插件:

                                root@localhost [mysql]> install plugin auth_socket SONAME 'auth_socket.so';
                                Query OK, 0 rows affected (0.00 sec)
                                复制

                                    创建数据库用户,必须为localhost

                                  root@localhost [(none)]> create user test@'localhost' identified with auth_socket;
                                  Query OK, 0 rows affected (0.00 sec)
                                  复制

                                      创建一个同名的操作系统用户

                                    [root@Tdongkf ~]#  useradd test
                                    复制

                                        切换到test用户,直接登录即可,不用输入密码

                                      [root@Tdongkf ~]# su - test
                                      Last login: Wed Feb 3 16:34:03 CST 2021 on pts/0
                                      [test@Tdongkf ~]$ mysql -utest --socket=/mysql/my3307/mysql.sock
                                      Welcome to the MySQL monitor. Commands end with ; or \g.
                                      Your MySQL connection id is 23
                                      Server version: 8.0.18 MySQL Community Server - GPL


                                      Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.


                                      Oracle is a registered trademark of Oracle Corporation and/or its
                                      affiliates. Other names may be trademarks of their respective
                                      owners.
                                      Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


                                      test@localhost [(none)]> select user();
                                      +----------------+
                                      | user() |
                                      +----------------+
                                      | test@localhost |
                                      +----------------+
                                      1 row in set (0.00 sec)
                                      test@localhost [(none)]>
                                      复制

                                          哈哈,终于不用密码就可以直接登录数据库了。

                                          在其它用户下试试:

                                        [mysql@Tdongkf ~]$ mysql -utest --socket=/mysql/my3307/mysql.sock
                                        ERROR 1698 (28000): Access denied for user 'test'@'localhost'
                                        [mysql@Tdongkf ~]$ 
                                        复制

                                            报错了,看来不行。

                                            如果我们希望操作系统用户和数据库用户不一样呢?可以手动指定操作系统用户

                                          root@localhost [(none)]> alter user test@'localhost' identified with auth_socket as 'mysql';
                                          Query OK, 0 rows affected (0.00 sec)
                                          复制

                                              再次用mysql用户登录试试:

                                            [mysql@Tdongkf ~]$ id
                                            uid=510(mysql) gid=510(mysql) groups=510(mysql)
                                            [mysql@Tdongkf ~]$ mysql -utest --socket=/mysql/my3307/mysql.sock
                                            Welcome to the MySQL monitor. Commands end with ; or \g.
                                            Your MySQL connection id is 27
                                            Server version: 8.0.18 MySQL Community Server - GPL


                                            Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.


                                            Oracle is a registered trademark of Oracle Corporation and/or its
                                            affiliates. Other names may be trademarks of their respective
                                            owners.


                                            Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


                                            test@localhost [(none)]> 
                                            复制

                                                mysql操作系统用户可以正常登录了,解决了操作系统用户和登录数据库的用户不一致的问题。


                                            总结,MySQL通过操作系统认证、系统用户与普通用户的分类、权限新增、角色引入等,实现了用户管理的多样化和精细化,可以更好地实现权限分离。

                                            =end=



                                            文章转载自数据库知多少,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                            评论