Mysql数据库的安全配置_第1页
Mysql数据库的安全配置_第2页
Mysql数据库的安全配置_第3页
Mysql数据库的安全配置_第4页
Mysql数据库的安全配置_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Mysql数据库的安全配置、实用技巧【2005-10-0707:34】【】【】1、 前言MySQL是完全网络化的跨平台关系型数据库系统,同时是具有客户机/服务器体系结构的分布式数据库管理系统。它具有功能强、使用简便、管理方便、运行速度快、安全可靠性强等优点,用户可利用许多语言编写访问MySQL数据库的程序,特别是与PHP更是黄金组合,运用十分广泛。由于MySQL是多平台的数据库,它的默认配置要考虑各种情况下都能适用,所以在我们自己的使用环境下应该进行进一步的安全加固。作为一个MySQL的系统管理员,我们有责任维护MySQL数据库系统的数据安全性和完整性。MySQL数据库的安全配置必须从两个方面入手,系统内部安全和外部网络安全,另外我们还将简单介绍编程时要注意的一些问题以及一些小窍门。2、 系统内部安全首先简单介绍一下MySQL数据库目录结构。MySQL安装好,运行了mysql_db_install脚本以后就会建立数据目录和初始化数据库。如果我们用MySQL源码包安装,而且安装目录是/usr/local/mysql,那么数据目录一般会是/usr/local/mysql/var。数据库系统由一系列数据库组成,每个数据库包含一系列数据库表。MySQL是用数据库名在数据目录建立建立一个数据库目录,各数据库表分别以数据库表名作为文件名,扩展名分别为MYD、MYI、frm的三个文件放到数据库目录中。MySQL的授权表给数据库的访问提供了灵活的权限控制,但是如果本地用户拥有对库文件的读权限的话,攻击者只需把数据库目录打包拷走,然后拷到自己本机的数据目录下就能访问窃取的数据库。所以MySQL所在的主机的安全性是最首要的问题,如果主机不安全,被攻击者控制,那么MySQL的安全性也无从谈起。其次就是数据目录和数据文件的安全性,也就是权限设置问题。从MySQL主站一些老的binary发行版来看,3.21.xx版本中数据目录的属性是775,这样非常危险,任何本地用户都可以读数据目录,所以数据库文件很不安全。3.22.xx版本中数据目录的属性是770,这种属性也有些危险,本地的同组用户既能读也能写,所以数据文件也不安全。3.23.xx版本数据目录的属性是700,这样就比较好,只有启动数据库的用户可以读写数据库文件,保证了本地数据文件的安全。如果启动MySQL数据库的用户是mysql,那么象如下的目录和文件的是安全的,请注意数据目录及下面的属性:total40drwxrwxr-x2 root root 4096 Feb 27 20:07 bindrwxrwxr-x3 root root 4096 Feb 27 20:07 includedrwxrwxr-x2 root root 4096 Feb 27 20:07 infodrwxrwxr-x3 root root 4096 Feb 27 20:07 libdrwxrwxr-x2 root root 4096 Feb 27 20:07 libexecdrwxrwxr-x3 root root 4096 Feb 27 20:07 mandrwxrwxr-x6 root root 4096 Feb 27 20:07 mysql-testdrwxrwxr-x3 root root 4096 Feb 27 20:07 sharedrwxrwxr-x7 root root 4096 Feb 27 20:07 sql-benchdrwx 4mysqlmysql4096Feb2720:07varshell>ls-l/usr/local/mysql/vartotal8drwx 2mysqlmysql4096Feb2720:08mysqldrwx 2mysqlmysql4096Feb2720:08testshell>ls-l/usr/local/mysql/var/mysqltotal104-rw 1mysqlmysql0Feb2720:08columns_priv.MYD-rw 1 mysql mysql 1024 Feb 27 20:08 columns_priv.MYI-rw 1 mysql mysql 8778 Feb 27 20:08 columns_priv.frm-rw 1mysqlmysql302Feb2720:08db.MYD-rw 1 mysql mysql 3072 Feb 27 20:08 db.MYI-rw 1 mysql mysql 8982 Feb 27 20:08 db.frm-rw 1mysqlmysql0Feb2720:08func.MYD-rw 1 mysql mysql 1024 Feb 27 20:08 func.MYI-rw 1 mysql mysql 8641 Feb 27 20:08 func.frm-rw 1mysqlmysql0Feb2720:08host.MYD-rw 1 mysql mysql 1024 Feb 27 20:08 host.MYI-rw 1 mysql mysql 8958 Feb 27 20:08 host.frm-rw 1mysqlmysql0Feb2720:08tables_priv.MYD-rw 1 mysql mysql 1024 Feb 27 20:08 tables_priv.MYI-rw 1 mysql mysql 8877 Feb 27 20:08 tables_priv.frm-rw 1mysqlmysql428Feb2720:08user.MYD-rw 1 mysql mysql 2048 Feb 27 20:08 user.MYI-rw 1 mysql mysql 9148 Feb 27 20:08 user.frm如果这些文件的属主及属性不是这样,请用以下两个命令修正之:shell>chown-Rmysql.mysql/usr/local/mysql/varshell>chmod-Rgo-rwx/usr/local/mysql/var用root用户启动远程服务一直是安全大忌,因为如果服务程序出现问题,远程攻击者极有可能获得主机的完全控制权。MySQL从3.23.15版本开始时作了小小的改动,默认安装后服务要用mysql用户来启动,不允许root用户启动。如果非要用root用户来启动,必须加上-user=root的参数(./safe_mysqld-user=root&)。因为MySQL中有LOADDATAINFILE和select...INTOOUTFILE的SQL语句,如果是root用户启动了MySQL服务器,那么,数据库用户就拥有了root用户的写权限。不过MySQL还是做了一些限制的,比如LOADDATAINFILE只能读全局可读的文件,select...INTOOUTFILE不能覆盖已经存在的文件。本地的日志文件也不能忽视,包括shell的日志和MySQL自己的日志。有些用户在本地登陆或备份数据库的时候为了图方便,有时会在命令行参数里直接带了数据库的密码,如:shell>/usr/local/mysql/bin/mysqldump-uroot-ptesttest>test.sql这些命令会被shell记录在历史文件里,比如bash会写入用户目录的.bash_history文件,如果这些文件不慎被读,那么数据库的密码就会泄漏。用户登陆数据库后执行的SQL命令也会被MySQL记录在用户目录的.mysql_history文件里。如果数据库用户用SQL语句修改了数据库密码,也会因.mysql_history文件而泄漏。所以我们在shell登陆及备份的时候不要在-P后直接加密码,而是在提示后再输入数据库密码。另外这两个文件我们也应该不让它记录我们的操作,以防万一。shell>rm.bash_history.mysql_historyshell>ln-s/dev/null.bash_historyshell>ln-s/dev/null.mysql_history上门这两条命令把这两个文件链接到/dev/null,那么我们的操作就不会被记录到这两个文件里了。外部网络安全MySQL数据库安装好以后,Unix平台的user表是这样的:mysql>usemysql;Databasechangedmysql>selectHost,User,Password,select_priv,Grant_privfromuser;+ + + + + +|Host|User|Password|select_priv|Grant_priv|+ + + + + +|localhost|root||Y|Y||redhat|root||Y|Y||localhost|||N|N||redhat|||N|N|+ + + + + +4rowsinset(0.00sec)Windows平台的user表是这样的:mysql>usemysql;Databasechangedmysql>selectHost,User,Password,selectpriv,Grant_privfromuser;+ + + + + -+|Host|User|Password|select_priv|Grant_priv|+ + + + + -+|localhost|root||Y|Y||%|:root||Y|Y||localhost|||Y|Y||%|||N|N|+ + + + + +4rowsinset(0.00sec)我们先来看Unix平台的user表。其中redhat只是我试验机的机器名,所以实际上Unix平台的MySQL默认只允许本机才能连接数据库。但是缺省root用户口令是空,所以当务之急是给root用户加上口令。给数据库用户加口令有三种方法:1) 在shell提示符下用mysqladmin命令来改root用户口令shell>mysqladmin-urootpasswordtest这样,MySQL数据库root用户的口令就被改成test了。(test只是举例,我们实际使用的口令一定不能使用这种易猜的弱口令)2) 用setpassword修改口令:mysql>setpasswordforroot@localhost二password(test);这时root用户的口令就被改成test了。3) 直接修改user表的root用户口令mysql>usemysql;mysql>updateusersetpassword二password(test)whereuser=root;mysql>flushprivileges;这样,MySQL数据库root用户的口令也被改成test了。其中最后一句命令flushprivileges的意思是强制刷新内存授权表,否则用的还是缓冲中的口令,这时非法用户还可以用root用户及空口令登陆,直到重启MySQL服务器。我们还看到user为空的匿名用户,虽然它在Unix平台下没什么权限,但为了安全起见我们应该删除它:mysql>deletefromuserwhereuser=;Windows版本MySQL的user表有很大不同,我们看到Host字段除了localhost还有是%。这里%的意思是允许任意的主机连接MySQL服务器,这是非常不安全的,给攻击者造成可乘之机,我们必须删除Host字段为%的记录:mysql>deletefromuserwherehost=%;默认root用户的空密码也是必须修改,三种修改方法和Unix平台一样。我们注意到Host字段为localhost的匿名用户拥有所有的权限!就是说本地用户用空的用户名和空的口令登陆MySQL数据库服务器可以得到最高的权限!所以匿名用户必须删除!mysql>deletefromuserwhereuser=;对user表操作以后不要忘了用flushprivileges来强制刷新内存授权表,这样才能生效。默认安装的Windows版MySQL存在的不安全因素太多,我们在安装后一定要进一步配置!MySQL的5个授权表:user,db,host,tables_priv和columns_priv提供非常灵活的安全机制,从MySQL3.22.11开始引入了两条语句GRANT和REVOKE来创建和删除用户权限,可以方便的限制哪个用户可以连接服务器,从哪里连接以及连接后可以做什么操作。作为MySQL管理员,我们必须了解授权表的意义以及如何用GRANT和REVOKE来创建用户、授权和撤权、删除用户。在3.22.11版本以前的MySQL授权机制不完善,和新版本也有较大的不同,建议升级到最新版本的MySQL。(本书的操作例子是以MySQL3.23.49为样本)我们先来了解授权表的结构。1)MySQL授权表的结构与内容:mysql>descuser;TOC\o"1-5"\h\z+ + + + + + +|Field|Type|Null|Key|Default|Extra|+ + + + + + +| Host|char(60)binary|| PRI | | || User|char(16)binary|| PRI | | || Password|char(16)binary || | | |select_priv|enum(N,Y)|||N||insert_priv|enum(N,Y)|||N||update_priv|enum(N,Y)|||N||delete_priv|enum(N,Y)|||N||create_priv|enum(N,Y)|||N||drop_priv|enum(N,Y)|||N||Reload_priv|enum(N,Y)|||N||Shutdown_priv|enum(N,Y)|||N|Process_priv-|enum(N,Y)|||N|File_priv|enum(N,Y)|||N||Grant_priv|enum(N,Y)|||N||References_priv|enum(N,Y)|||NIndex_priv|enum(N,Y)|||N||alter_priv|enum(N,Y)|||N||+ + + + + + +17rowsinset(0.01sec)user表是5个授权表中最重要的一个,列出可以连接服务器的用户及其加密口令,并且它指定他们有哪种全局(超级用户)权限。在user表启用的任何权限均是全局权限,并适用于所有数据库。所以我们不能给任何用户访问mysql.user表的权限!权限说明:+ + + +|权限指定符|列名|权限操作|+ + + +|select|select_priv|允许对表的访问,不对数据表进行访问的select语句不受影响,比如select1+1|+ + + +|insert|insert_priv|允许对表用insert语句进行写入操作。|+ + + +|update|update_priv|允许用update语句修改表中现有记录。|+ + + +|delete|delete_priv|允许用delete语句删除表中现有记录。|+++|create|create_priv|允许建立新的数据库和表。|+ + + +|drop|drop_priv|允许删除现有的数据库和表。|+ + + +|Index|Index_priv|允许创建、修改或删除索引。|+ + + +|alter|alter_priv|允许用alter语句修改表结构。|+ + + +|Grant|Grant_priv|允许将自己拥有的权限授予其它用户,包括grant。|+ + + +|Reload|Reload|允许重载授权表,刷新服务器等命令。|+ + + +|Shutdown|Shudown_priv|允许用mysqladminshutdown命令关闭MySQL服务器。该权限比较危险,||||不应该随便授予。|+ + + +|Process|Process_priv|允许查看和终止MySQL服务器正在运行的线程(进程)以及正在执行的查询语句||||,包括执行修改密码的查询语句。该权限比较危险,不应该随便授予。|+ + + +|File|File_priv|允许从服务器上读全局可读文件和写文件。该权限比较危险,不应该随便授予。|+ + + +mysql>descdb;TOC\o"1-5"\h\z+ + + + + + +|Field|Type|Null|Key|Default|Extra|+ + + + + + +| Host |char(60)binary | |PRI | | || Db| char(64)binary| | PRI| | || User |char(16)binary | |PRI | | |select_priv|enum(N,Y)|||Ninsert_priv|enum(N,Y)|||Nupdate_priv|enum(N,Y)|||Ndelete_priv|enum(N,Y)|||Ncreate_priv|enum(N,Y)|||Ndrop_priv|enum(N,Y)|||N||Grant_priv|enum(N,Y)|||N|||References_priv|enum(N,Y)|||N|||Index_priv|enum(N,Y)|||N|||alter_priv|enum(N,Y)|||N||+ + + + + + +13rowsinset(0.01sec)db表列出数据库,而用户有权限访问它们。在这里指定的权限适用于一个数据库中的所有表。mysql>deschost;+ + + + + + +|Field|Type|Null|Key|Default|Extra|+ + + + + + +|Host|char(60)binary||PRI||||Db|char(64)binary||PRI|||select_priv|enum(N,Y)|||N||insert_priv|enum(N,Y)|||N||update_priv|enum(N,Y)|||N||delete_priv|enum(N,Y)|||N||create_priv|enum(N,Y)|||N||drop_priv|enum(N,Y)|||N||Grant_priv|enum(N,Y)|||N||References_priv|enum(N,Y)|||NIndex_priv|enum(N,Y)|||N|||alter_priv|enum(N,Y)|||N||+■+■+■12rowsinset(0.01sec)host表与db表结合使用在一个较好层次上控制特定主机对数据库的访问权限,这可能比单独使用db好些。这个表不受GRANT和REVOKE语句的影响,所以,你可能发觉你根本不是用它。mysql>desctables_priv;|Field|Type|Null|Key|Default|Extra|TOC\o"1-5"\h\z| Host|char(60)binary ||PRI | | || Db|char(64)binary| |PRI| | || User|char(16)binary ||PRI | | || Table_name|char(60)binary| | PRI |||| Grantor|char(77)|| MUL|| ||Timestamp|timestamp(14)|YES||NULL|||Table_priv|set(select,insert,|||||| |update,delete,create,| | | | || |drop,Grant,References,| | | | |||Index,alter)||||||Column_priv|set(select,insert,|||||||update,References)|||||+ + + + + + +8rowsinset(0.01sec)tables_priv表指定表级权限。在这里指定的一个权限适用于一个表的所有列。mysql>desccolumns_priv;+ + + + + + -+|Field|Type|Null|Key|Default|Extra|+ + + + + + -+TOC\o"1-5"\h\z| Host |char(60)binary | |PRI | | || Db| char(64)binary| | PRI| | || User |char(16)binary | |PRI | | || Table_name|char(64)binary| | PRI ||||Column_name|char(64)binary||PRI||||Timestamp|timestamp(14)|YES||NULL|||Column_priv|set(select,insert,|||||||update,References)|||||+ + + + + + -+7rowsinset(0.00sec)columns_priv表指定列级权限。在这里指定的权限适用于一个表的特定列。MySQL授权表运行机制MySQL的访问控制分两个步骤:a) 服务器检查是否允许该用户连接。b) 如果该用户有权连接,那么服务器还会检查它的每一个请求是否有足够的权限。比如:用户检索数据库中的一个表需要有这个数据库的select权限,用户删除数据库中的一个表需要有这个数据库的drop权限。授权表的user,db,host表使用这两个步骤,tables_priv和columns_priv表只使用第二步(检查请求)。每个授权表包含决定一个权限何时运用的范围列和决定授予哪种权限的权限列。范围列指定表中的权限何时运用。每个授权表条目包含User和Host列来指定权限何时运用于一个给定用户从给定主机的连接。其他表包含附加的范围列,如db表包含一个Db列指出权限运用于哪个数据库。类似地,tables_priv和columns_priv表包含范围字段,缩小范围到一个数据库中的特定表或一个表的特定列。下面是user表的Host字段和User字段组合的一些例子:+ + + +|Host值|User值|匹配的连接|+ + + +|x.y.z|test|test用户只能从x.y.z连接数据库|+ + + +|x.y.z||任何用户可以从x.y.z连接数据库|+ + + +|%|test|test用户可以从任意主机连接数据库|+ + + +|||任何用户可以从任意主机连接数据库|+ + + +|%.y.z|test|test用户可以从y.z域的任意主机连接数据库|+ + + +|x.y.%|test|test用户可以从,,等主机连接数据库|+ + + +||test|test用户可以从IP地址为的主机连接数据库|+ + + +|192.168.1.%|test|test用户可以从C类子网192.168.1中的任意主机连接数据库|+ + + +|/|test|同上|+ + + +SQL的字符串通配符%表示匹配任意字符,可以是0个字符,通配符_表示匹配一个字符。权限列指出在范围列中指定的用户拥有何种权限。该表使用GRANT语句的权限名称。对于绝大多数在user、db和host表中的权限列的名称与GRANT语句中有明显的联系。如select_priv对应于select权限。授权表使用举例grant用于给增加用户和创建权限,revoke用于删除用户权限。下面是一些用grant增加用户和创建权限的例子:mysql>grantallprivilegeson*.*totest@localhostidentifiedbytestwithgrantoption;这句增加一个本地具有所有权限的test用户(超级用户),密码是test。ON子句中的*.*意味着〃所有数据库、所有表"owithgrantoption表示它具有grant权限。mysql>grantselect,insert,update,delete,create,dropprivilegesontest.*totest1@/identifiedbytest;这句是增加了一个test1用户,口令是test,但是它只能从C类子网192.168.1连接,对test库有select,insert,update,delete,create,drop操作权限。用grant语句创建权限是不需要再手工刷新授权表的,因为它已经自动刷新了。给用户创建权限还可以通过直接修改授权表:mysql>insertintouservalues("localhost”,"test”,password("test"),"Y”,"Y”,"Y”,"Y”,"Y”,"Y”,"Y","丫","丫","丫","丫","丫","丫","丫");mysql>flushprivileges;这两句和上面第一句grant的效果是一样的,也是增加了一个本地的test超级用户。我们看到用grant方便多了,而且还不需flushprivileges。mysql>insertintouser(host,user,password)values("/","test1",PASSWORD("test"));mysql>insertintodbvalues("/","test","test1","Y","Y","Y","Y","Y","Y","N","N","N","N")mysql>flushprivileges;这三句和上面第二句grant的效果也是一样的,也是增加了一个只能从C类子网192.168.1连接,对test库有select,insert,update,delete,create,drop操作权限的testl用户,口令是test。要取消一个用户的权限,使用revoke语句。revoke的语法非常类似于grant语句,除了to用from取代并且没有identifiedby和withgrantoption子句,下面是用revoke删除用户权限的例子:mysql>revokeallontest.*fromtest1@/;这句revoke就撤消了上面第二句grant创建的权限,但是test1用户并没有被删除,必须手工从user表删除:mysql>deletefromuserwhereuser=test1;mysql>flushprivileges;这样,test1用户就彻底删除了。这些只是MySQL授权表的简单使用,更多详细的资料请见MySQL提供的手册。3、编程需要注意的一些问题不管是用哪种程序语言写连接MySQL数据库的程序,有一条准则是永远不要相信用户提交的数据!对于数字字段,我们要使用查询语句:select*FROMtablewhereID=234不要使用select*FROMtablewhereID=234这样的查询语句。MySQL会自动把字串转换为数字字符并且去除非数字字符。如果用户提交的数据经过了mysql_escape_string处理,这样我们就可以完全杜绝了sqlinject攻击,关于sqlinject攻击请参考下面链接的文章:/papers/SQLInjectionWhitePaper.pdfhttp:///papers/advanced_sql_injection.pdf各种编程语言该注意的问题:1)所有Web程序:a)尝试在Web表单输入单引号和双引号来测试可能出现的错误,并找出原因所在。b)修改URL参数带的%22("),%23(#),和%27()。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论