您的位置:首页 > 数据库 > MySQL

MySQL数据库权限与安全设置详解

2017-01-04 10:43 399 查看
MySQL目录权限与安全设置详解

一.权限表
mysql数据库中的3个权限表:user 、db、 host
权限表的存取过程是:
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各种权限(共27个)
(以下操作都是以root身份登陆进行grant授权,以p1@localhost身份登陆执行各种命令。)

1. usage
连接(登陆)权限,建立一个用户,就会自动授予其usage权限(默认授予)。
mysql> grant usage on *.* to ‘p1′@’localhost’ identified by ‘123′;
该权限只能用于数据库登陆,不能执行任何操作;且usage权限不能被回收,也即REVOKE用户并不能删除用户。
2. select
必须有select的权限,才可以使用select table
mysql> grant select on pyt.* to ‘p1′@’localhost’;
mysql> select * from shop;
3. create
必须有create的权限,才可以使用create table
mysql> grant create on pyt.* to ‘p1′@’localhost’;
4. create routine
必须具有create routine的权限,才可以使用{create |alter|drop} {procedure|function}
mysql> grant create routine on pyt.* to ‘p1′@’localhost’;
当授予create routine时,自动授予EXECUTE, ALTER ROUTINE权限给它的创建者:
mysql> show grants for ‘p1′@’localhost’;
+—————————————————————————+
Grants for p1@localhost
+————————————————————————–+
| GRANT USAGE ON *.* TO ‘p1′@’localhost’ IDENTIFIED BY PASSWORD ‘*23AE809DDACAF96AF0FD78ED04B6A265E05AA257′ |
| GRANT SELECT, CREATE, CREATE ROUTINE ON `pyt`.* TO ‘p1′@’localhost’|
| GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `pyt`.`pro_shop1` TO ‘p1′@’localhost’ |
+————————————————————————————-+
5. create temporary tables(注意这里是tables,不是table)
必须有create temporary tables的权限,才可以使用create temporary tables.
mysql> grant create temporary tables on pyt.* to ‘p1′@’localhost’;
[mysql@mydev ~]$ mysql -h localhost -u p1 -p pyt
mysql> create temporary table tt1(id int);
6. create view
必须有create view的权限,才可以使用create view
mysql> grant create view on pyt.* to ‘p1′@’localhost’;
mysql> create view v_shop as select price from shop;
7. create user
要使用CREATE USER,必须拥有mysql数据库的全局CREATE USER权限,或拥有INSERT权限。
mysql> grant create user on *.* to ‘p1′@’localhost’;
或:mysql> grant insert on *.* to p1@localhost;
8. insert
必须有insert的权限,才可以使用insert into ….. values….
9. alter
必须有alter的权限,才可以使用alter table
alter table shop modify dealer char(15);
10. alter routine
必须具有alter routine的权限,才可以使用{alter |drop} {procedure|function}
mysql>grant alter routine on pyt.* to ‘p1′@’ localhost ‘;
mysql> drop procedure pro_shop;
Query OK, 0 rows affected (0.00 sec)

