数据库的访问权限控制很重要,尤其是在远程访问控制的时候,一般情况下只给出查看权限,其他的都不给,结合访问ip白名单的控制,可以有效防止恶意修改数据甚至删除数据。本文简单描述下权限的赋予和撤销,并做简单的测试强化理解。
熟悉mysql
的同学应该也都知道MariaDB
,他们是孪生兄弟,由于mysql
被oracle
收购,作者担心被闭源,故创作了mysql
的分支:MariaDB
,不过,MariaDB
绝对不是MySQL
的简单替代品,相对于MySQL
,其有更多新选项、扩展、存储引擎及漏洞修复。目前开源的CentOS7
已经换成了MariaDB
。如果用户需要在CentOS7
上安装MySQL
需要先将MariaDB
卸载掉,否则就会导致安装冲突。他两的api
都是一样的,所以没有额外学习的成本,本文以MariaDB
为例学习下数据库的权限操作。使用的版本是Server version: 10.5.5-MariaDB MariaDB Server
。
MariaDB
名称来自麦克尔·维德纽斯的女儿玛丽亚(英语:Maria
)的名字。
赋予权限
权限操作的关键字是grant
。
MariaDB [mysql]> grant select,insert on *.* to test@'114.221.179.3' identified by 'test';
Query OK, 0 rows affected (0.008 sec)
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.001 sec)
MariaDB [mysql]> show grants for test@'114.221.179.3';
+--------------------------------------------------------------------------------------------------------------------------+
| Grants for test@114.221.179.3 |
+--------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `test`@`114.221.179.3` IDENTIFIED BY PASSWORD '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' |
+--------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
我这里新建一个用户叫做test
,设定只能是114.221.179.3
这个ip才能远程访问这个数据库,且对*.*
表示所有database
下的所有表都生效。(注意,在执行grant
前我并没有去新建用户,这个命令一句就把创建用户和赋予权限都搞定了。)
如果只对单个database
生效:
grant select on testdb.* to test@localhost;
如果是对单个数据库的单张表生效:
grant select, insert, update, delete on testdb.orders to test@localhost;
最后密码也是test
。此外,我只给了查询权限和插入权限,而更新权限、删除权限等都没有给,当然了,类似于create
、drop
、truncate
自然就更不可能了。
这里看到,针对不同的ip
是可以设定不同的权限的,比如我再对test
用户针对localhost
访问的时候赋予所有权限:
MariaDB [mysql]> grant all on *.* to test@'localhost' identified by 'test';
Query OK, 0 rows affected (0.002 sec)
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.000 sec)
这个时候权限就变成了:
MariaDB [mysql]> show grants for test@'114.221.179.3';
+--------------------------------------------------------------------------------------------------------------------------+
| Grants for test@114.221.179.3 |
+--------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `test`@`114.221.179.3` IDENTIFIED BY PASSWORD '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' |
+--------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
MariaDB [mysql]> show grants for test@localhost;
+----------------------------------------------------------------------------------------------------------------------+
| Grants for test@localhost |
+----------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO `test`@`localhost` IDENTIFIED BY PASSWORD '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' |
+----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
这个时候我就可以在服务器上通过这个用户密码进行登录,验证下是不是权限都可以:
这里就以update
为例了,可以看到,针对来自本地ip的操作是允许的,这样的话就比较方便了,我远程用户跟本地用户可以设置成一样的,只是远程用户可能只有查看权限,而本地用户是有全部权限的。
注意,grant
、revoke
用户权限后,该用户只有重新连接 MySQL
数据库,权限才能生效。
此外,grant
是可以多次执行的,即可以叠加权限。
撤销权限
MariaDB [mysql]> revoke all on *.* from test@'114.221.179.3';
Query OK, 0 rows affected (0.002 sec)
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.000 sec)
MariaDB [mysql]> show grants for test@'114.221.179.3';
+-----------------------------------------------------------------------------------------------------------------+
| Grants for test@114.221.179.3 |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`114.221.179.3` IDENTIFIED BY PASSWORD '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' |
+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
usage
权限(默认授予),该权限只能用于数据库登陆,不能执行任何操作;且usage
权限不能被回收,也即REVOKE
用户并不能删除用户。
要向删除此用户,可以用delete
:
MariaDB [mysql]> select * from user where user='test';
+---------------+------+-------------------------------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+---------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+---------+--------------+--------------------+
| Host | User | Password | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Show_db_priv | Super_priv | Create_tmp_table_priv | Lock_tables_priv | Execute_priv | Repl_slave_priv | Repl_client_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Create_user_priv | Event_priv | Trigger_priv | Create_tablespace_priv | Delete_history_priv | ssl_type | ssl_cipher | x509_issuer | x509_subject | max_questions | max_updates | max_connections | max_user_connections | plugin | authentication_string | password_expired | is_role | default_role | max_statement_time |
+---------------+------+-------------------------------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+---------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+---------+--------------+--------------------+
| 114.221.179.3 | test | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | | | | | 0 | 0 | 0 | 0 | mysql_native_password | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | N | N | | 0.000000 |
+---------------+------+-------------------------------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+---------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+---------+--------------+--------------------+
1 row in set (0.001 sec)
MariaDB [mysql]> delete from user where user='test' and host='114.221.179.3';
Query OK, 1 row affected (0.002 sec)
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.000 sec)
这样的话,用户就会被删除,那么我们就无法通过test
用户远程连接数据库了。
实际上,使用grant授权实质是在mysql数据库的user表中增加一列,收回权限实质是从表中删除一列。所以授权也可以替换为删除表数据来代替,授权撤权实质是操作mysql的user表。
可以看到,所有的权限都在这张表里面。我们可以再看下test
用户只有查看和删除权限的模样:
因此,我们可以通过这个方式查看某个用户相关的权限!本文完。