MySQL之权限管理
一、MySQL权限简介
关于mysql的权限简单的理解就是mysql允许你做你全力以内的事情,不可以越界。比如只允许你执行select操作,那么你就不能执行update操作。只允许你从某台机器上连接mysql,那么你就不能从除那台机器以外的其他机器连接mysql。
那么Mysql的权限是如何实现的呢?这就要说到mysql的两阶段验证,下面详细介绍:第一阶段:服务器首先会检查你是否允许连接。因为创建用户的时候会加上主机限制,可以限制成本地、某个IP、某个IP段、以及任何地方等,只允许你从配置的指定地方登陆。第二阶段:如果你能连接,Mysql会检查你发出的每个请求,看你是否有足够的权限实施它。比如你要更新某个表、或者查询某个表,Mysql会查看你对哪个表或者某个列是否有权限。再比如,你要运行某个存储过程,Mysql会检查你对存储过程是否有执行权限等。
MYSQL到底都有哪些权限呢?从官网复制一个表来看看:
权限 |
权限级别 |
权限说明 |
CREATE |
数据库、表或索引 |
创建数据库、表或索引权限 |
DROP |
数据库或表 |
删除数据库或表权限 |
GRANT OPTION |
数据库、表或保存的程序 |
赋予权限选项 |
REFERENCES |
数据库或表 |
|
ALTER |
表 |
更改表,比如添加字段、索引等 |
DELETE |
表 |
删除数据权限 |
INDEX |
表 |
索引权限 |
INSERT |
表 |
插入权限 |
SELECT |
表 |
查询权限 |
UPDATE |
表 |
更新权限 |
CREATE VIEW |
视图 |
创建视图权限 |
SHOW VIEW |
视图 |
查看视图权限 |
ALTER ROUTINE |
存储过程 |
更改存储过程权限 |
CREATE ROUTINE |
存储过程 |
创建存储过程权限 |
EXECUTE |
存储过程 |
执行存储过程权限 |
FILE |
服务器主机上的文件访问 |
文件访问权限 |
CREATE TEMPORARY TABLES |
服务器管理 |
创建临时表权限 |
LOCK TABLES |
服务器管理 |
锁表权限 |
CREATE USER |
服务器管理 |
创建用户权限 |
PROCESS |
服务器管理 |
查看进程权限 |
RELOAD |
服务器管理 |
执行flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh, reload等命令的权限 |
REPLICATION CLIENT |
服务器管理 |
复制权限 |
REPLICATION SLAVE |
服务器管理 |
复制权限 |
SHOW DATABASES |
服务器管理 |
查看数据库权限 |
SHUTDOWN |
服务器管理 |
关闭数据库权限 |
SUPER |
服务器管理 |
执行kill线程权限 |
MYSQL的权限如何分布,就是针对表可以设置什么权限,针对列可以设置什么权限等等,这个可以从官方文档中的一个表来说明:
权限分布 |
可能的设置的权限 |
表权限 |
'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter' |
列权限 |
'Select', 'Insert', 'Update', 'References' |
过程权限 |
'Execute', 'Alter Routine', 'Grant' |
二、MySQL权限经验原则:
权限控制主要是出于安全因素,因此需要遵循一下几个经验原则:
1、只授予能满足需要的最小权限,防止用户干坏事。比如用户只是需要查询,那就只给select权限就可以了,不要给用户赋予update、insert或者delete权限。
2、创建用户的时候限制用户的登录主机,一般是限制成指定IP或者内网IP段。
3、初始化数据库的时候删除没有密码的用户。安装完数据库的时候会自动创建一些用户,这些用户默认没有密码。
4、为每个用户设置满足密码复杂度的密码。
5、定期清理不需要的用户。回收权限或者删除用户。
三、MySQL权限实战:
1、GRANT命令使用说明:
先来看一个例子,创建一个只允许从本地登录的超级用户jack,并允许将权限赋予别的用户,密码为:jack.
mysql> grant all privileges on *.* to jack@'localhost' identified by "jack" with grant option; Query OK, 0 rows affected (0.01 sec)
GRANT命令说明:
ALL PRIVILEGES 是表示所有权限,你也可以使用select、update等权限。
ON 用来指定权限针对哪些库和表。
*.* 中前面的*号用来指定数据库名,后面的*号用来指定表名。
TO 表示将权限赋予某个用户。
jack@'localhost' 表示jack用户,@后面接限制的主机,可以是IP、IP段、域名以及%,%表示任何地方。注意:这里%有的版本不包括本地,以前碰到过给某个用户设置了%允许任何地方登录,但是在本地登录不了,这个和版本有关系,遇到这个问题再加一个localhost的用户就可以了。
IDENTIFIED BY 指定用户的登录密码。
WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人。注意:经常有人在创建操作用户的时候不指定WITH GRANT OPTION选项导致后来该用户不能使用GRANT命令创建用户或者给其它用户授权。
备注:可以使用GRANT重复给用户添加权限,权限叠加,比如你先给用户添加一个select权限,然后又给用户添加一个insert权限,那么该用户就同时拥有了select和insert权限。
2、刷新权限
使用这个命令使权限生效,尤其是你对那些权限表user、db、host等做了update或者delete更新的时候。以前遇到过使用grant后权限没有更新的情况,只要对权限做了更改就使用FLUSH PRIVILEGES命令来刷新权限。
mysql> flush privileges; Query OK, 0 rows affected (0.01 sec)
3、查看权限
查看当前用户的权限:
mysql> show grants;
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
rows in set (0.00 sec)
查看某个用户的权限:
mysql> show grants for 'jack'@'%';
+-----------------------------------------------------------------------------------------------------+
| Grants for jack@% |
+-----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'jack'@'%' IDENTIFIED BY PASSWORD '*9BCDC990E611B8D852EFAF1E3919AB6AC8C8A9F0' |
+-----------------------------------------------------------------------------------------------------+
row in set (0.00 sec)
4、回收权限
mysql> revoke delete on *.* from 'jack'@'localhost'; Query OK, 0 rows affected (0.01 sec)
5、删除用户
mysql> select host,user,password from user;
+-----------+------+-------------------------------------------+
| host | user | password |
+-----------+------+-------------------------------------------+
| localhost | root | |
| rhel5.4 | root | |
| 127.0.0.1 | root | |
| ::1 | root | |
| localhost | | |
| rhel5.4 | | |
| localhost | jack | *9BCDC990E611B8D852EFAF1E3919AB6AC8C8A9F0 |
+-----------+------+-------------------------------------------+
rows in set (0.00 sec)
mysql> drop user 'jack'@'localhost';
Query OK, 0 rows affected (0.01 sec)
6、对账户重命名
mysql> rename user 'jack'@'%' to 'jim'@'%'; Query OK, 0 rows affected (0.00 sec)
7、修改密码
1、用set password命令
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');
Query OK, 0 rows affected (0.00 sec)
2、用mysqladmin
[root@rhel5 ~]# mysqladmin -uroot -p123456 password 1234abcd
备注:
格式:mysqladmin -u用户名 -p旧密码 password 新密码
3、用update直接编辑user表
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> update user set PASSWORD = PASSWORD('1234abcd') where user = 'root';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
4、在丢失root密码的时候:
[root@rhel5 ~]# mysqld_safe --skip-grant-tables &
[1] 15953
[root@rhel5 ~]# 130911 09:35:33 mysqld_safe Logging to '/mysql/mysql5.5/data/rhel5.4.err'.
09:35:33 mysqld_safe Starting mysqld daemon with databases from /mysql/mysql5.5/data
[root@rhel5 ~]# mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.22 Source distribution
Copyright (c) 2000, 2011, 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.
mysql> \s
--------------
mysql Ver 14.14 Distrib 5.5.22, for Linux (i686) using EditLine wrapper
Connection id: 2
Current database:
Current user: root@
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.5.22 Source distribution
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /tmp/mysql.sock
Uptime: 36 sec
Threads: 1 Questions: 5 Slow queries: 0 Opens: 23 Flush tables: 1 Open tables: 18 Queries per second avg: 0.138
--------------
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> update user set password = PASSWORD('123456') where user = 'root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql 权限控制详解
概述
MySQL权限控制在不同的上下文和不同的操作水平上都可以进行控制,他们包括如下几个
** 管理权限可以允许用户管理mysql server的操作。这些权限控制是全局的,不是针对某个特定的数据库的
** 数据库权限对应到一个数据库和里面的对象。这些权限被用来控制特定的数据库或者全局的,他们能够应用到所有的数据库
** 数据库对象的权限对应到数据库表,索引,视图,和存储过程,可以对数据库内部的某个对象进行授权控制。
权限的存储位置
** 账号权限信息被存储在mysql数据库的user,db,tables_priv ,columns_priv ,procs_priv 表中。
** mysql启动的时候读取这些信息到内存中去,或者在权限变更生效的时候,重新读取到内存中去
mysql 账号管理
mysql 账号名字由用户名和主机名组成。这样可以允许同已用户在不同主机上分别控制权限。这一部分描述如何分配账户名字包括特定的值和模糊
匹配规则,在sql语句中,create user, grant ,set password的时候,会用到这些规则:
- ‘user_name’@’host_name’ 就是账户名字的语法规则
- 仅仅包含用户名的账号等同于 ‘username’@’%’
- 如果用户名是合法的字符,用户名和主机名不必用引号引起来。在你的用户名包含’-‘这样的字符的时候,需要用引号引起来。或者说主机名有
通配符的时候需要引起来。
- 引号可以用单引号也可以用双引号。
- 主机和用户名必须分别被引号括起来,如果必须要括的话。
mysql在mysql数据库中分别用两个列去存储用户名和主机名:
- 用户表每个账户一行记录,此表也表示了账号有哪些全局权限。
- 其他授权表表示了账号拥有的数据库和数据库内的对象。这些表都有用户名和主机列。每行的账户信息和user表的账户信息是奕扬的。
用户名和主机名可以包含特殊字符或者通配符,下面是这些规则:
用户名要么是一个非空字符串字面上必须匹配连接字符串中指名的用户名,或者一个空字符串就会匹配人户用户名。空用户名是一个匿名用户。
主机名也可以又好多形式,或者通配符:
- 主机名可以是一个IP地址或者一个localhost样的字符串。
- %和sql中的like的效果是一样的。例如 ’%.mysql.com’ 就会匹配 a.mysql.com.
权限控制阶段1:连接校验
当你尝试去连接到mysql服务器,服务器基于下面两点条件去接受或者拒绝连接:
- 你的身份标识以及正确的密码
- 你的账号是否被锁定了
服务器先校验密码是否正确,然后校验是否锁定。任何一个步骤失败,服务器将会拒绝连接。如果通过校验,服务器接受连接,然后进入第二阶段并且等候请求。
认证检查先检查user表的三个列,host,user,password。锁定状态是在user表的account_locked列中记录着的。账号锁定状态可以通过alter user语句来变更。
你的身份由两部分来组成,你连接的客户主机以及你的mysql用户名。如果用户名不空,则必须全字符匹配才可以,如果用户名是空的,则匹配任何用户。如果用户表匹配到一个空用户名,这个用户被认为是一个匿名用户,二不是客户实际提供的。这意味着空用户名是用来进一步检查用的也就是阶段2.
密码可以为空,这个不是一个通配符,不意味着匹配任何密码。它的意思是用户必须无密码连接。如果服务起授权一个客户都安使用一个插件,这样
该插件实现的认证体系或许没有用密码列。在这样的情况下,外部密码也可以用来去认证mysql服务器。
非空密码都是加密存储的,mysql没有存储任何明文密码。并且用户提供的密码也是被加密的。这个加密的密码后来在连接过程中,来检查密码是否正确。
从mysql的观点来看,加密的密码才是真正的密码,所以不要告诉任何人这个加密的密码。
如果在user表中有多行被匹配,服务器必须决定用哪一个,它的规则是这样的:
- 任何时候服务器读取用户表到内存中的时候,它会排序。
- 服务器检查的伺候服务器按行顺序去检查
- 服务器使用第一个匹配的行
服务器排序的规则是无通配符的在前面,统配的在后面。
权限控制阶段2:请求校验
当通过了连接校验,你和服务器建立了连接后,服务器进入权限控制的第二个阶段。你的每个请求,服务器决定出你想做什么操作,然后检查你是否有
权限去做。此时,grant 表的privilege列就该出场了。这些列可以出自 user,db,tables_priv,columns_priv,procs_priv。不再细讲这些表了。
什么时候去权限变更生效
当服务器启动的时候,grant表的数据被读入内存。如果你使用账户管理语句去更新权限控制,服务器将会知道这些变更,然后重新读取它们。如果你
直接用sql语句去更新这些表,你的变更不会生效,直到你重新启动服务器或者你告诉服务器去重建缓存。
你可以通过执行一个刷新权限操作来通知服务器重建缓存。下面三个语句都可以达到效果:
- flush_privileges
- mysqladmin_flush-privileges
- mysqladmin_reload
如果启动参数是 –skip-grant-tables ,那么服务器不再校验任何权限,很不安全。
mysql 用户管理和权限设置
用户管理
mysql>use mysql;
查看
mysql> select host,user,password from user ;
创建
mysql> create user zx_root IDENTIFIED by 'xxxxx'; //identified by 会将纯文本密码加密作为散列值存储
修改
mysql>rename user feng to newuser;//mysql 5之后可以使用,之前需要使用update 更新user表
删除
mysql> drop user newuser; //mysql5之前删除用户时必须先使用revoke 删除用户权限,然后删除用户,mysql5之后drop 命令可以删除用户的同时删除用户的相关权限
更改密码
mysql> set password for zx_root =password('xxxxxx');
mysql> update mysql.user set password=password('xxxx') where user='otheruser'
查看用户权限
mysql> show grants for zx_root;
赋予权限
mysql> grant select on dmc_db.* to zx_root;
回收权限
mysql> revoke select on dmc_db.* from zx_root; //如果权限不存在会报错
上面的命令也可使用多个权限同时赋予和回收,权限之间使用逗号分隔
mysql> grant select,update,delete ,insert on dmc_db.* to zx_root;
如果想立即看到结果使用
flush privileges ;
命令更新
设置权限时必须给出一下信息
1,要授予的权限
2,被授予访问权限的数据库或表
3,用户名
grant和revoke可以在几个层次上控制访问权限
1,整个服务器,使用 grant ALL 和revoke ALL
2,整个数据库,使用on database.*
3,特点表,使用on database.table
4,特定的列
5,特定的存储过程
user表中host列的值的意义
% 匹配所有主机
localhost localhost不会被解析成IP地址,直接通过UNIXsocket连接
127.0.0.1 会通过TCP/IP协议连接,并且只能在本机访问;
::1 ::1就是兼容支持ipv6的,表示同ipv4的127.0.0.1
grant 普通数据用户,查询、插入、更新、删除 数据库中所有表数据的权利。
grant select on testdb.* to common_user@’%’
grant insert on testdb.* to common_user@’%’
grant update on testdb.* to common_user@’%’
grant delete on testdb.* to common_user@’%’
或者,用一条 MySQL 命令来替代:
grant select, insert, update, delete on testdb.* to common_user@’%’
9>.grant 数据库开发人员,创建表、索引、视图、存储过程、函数。。。等权限。
grant 创建、修改、删除 MySQL 数据表结构权限。
grant create on testdb.* to developer@’192.168.0.%’;
grant alter on testdb.* to developer@’192.168.0.%’;
grant drop on testdb.* to developer@’192.168.0.%’;
grant 操作 MySQL 外键权限。
grant references on testdb.* to developer@’192.168.0.%’;
grant 操作 MySQL 临时表权限。
grant create temporary tables on testdb.* to developer@’192.168.0.%’;
grant 操作 MySQL 索引权限。
grant index on testdb.* to developer@’192.168.0.%’;
grant 操作 MySQL 视图、查看视图源代码 权限。
grant create view on testdb.* to developer@’192.168.0.%’;
grant show view on testdb.* to developer@’192.168.0.%’;
grant 操作 MySQL 存储过程、函数 权限。
grant create routine on testdb.* to developer@’192.168.0.%’; -- now, can show procedure status
grant alter routine on testdb.* to developer@’192.168.0.%’; -- now, you can drop a procedure
grant execute on testdb.* to developer@’192.168.0.%’;
10>.grant 普通 DBA 管理某个 MySQL 数据库的权限。
grant all privileges on testdb to dba@’localhost’
其中,关键字 “privileges” 可以省略。
11>.grant 高级 DBA 管理 MySQL 中所有数据库的权限。
grant all on *.* to dba@’localhost’
12>.MySQL grant 权限,分别可以作用在多个层次上。
1. grant 作用在整个 MySQL 服务器上:
grant select on *.* to dba@localhost; -- dba 可以查询 MySQL 中所有数据库中的表。
grant all on *.* to dba@localhost; -- dba 可以管理 MySQL 中的所有数据库
2. grant 作用在单个数据库上:
grant select on testdb.* to dba@localhost; -- dba 可以查询 testdb 中的表。
3. grant 作用在单个数据表上:
grant select, insert, update, delete on testdb.orders to dba@localhost;
4. grant 作用在表中的列上:
grant select(id, se, rank) on testdb.apache_log to dba@localhost;
5. grant 作用在存储过程、函数上:
grant execute on procedure testdb.pr_add to ’dba’@’localhost’
grant execute on function testdb.fn_add to ’dba’@’localhost’
注意:修改完权限以后 一定要刷新服务,或者重启服务,刷新服务用:FLUSH PRIVILEGES。
权限表
权限 | 说明 |
all | |
alter | |
alter routine | 使用alter procedure 和drop procedure |
create | |
create routine | 使用create procedure |
create temporary tables | 使用create temporary table |
create user | |
create view | |
delete | |
drop | |
execute | 使用call和存储过程 |
file | 使用select into outfile 和load data infile |
grant option | 可以使用grant和revoke |
index | 可以使用create index 和drop index |
insert | |
lock tables | 锁表 |
process | 使用show full processlist |
reload | 使用flush |
replication client | 服务器位置访问 |
replocation slave | 由复制从属使用 |
select | |
show databases | |
show view |
shutdown | 使用mysqladmin shutdown 来关闭mysql |
super | |
update | |
usage | 无访问权限 |
一、前言
很多文章中会说,数据库的权限按最小权限为原则,这句话本身没有错,但是却是一句空话。因为最小权限,这个东西太抽象,很多时候你并弄不清楚具体他需要哪些权限。 现在很多mysql用着root账户在操作,并不是大家不知道用root权限太大不安全,而是很多人并不知道该给予什么样的权限既安全又能保证正常运行。所以,本文更多的是考虑这种情况下,我们该如何简单的配置一个安全的mysql。注:本文测试环境为mysql-5.6.4
二、Mysql权限介绍
mysql中存在4个控制权限的表,分别为user表,db表,tables_priv表,columns_priv表。
mysql权限表的验证过程为:
1.先从user表中的Host,User,Password这3个字段中判断连接的ip、用户名、密码是否存在,存在则通过验证。
2.通过身份认证后,进行权限分配,按照user,db,tables_priv,columns_priv的顺序进行验证。即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db, tables_priv,columns_priv;如果为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限;如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推。
三、mysql有哪些权限
四、数据库层面(db表)的权限分析
五、mysql安全配置方案
1 限制访问mysql端口的ip
windows可以通过windows防火墙或者ipsec来限制,linux下可以通过iptables来限制。
2 修改mysql的端口
windows下可以修改配置文件my.ini来实现,linux可以修改配置文件my.cnf来实现。
3 对所有用户设置强密码并严格指定对应账号的访问ip
mysql中可在user表中指定用户的访问可访问ip
4 root特权账号的处理
建议给root账号设置强密码,并指定只容许本地登录
5 日志的处理
如需要可开启查询日志,查询日志会记录登录和查询语句。
6 mysql进程运行账号
在windows下禁止使用local system来运行mysql账户,可以考虑使用network service或者自己新建一个账号,但是必须给与mysql程序所在目录的读取权限和data目录的读取和写入权限; 在linux下,新建一个mysql账号,并在安装的时候就指定mysql以mysql账户来运行,给与程序所在目录的读取权限,data所在目录的读取和写入权限。
7 mysql运行账号的磁盘权限
1)mysql运行账号需要给予程序所在目录的读取权限,以及data目录的读取和写入权限
2)不容许给予其他目录的写入和执行权限,特别是有网站的。
3)取消mysql运行账户对于cmd,sh等一些程序的执行权限。
8 网站使用的mysql账户的处理
新建一个账户,给予账户在所使用数据库的所有权限即可。这样既能保证网站对所对应的数据库的全部操作,也能保证账户不会因为权限过高而影响安全。给予单个数据库的所有权限的账户不会拥有super, process, file等管理权限的。 当然,如果能很明确是的知道,我的网站需要哪些权限,还是不要多给权限,因为很多时候发布者并不知道网站需要哪些权限,我才建议上面的配置。而且我指的通用的,具体到只有几台机器,不多的情况下,我个人建议还是给予只需要的权限,具体可参考上面的表格的建议。
9 删除无用数据库
test数据库对新建的账户默认有权限
六、mysql***提权分析及防止措施
一般来说,mysql的提权有这么几种方式:
1 udf提权
此方式的关键导入一个dll文件,个人认为只要合理控制了进程账户对目录的写入权限即可防止被导入dll文件;然后如果万一被攻破,此时只要进程账户的权限够低,也没办执行高危操作,如添加账户等。
2 写入启动文件
这种方式同上,还是要合理控制进程账户对目录的写入权限。
3 当root账户被泄露
如果没有合理管理root账户导致root账户被***,此时数据库信息肯定是没办法保证了。但是如果对进程账户的权限控制住,以及其对磁盘的权限控制,服务器还是能够保证不被沦陷的。
4 普通账户泄露(上述所说的,只对某个库有所有权限的账户)
此处说的普通账户指网站使用的账户,我给的一个比较方便的建议是直接给予特定库的所有权限。账户泄露包括存在注入及web服务器被***后直接拿到数据库账户密码。
此时,对应的那个数据库数据不保,但是不会威胁到其他数据库。而且这里的普通账户无file权限,所有不能导出文件到磁盘,当然此时还是会对进程的账户的权限严格控制。
普通账户给予什么样的权限可以见上表,实在不会就直接给予一个库的所有权限。
七、安全配置需要的常用命令
1.新建一个用户并给予相应数据库的权限
grant select,insert,update,delete,create,drop privileges on database.* to user@localhost identified by 'passwd';
grant all privileges on database.* to user@localhost identified by 'passwd';
2.刷新权限
flush privileges;
3. 显示授权
show grants;
4. 移除授权
revoke delete on *.* from 'jack'@'localhost';
5. 删除用户
drop user 'jack'@'localhost';
6. 给用户改名
rename user 'jack'@'%' to 'jim'@'%';
7. 给用户改密码
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');
8. 删除数据库
drop database test;
9. 从数据库导出文件
select * from a into outfile "~/abc.sql"
MySQL的访问分两个阶段:
1. 检查用户是否具有建立与mysql的连接的权利,主要依靠检查:用户名、主机名和密码;
2. 建立了连接后,服务器检查客户端发出的每个请求。看是否有足够的权限实施它。例如执行select命令等。
二、 权限控制
1. mysql访问权限管理通过6个表:user、db、host、tables_priv、columns_priv和procs_priv来控制,6个表的作用如下表:
表名 |
含义 |
user |
控制“用户名”(user)可以从哪一台“主机名”(host)访问mysql 该表包括全局权限的控制 |
Db |
规定哪个用户可以访问哪个数据库 |
Host |
host表与db表结合使用在一个较好层次上控制特定主机对数据库的访问权限 |
Tables_priv |
规定谁可以访问数据库的哪一个表 |
columns_priv |
规定谁可以访问表的哪一个列 |
procs_priv |
规定谁可以执行哪个存储过程 |
2. mysql识别的权限如下表:
Mysql权限 |
对应权限列 |
含义 |
用于数据表访问 | ||
Select |
Select_priv |
是否可以读取表的数据 |
Insert |
Insert_priv |
是否可以向表中插入新的记录 |
delete |
Delete_priv |
是否可以删除表中现有记录 |
Update |
Update_priv |
是否可以更新表中现有记录 |
Lock tables |
Lock_tables_priv |
是否可以锁定表 |
用于改变数据库、数据表和视图 | ||
Create |
Create_priv |
是否可以创建一个新的数据库和数据表 |
Create temporary table |
Create_tmp_table_priv |
是否可以创建临时表 |
Alter |
Alter_priv |
是否可以重命名并改变它的结构 |
Index |
Index_priv |
是否可以添加或删除表索引 |
References |
References_priv |
暂不用 |
Drop |
Drop_priv |
是否可以删除现有的数据库或表 |
Create view |
Create_view_priv |
是否可以创建视图 |
Show view |
Show_view_priv |
是否是可以检查视图定义 |
用于存储过程 | ||
Alter routine |
Alter_routine_priv |
是否改变现有的存储过程 |
Create routine |
Create_routine_priv |
是否可以定义新的存储过程 |
Execute |
Execute_priv |
是否可以执行存储过程 |
用于数据库访问 | ||
File |
File_priv |
是否可以读取和改变本地文件系统的文件 |
Create user |
Create_user_priv |
是否可以创建新用户 |
用于mysql管理 | ||
Grant option |
Grant_priv |
是否可以赋予其他用户个人的权限 |
Show databases |
Show_db_priv |
是否可以看到一份全体数据库的清单 |
Process |
Process_priv |
是否可以看淡到其他用户的mysql进程 |
Super |
Super_priv |
是否可以终止其他用户的mysql进程(kill) |
Reload |
Reload_priv |
是否可以执行各种命令 |
Replication client |
Repl_client_priv |
是否可以决定镜像系统中参与者的信息 |
Replication slave |
Repl_slient_priv |
是否可以通过镜像机制读取msyql服务器数据 |
Shoutdown |
Shutdown_priv |
是否可以关闭mysql |
3. 6个数据权限表的结构
user表 |
db表 |
host表 |
tables_priv表 |
columns_pirv表 |
proc_priv表 |
访问控制列 | |||||
Host |
Host |
Host |
Host |
Host |
Host |
User |
Db |
Db |
Db |
Db |
Db |
Password |
User |
|
User |
User |
User |
数据库/表权限控制列 | |||||
Select_priv |
Select_priv |
Select_priv |
Table_name |
Table_name |
Routine_name |
Insert_priv |
Insert_priv |
Insert_priv |
Grantor |
Column_name |
Routine_type |
Update_priv |
Update_priv |
Update_priv |
Timestamp |
Timestamp |
Grantor |
Delete_priv |
Delete_priv |
Delete_priv |
Table_priv |
Column_priv |
Proc_priv |
Create_priv |
Create_priv |
Create_priv |
Column_priv |
|
Timestamp |
Drop_priv |
Drop_priv |
Drop_priv |
|
|
|
Reload_priv |
Grant_priv |
Grant_priv |
|
|
|
Shutdown_priv |
References_priv |
References_priv |
|
|
|
Process_priv |
Index_priv |
Index_priv |
|
|
|
File_priv |
Alter_priv |
Alter_priv |
|
|
|
Grant_priv |
Create_tmp_table_priv |
Create_tmp_table_priv |
|
|
|
References_priv |
Lock_tables_priv |
Lock_tables_priv |
|
|
|
Index_priv |
Create_view_priv |
Create_view_priv |
|
|
|
Alter_priv |
Show_view_priv |
Show_view_priv |
|
|
|
Show_db_priv |
Create_routine_priv |
Create_routine_priv |
|
|
|
Super_priv |
Alter_routine_priv |
Alter_routine_priv |
|
|
|
Create_tmp_table_priv |
Execute_priv |
Execute_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 |
|
|
|
|
|
安全控制列 |
|
|
|
|
|
ssl_type |
|
|
|
|
|
ssl_cipher |
|
|
|
|
|
x509_issuer |
|
|
|
|
|
x509_subject |
|
|
|
|
|
资源控制列: | |||||
max_questions :规定每个小时之内可以允许执行多少次数据查询 | |||||
max_updates :规定每个小时之内可以允许执行多少次数据修改 | |||||
max_connections :规定每个小时单个用户可以连接到少此 | |||||
max_user_connections :规定单个用户同时连接多少数 |
说明:1).user表中的字段列代表的全局的权限,即一个用户如果在user表中设置允许某个操作,则该用户对所有数据库都可以操作,例如如果给一个用户授予select,则该用户对所有数据库都读的权限;
2).当user表的全局权限与其他表对象权限都有设置时,有下列关系:
User表 |
Y(select为例) |
N(select为例) |
Y |
Y |
Y |
N |
Y |
N |
3.数据访问列的内容
3.1、 Host 字段
一个Host列值可以是一个主机名或一个IP地址。可以用通配符指定Host值。可以使用SQL的模式字符“%”和“_”并具有当你在一个查询中使用LIKE算符同样的含义(不允许regex算符)。 (例如:192.168.3.%匹配任何在192.168.3 C类子网的主机。)
3.2、User 字段
用户名必须是文字的或空白。一个空白值匹配任何用户。%作为一个User值不意味着空白,而是匹配一个字面上的%名字, 当一个到来的连接通过user表被验证而匹配的记录包含一个空白的User值,客户被认为是一个匿名用户。
3.3、Password字段
口令值可以是空或非空,不允许用通配符。一个空口令不意味着匹配任何口令,它意味着用户必须不指定口令。
3.4、Db字段
在columns_priv和tables_priv表中,Db值必须是真正的数据库名(照字面上),不允许模式和空白。在db和host中,Db值可以以字面意义指定或使用SQL模式字符'%'或'_'指定一个通配符。一个'%'或空白匹配任何数据库。
3.5、Table_name,Column_name字段
这些列中的值必须是照字面意思的表或列名,不允许模式和空白。
3.6、mysql匹配连接关系如下
三、权限分配管理:
权限可分为以下层级:
全局层级: 全局权限适用于一个给定服务器中的所有数据库。这些权限存储在mysql.user表中。GRANT ALL ON *.*和REVOKE ALL ON *.*只授予和撤销全局权限。
数据库层级 :数据库权限适用于一个给定数据库中的所有目标。这些权限存储在mysql.db和mysql.host表中。GRANT ALL ON db_name.*和REVOKE ALL ON db_name.*只授予和撤销数据库权限。
表层级:表权限适用于一个给定表中的所有列。这些权限存储在mysql.talbes_priv表中。GRANT ALL ONdb_name.tbl_name和REVOKE ALL ON db_name.tbl_name只授予和撤销表权限。
列层级:列权限适用于一个给定表中的单一列。这些权限存储在mysql.columns_priv表中。当使用REVOKE时,您必须指定与被授权列相同的列。
子程序层级:CREATE ROUTINE, ALTER ROUTINE, EXECUTE和GRANT权限适用于已存储的子程序。这些权限可以被授予为全局层级和数据库层级。而且,除了CREATE ROUTINE外,这些权限可以被授予为子程序层级,并存储在mysql.procs_priv表中。
授权管理:根据操作人员的所在职责要求具体操作如下:
2.1:数据库管理员:
权限:全局层的所有的操作权限:
操作:grant all privileges on *.* to ‘usename’@’hostnane’ IDENTIFIED
by 'password' with grant option
2.2:数据库操作者:
权限:表层级的访问和更新权限:
2.2.1授予某个用户某个表的操作权限:
操作:grant select,update on dbname.tbl_name to
‘usename’@’hostnane’ IDENTIFIED by 'password'
2.2.2授予某个用户表的某个字段操作权限:
操作:grant update(column_name) on dbname.tbl_name to
‘usename’@’hostnane’ IDENTIFIED by 'password'
2.3:数据访问者:
权限:表层级的访问权限:
操作:grant select on dbname.tbl_name to ‘usename’@’hostnane’
IDENTIFIED by 'password'
2.4:执行存储过程的权限:
权限:可以执行某个数据库的存储过程或者函数
操作:grant Execute on dbname.* to ‘usename’@’hostnane’
IDENTIFIED by 'password'
说明:1.创建某个数据库的某个存储过程的执行权限操作为:
insert into `procs_priv` (`Host`, `Db`, `User`, `Routine_name`,
`Routine_type`, `Grantor`, `Proc_priv`, `Timestamp`)
values('host','dbname','username','proc_name','PROCEDURE',‘存
储过程创建者的访问帐号','Execute,Alter Routine','2007-08-14
17:33:39');
2.mysql的中,root用户可以执行、修改任何用户创建的存储过程;
其他访问用户只能修改自己创建的存储过程,如果想要修改其他用户
的存储过程,则必须要授予mysql.proc表的选择权限。(如果某用户
被授予了此权限,则此用户也拥有了他能访问的数据库的所有存储过
程的执行权限)
2.5:限制某个帐户的资源使用:
权限:访问帐号在每个小时内可以查询多少次、访问多少次等:
操作:GRANT ALL ON dbname.* TO 'username'@'hostname'
IDENTIFIED BY 'frank' WITH MAX_QUERIES_PER_HOUR 20
MAX_UPDATES_PER_HOUR 10 MAX_CONNECTIONS_PER_HOUR 5
MAX_USER_CONNECTIONS 2;
说明:WITH MAX_QUERIES_PER_HOUR 20:平均每小时可以执行20次查询;
MAX_UPDATES_PER_HOUR 10:平均每个小时可以执行20次更新;
MAX_CONNECTIONS_PER_HOUR 5:每小时最大连接用户数;
MAX_USER_CONNECTIONS 2:单个用户每小时可连接两次;
说明:对于修改数据库、表、视图的修改,存储过程和函数的创建和修改权限,授
权和资源控制权限一旦授权后存在风险,建议应该只有管理员拥有这些权限Mysql连接匹配关系如下表:
编号 |
Host值 |
User值 |
匹配连接 |
1 |
Localhost |
Root |
Root用户,从本地可以连接 |
2 |
192.168.1.% |
Root |
Root用户,从192.168.1的子网可以连接 |
3 |
192.168.1.2 |
Root |
Root用户,从192.168.1.2的主机可以连接 |
4 |
192.168.1.2 |
空值 |
任何用户,从192.168.1.2的主机都可以连接 |
5 |
% |
Root |
Root用户,从任何主机都可以连接 |
6 |
% |
空值 |
任何用户,任何主机都可以连接 |
7 |
空值 |
空值 |
任何用户,任何主机都可以连接 |
8 |
Localhost |
空值 |
任何用户,从localhost都可以连接 |
说明:在连接中如果没有指定连接参数,mysql客户端程序使用默认值:
1. 默认主机名上localhost,默认用户名在windows中是odbc,在linux中是
linux的登陆名;
2. 如果在mysql.user表中同时存在编号7、8两个访问连接,那么在当客户
端的连接参数都为空时,mysql默认匹配编号为8的连接,如果只存在7,
那么匹配编号7的连接;
帐户管理
4.1.给root帐户和没有设置密码的帐户设置一个强密码:
操作:SET PASSWORD FOR 'root'= PASSWORD('biscuit');
或者:GRANT USAGE ON *.* TO ‘usernmae’ IDENTIFIED BY 'biscuit'
4.2.删除匿名用户:
操作:delete from user where user=’’
4.3.删除host中为%的访问者:
操作:delete from user where host=’%’
4.4.撤消某个用户的权限:
4.4.1撤消某个用户对某个数据库的操作权限:
操作:revoke update on dbname.* from ‘username’%’hostname‘
4.4.2撤消某个用户对数据库的某个表的操作权限:
操作:revoke update on dbname.tblname from ‘username’%’hostname’
4.5.删除废用的访问帐号:
操作:drop user ‘usename’@’hostname’
4.6.撤消某个帐户的资源限制:
操作:GRANT USAGE ON dbname.* TO 'username'@'hostname' WITH
MAX_CONNECTIONS_PER_HOUR 0
后记:
若访问MySQL服务器中的数据的客户端IP可以固定的话,建议尽量采用固定IP地址,或者机器名称(若在my.cnf中禁用了skip-networking,就不要使用主机名称,会导致无法解释)。启动Mysqld时不要使用root帐号,使用专用的帐号,若不嫌麻烦尽量把root帐号的名称进行更改。