mysql> revoke alter routine on pyt.* from ‘p1′@’localhost’;
[mysql@mydev ~]$ mysql -h localhost -u p1 -p pyt
mysql> drop procedure pro_shop;
ERROR 1370 (42000): alter routine command denied to user ‘p1′@’localhost’ for routine ‘pyt.pro_shop’
11. update
必须有update的权限,才可以使用update table
mysql> update shop set price=3.5 where article=0001 and dealer=’A’;
12. delete
必须有delete的权限,才可以使用delete from ….where….(删除表中的记录)
13. drop
必须有drop的权限,才可以使用drop database db_name; drop table tab_name;
drop view vi_name; drop index in_name;
14. show database
通过show database只能看到你拥有的某些权限的数据库,除非你拥有全局SHOW DATABASES权限。
对于p1@localhost用户来说,没有对mysql数据库的权限,所以以此身份登陆查询时,无法看到mysql数据库:
mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema|
| pyt |
| test |
+——————–+
15. show view
必须拥有show view权限,才能执行show create view。
mysql> grant show view on pyt.* to p1@localhost;
mysql> show create view v_shop;
16. index
必须拥有index权限,才能执行[create |drop] index
mysql> grant index on pyt.* to p1@localhost;
mysql> create index ix_shop on shop(article);
mysql> drop index ix_shop on shop;
17. excute
执行存在的Functions,Procedures
mysql> call pro_shop1(0001,@a);
+———+
| article |
+———+
| 0001 |
| 0001 |
+———+
mysql> select @a;
+——+
| @a |
+——+
| 2 |
+——+
18. lock tables
必须拥有lock tables权限,才可以使用lock tables
mysql> grant lock tables on pyt.* to p1@localhost;
mysql> lock tables a1 read;
mysql> unlock tables;
19. references
有了REFERENCES权限,用户就可以将其它表的一个字段作为某一个表的外键约束。
20. reload
必须拥有reload权限,才可以执行flush [tables | logs | privileges]
mysql> grant reload on pyt.* to p1@localhost;
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
mysql> grant reload on *.* to ‘p1′@’localhost’;
Query OK, 0 rows affected (0.00 sec)
mysql> flush tables;
21. replication client
拥有此权限可以查询master server、slave server状态。
mysql> show master status;
ERROR 1227 (42000): Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation
mysql> grant Replication client on *.* to p1@localhost;
或:mysql> grant super on *.* to p1@localhost;
mysql> show master status;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000006 | 2111 | | |
+——————+———-+————–+——————+
mysql> show slave status;
22. replication slave
拥有此权限可以查看从服务器,从主服务器读取二进制日志。
mysql> show slave hosts;
ERROR 1227 (42000): Access denied; you need the REPLICATION SLAVE privilege for this operation
mysql> show binlog events;
ERROR 1227 (42000): Access denied; you need the REPLICATION SLAVE privilege for this operation
mysql> grant replication slave on *.* to p1@localhost;
mysql> show slave hosts;
Empty set (0.00 sec)
mysql>show binlog events;
+—————+——-+—————-+———–+————-+————–+
| Log_name | Pos | Event_type | Server_id| End_log_pos|Info | +—————+——-+————–+———–+————-+—————+
| mysql-bin.000005 | 4 | Format_desc | 1 | 98 | Server ver: 5.0.77-log,
Binlog ver: 4 | |mysql-bin.000005|98|Query|1|197|use `mysql`; create
table a1(i int)engine=myisam|
……………………………………
23. Shutdown
关闭MySQL:
[mysql@mydev ~]$ mysqladmin shutdown
重新连接:
[mysql@mydev ~]$ mysql
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)
[mysql@mydev ~]$ cd /u01/mysql/bin
[mysql@mydev bin]$ ./mysqld_safe &
[mysql@mydev bin]$ mysql
24. grant option
拥有grant option,就可以将自己拥有的权限授予其他用户(仅限于自己已经拥有的权限)
mysql> grant Grant option on pyt.* to p1@localhost;
mysql> grant select on pyt.* to p2@localhost;
25. file
拥有file权限才可以执行 select ..into outfile和load data infile…操作,但是不要把file, process, super权限授予管理员以外的账号,这样存在严重的安全隐患。
mysql> grant file on *.* to p1@localhost;
mysql> load data infile ‘/home/mysql/pet.txt’ into table pet;
26. super
这个权限允许用户终止任何查询;修改全局变量的SET语句;使用CHANGE MASTER,PURGE MASTER LOGS。
mysql> grant super on *.* to p1@localhost;
mysql> purge master logs before ‘mysql-bin.000006′;
27. process
通过这个权限,用户可以执行SHOW PROCESSLIST和KILL命令。默认情况下,每个用户都可以执行SHOW PROCESSLIST命令,但是只能查询本用户的进程。 mysql> show processlist;
+—-+——+———–+——+———+——+——-+——————+
| Id | User | Host | db | Command | Time | State | Info |
+—-+——+———–+——+———+——+——-+——————+
| 12 | p1 | localhost | pyt | Query | 0 | NULL | show processlist |
+—-+——+———–+——+———+——+——-+——————+
另外,
管理权限(如 super, process, file等)不能够指定某个数据库,on后面必须跟*.*
mysql> grant super on pyt.* to p1@localhost;
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
mysql> grant super on *.* to p1@localhost;
Query OK, 0 rows affected (0.01 sec)

数据库安全 5.1. 保护MySQL安装程序文件 5.2. 权限表 5.3. 建立加密连接
[更新时间]2008-04-09 22:19:52 [字数]7008
Chapter 5. 数据库安全

