mysql学习笔记:数据库安全

http://hi.baidu.com/silentseason/blog/item/171e3cddab52d1d98c102934.html

Chapter 5. 数据库安全
Table of Contents

5.1. 保护MySQL安装程序文件
5.2. 权限表
5.3. 建立加密连接
安全是一个过程,而不是一个方法,它贯穿在我们使用和维护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文件里有说明。

此条目发表在lnmp分类目录,贴了标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据