安全是一个过程,而不是一个方法,它贯穿在我们使用和维护MySQL数据库的过程中。这不单是系统管理员工作,用户也要有安全的意识,使安全问题得到有效控制。MySQL服务器的安全问题可分为内部安全和外部安全两部份。内部安全问题大都与系统文件有关,我们需确保

MySQL程序文件和数据文件的安全。外部安全是指通过网络连接到服务器的安全问题,应该只允许合法用户访问数据库,在一些情况下还可用SSL加密信息传输通道。下分别介绍内部安全和外部安全的防范措施。

5.1. 保护 MySQL安装程序文件

*

在重设置文件权限时,请先关闭数据库服务器。
*

用以下命令把MySQL安装程序目录的属主和所属组设置为MySQL管理员帐号的用户名和用户组名。

% chown -R mysql.mysql /usr/local/mysql

另外一种方法是把除数据目录外的所有目录属主设置为root所有,如:

% chown -R root.mysql /usr/local/mysql
% chown -R mysql.mysql /usr/local/mysql/data

*

设置安装目录及各有关子目录的权限,允许管理员进行所有操作,只允许其他人进行读和执行访问,设置命令如下:

#设置mysql目录
% chmod 755 /usr/local/mysql
or
% chmod u=rwx,go=rx /usr/local/mysql
#设置mysql/bin目录
% chmod 755 /usr/local/mysql/bin
or
% chmod u=rwx,go=rx /usr/local/mysql/bin
#设置mysql/libexec目录
% chmod 700 /usr/local/mysql/libexec
or
% chmod u=rwx,go-rwx /usr/local/mysql/libexec

*

把数据目录及目录中的所有子目录和文件设置为只允许MySQL管理员访问。

% chmod -R go-rwx /usr/local/mysql/data

如果数据目录下有选项文件或套接字文件,并一些客户需访问这些文件,则可用以下的权限设置,使客户在没有读权限的前提下使用这些文件:

% chmod go+x /usr/local/mysql/data

*

mysql.sock
套接字文件一般放以/tmp目录下,要确保该目录设置了粘着位,使自户只能删除自已创建的文件,不能删除其他用户创建的文件。
/etc/my.cnf中公共选项文件,是对所有用户可读的,所以不应把一些敏感信息保存在里面。.my.cnf是用户专用选项文件,要确保只有该用户有权访问。
*

这样设置以后,只有MySQL管理员才能启动服务器。

5.2. 权限表

MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:

*

user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。
*

db权限表:记录各个帐号在各个数据库上的操作权限。
*

table_priv权限表:记录数据表级的操作权限。
*

columns_priv权限表:记录数据列级的操作权限。
*

host权限表:配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。

大家注意到,以上权限没有限制到数据行级的设置。在MySQL只要实现数据行级控制就要通过编写程序(使用GET-LOCK()函数)来实现。

MySQL的版本很多,所以权限表的结构在不同版本间会有不同。如果出现这种情况,可用mysql_fix_privilege_tables脚本来修正。运行方式如下:

% mysql_fix_privilege_tables rootpassword #这里要给出MySQL的root用户密码

最好一下子升级到MySQL 4.0.4版本,因为4.0.2和4.0.3的db表没有Create_tmp_table_priv和Lock_tables_priv权限。

MySQL的权限表定义了两部份内容,一个部份定义权限的范围,即谁(帐户)可以从哪里(客户端主机)访问什么(数据库、数据表、数据列);另一部份定义权限,即控制用户可以进行的操作。下面是一些常用的权限介绍,可直接在GRANT语句中使用。

*

CREATE TEMPORARY TABLES,允许创建临时表的权限。
*

EXECUTE,允许执行存储过程的权限,存储过程在MySQL的当前版本中还没实现。
*

FILE,允许你通过MySQL服务器去读写服务器主机上的文件。但有一定限制,只能访问对任何用户可读的文件,通过服务器写的文件必须是尚未存在的,以防止服务器写的文件覆盖重要的系统文件。尽管有这些限制,但为了安全,尽量不要把该权限授予普通用户。并且不要以root用户来运行MySQL服务器,因为root
用户可在系统任何地方创建文件。
*

GRANT OPTION,允许把你自已所拥有的权限再转授给其他用户。
*

LOCK TABLES,可以使用LOCK TABLES语句来锁定数据表
*

PROCESS,允许你查看和终止任何客户线程。SHOW PROCESSLIST语句或mysqladmin
processlist命令可查看线程,KILL语句或mysqladmin
kill命令可终止线程。在4.0.2版及以后的版本中,PROCESS权限只剩下查看线程的能力,终止线程的能力由SUPER权限控制。
*

RELOAD,允许你进行一些数据库管理操作,如FLUSH,RESET等。它还允许你执行mysqladmin命令:reload,refresh,flush-
hosts,flush-logs,flush-privileges,flush-
status,flush-tables和flush-threads。
*

REPLICATION CLIENT,允许查询镜像机制中主服务器和从服务器的位置。
*

REPLICATION SLAVE,允许某个客户连接到镜像机制中的主服务器并请求发送二进制变更日志。该权限应授予从服务器用来连接主服务器的帐号。在4.0.2版这前,从服务器是用FILE权限来连接的。
*

SHOW DATABASES,控制用户执行SHOW DATABASES语句的权限。
*

SUPER,允许终止线程,使用mysqladmin debug命令,使用CHANGE MASTER,PURGE MASTER LOGS以及修改全局级变量的SET语句。SUPER还允许你根据存放在DES密钥文件里的密钥进行DES解密的工作。

user权限表中有一个ssl_type数据列,用来说明连接是否使用加密连接以及使用哪种类型的连接,它是一个ENUM类型的数据列,可能的取值有:

*

NONE,默认值,表示不需加密连接。
*

ANY,表示需要加密连接,可以是任何一种加密连接。由GRANT的REQUIRE SSL子句设置。
*

X509,表示需要加密连接,并要求客户提供一份有效的X509证书。由GRANT的REQUIRE X509子句设置。
*

SPECIFIED,表示加密连接需满足一定要求,由REQUIRE子句的ISSUER,SUBJECT或CIPHER的值进行设置。只要
ssl_type列的值为SPECIFIED,则MySQL会去检查ssl_cipher(加密算法)、x509_issuer(证书签发者)和
x509_subject(证书主题)列的值。这几列的列类型是BLOB类型的。

user权限表里还有几列是设置帐户资源使用情况的,如果以下数据列中的数全为零,则表示没有限制:

*

max_connections,每小时可连接服务器的次数。
*

max_questions,每小时可发出查询命令数。
*

max_updates,每小时可以发出的数据修改类查询命令数。

设置权限表应注意的事项:

*

删除所有匿名用户。
*

查出所有没有口令用户,重新设置口令。可用以下命令查询空口令用户:

mysql> SELECT host,user FROM user WHERE password = '';

*

尽量不要在host中使用通配符。
*

最好不要用user权限表进行授权,因为该表的权限都是全局级的。
*

不要把mysql数据库的权限授予他人,因为该数据库包含权限表。
*

使用GRANT OPTION权限时不要滥用。
*

FILE权限可访问文件系统中的文件,所以授权时也要注意。一个具有FILE权限的用户执行以下语句就可查看服务器上全体可读的文件:

mysql> CREATE TABLE etc_passwd(pwd_entry TEXT);
mysql> LOAD DATA INFILE '/etc/passwd' INTO TABLE etc_passwd;
mysql> SELECT * FROM etc_passwd;

如果MySQL服务器数据目录上的访问权限设置得不好,就会留下让具有FILE权限的用户进入别人数据库的安全漏洞。所以建议把数据目录设置成只能由MySQL服务器读取。下面演示一个利用具有FILE权限的用户读取数据目录中文件权限设置不严密的数据库数据的过程:

mysql> use test;
mysql> create table temp(b longblob);
mysql> show databases #显示数据库名清单,--skip-show-database可禁止该功能
mysql> load data infile './db/xxx.frm' into table temp fields escaped by '' lines terminated by '';
mysql> select * from temp into outfile 'xxx.frm' fields escaped by '' lines terminated by '';
mysql> delete from temp;
mysql> load data infile './db/xxx.MYD' into table temp fields escaped by '' lines terminated by '';
mysql> select * from temp into outfile 'xxx.MYD' fields escaped by '' lines terminated by '';
mysql> delete from temp;
mysql> load data infile './db/xxx.MYI' into table temp fields escaped by '' lines terminated by '';
mysql> select * from temp into outfile 'xxx.MYI' fields escaped by '' lines terminated by '';
mysql> delete from temp;

这样,你的数据库就给人拷贝到本地了。如果服务器是运行在root用户下,那危害就更大了,因为root可在服务器上做任何的操作。所以尽量不要用 root用户来运行服务器。
*

只把PROCESS权限授予可信用户,该用户可查询其他用户的线程信息。
*

不要把RELOAD权限授予无关用户,因为该权限可发出FLUSH或RESET语句,这些是数据库管理工具,如果用户不当使用会使数据库管理出现问题。
*

ALTER权限也不要授予一般用户,因为该权限可更改数据表。

GRANT语句对权限表的修改过程:

*

当你发送一条GRANT语句时,服务器会在user权限表里创建一个记录项并把你用户名、主机名和口令记录在User、Host和Password 列中。如果设置了全局权限,由把该设置记录在相在的权限列中。
*

如果在GRANT里设置了数据库级权限,你给出的用户名和主机名就会记录到db权限表的User和Host列中,数据库名记录在Db列中,权限记录到相关的权限列中。
*

接着是到数据表和数据列级的权限设置,设置方法和上面的一样。服务器会把用户名、主机名、数据库名以及相应的数据表名和数据列名记录到数据表中。

删除用户权限其实就是把这些权限表中相应的帐号记录全部删除即可。
5.3. 建立加密连接

加密连接可提高数据的安全性,但会降低性能。要进行加密连接,必须满足以下要求:

*

user权限表里要有相关的SSL数据列。如果安装的MySQL服务器是4.0.0版的,user权限表已包含相关的SSL数据列,否则,我们也可用mysql_fix_privilege_tables脚本升级权限表。
*

服务器和客户程序都已经编译有OpenSSL支持。首先要安装openssl,在编译时MySQL服务器时加--with-vio和--with- openssl选项加上openssl支持。可用以下语句查询服务器是否支持SSL:

mysql> show variables like 'have_openssl';

*

在启动服务器时用有关选项指明证书文件和密钥文件的位置。在建立加密连接前,要准备三个文件,一个CA证书,是由可信赖第三方出具的证书,用来验证客户端和服务器端提供的证书。CA证书可向商业机构购买,也可自行生成。第二个文件是证书文件,用于在连接时向对方证明自已身份的文件。第三个文件是密钥文件,用来对在加密连接上传输数据的加密和解密。MySQL服务器端的证书文件和密钥文件必须首先安装,在sampdb发行版本的ssl目录里有几个供参考的样本文件:ca-cert.pem(CA证书),server-cert.pem(服务器证书),server-key.pem(服务器公共密钥)。把这几个文件拷贝到服务器的数据目录中,再在选项文件里加上以下内容:

[mysqld]
ssl-ca=/usr/local/mysql/data/ca-cert.pem
ssl-cert=/usr/local/mysql/data/server-cert.pem
ssl-key=/usr/local/mysql/data/server-key.pem

重启服务器,使配置生效。
*

要想让某个客户程序建立加密连接,必须在调用这个客户程序时用有关选项告诉它在哪里能找到其证书文件和密钥文件。在sampdb发行版的ssl目录中提供了
client-cert.pem(客户证书文件),client-key.pem(客户密钥文件),CA证书与服务器使用同样的ca-
cert.pem。把他们拷贝到个人目录下,并在.my.cnf选项文件中指出文件位置,如:

[mysql]
ssl-ca=/home/mysql/ca-cert.pem
ssl-cert=/home/mysql/client-cert.pem
ssl-key=/home/mysql/client-key.pem

配置完成后,调用mysql程序运行\s或SHOW STATUS LIKE
'SSL%'命令,如果看到SSL:的信息行就说明是加密连接了。如果把SSL相关的配置写进选项文件,则默认是加密连接的。也可用mysql程序的
--skip-ssl选项取消加密连接。如果用命令行方式启用加密连接可以这样写:

% mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem

可用GRANT语句的REQUIRE SSL选项来强制用户使用加密连接。

使用sampdb发行版的证书可以建立一个加密连接,但由于该文件已公开,所以安全性不好,我们可以在测试成功后自行建立证书或购买商业证书,以提高安全性。如何自行建立SSL证书的文档在sampdb发行版的ssl/README文件里有说明。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql