MySQL数据库一向以高性能、高可性和易用性著称,它已经成为世界上最流行的开源数据库。大量的我的、WEB开发者、大型公司等都在其网站、关键系统、软件包中普遍使用MySQL数据库。mysql
一般,许多企业在部署一种产品时,安全性经常得不到应有的重视。企业最关心的是使其能够尽快地运行,企业由此也能够尽快赢利。linux
但有的企业在安装MySQL时用的是默认选项,由此形成其数据不安全,且服务器也面临被入侵的风险,并有可能在短期内就出现性能问题。下面将提供保障MySQL安全的最佳方法。web
一、避免从互联网访问MySQL数据库,确保特定主机才拥有访问特权sql
直接经过本地网络以外的计算机改变生产环境中的数据库是异常危险的。有时,管理员会打开主机对数据库的访问:shell
> GRANT ALL ON *.* TO 'root'@'%';数据库
这实际上是彻底放开了对root的访问。因此,把重要的操做限制给特定主机很是重要:windows
> GRANT ALL ON *.* TO 'root'@'localhost';安全
> GRANT ALL ON *.* TO 'root'@'myip.athome'服务器
> FLUSH PRIVILEGES网络
此时,你仍有彻底的访问,但只有指定的IP(无论其是否静态)能够访问。
二、按期备份数据库
任何系统都有可能发生灾难。服务器、MySQL也会崩溃,也有可能遭受入侵,数据有可能被删除。只有为最糟糕的状况作好了充分的准备,才可以在过后快速地从灾难中恢复。企业最好把备份过程做为服务器的一项平常工做。
三、禁用或限制远程访问
前面说过,若是使用了远程访问,要确保只有定义的主机才能够访问服务器。这通常是经过TCP wrappers、iptables或任何其它的防火墙软件或硬件实现的。
为限制打开网络socket,管理员应当在my.cnf或my.ini的[mysqld]部分增长下面的参数:
skip-networking
这些文件位于windows的C:\Program Files\MySQL\MySQL Server 5.1文件夹中,或在Linux中,my.cnf位于/etc/,或位于/etc/mysql/。这行命令在MySQL启动期间,禁用了网络链接的初始 化。请注意,在这里仍能够创建与MySQL服务器的本地链接。
另外一个可行的方案是,强迫MySQL仅监听本机,方法是在my.cnf的[mysqld]部分增长下面一行:
bind-address=127.0.0.1
若是企业的用户从本身的机器链接到服务器或安装到另外一台机器上的web服务器,你可能不太愿意禁用网络访问。此时,不妨考虑下面的有限许可访问:
mysql> GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';
这里,你要把someuser换成用户名,把somehost换成相应的主机。
四、设置root用户的口令并改变其登陆名
在linux中,root用户拥有对全部数据库的彻底访问权。于是,在Linux的安装过程当中,必定要设置root口令。固然,要改变默认的空口令,其方法以下:
Access MySQL控制台:$ mysql -u root -p
在MySQL控制台中执行:
> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
在实际操做中,只需将上面一行的new_password换成实际的口令便可。
在Linux控制台中更改root口令的另外一种方法是使用mysqladmin工具:
$ mysqladmin -u root password new_password
此时,也是将上面一行的new_password换成实际的口令便可。
固然,这是须要使用强口令来避免强力攻击。
为了更有效地改进root用户的安全性,另外一种好方法是为其更名。为此,你必须更新表用户中的mySQL数据库。在MySQL控制台中进行操做:
> USE mysql;
> UPDATE user SET user="another_username" WHERE user="root";
> FLUSH PRIVILEGES;
而后,经过Linux访问MySQL控制台就要使用新用户名了:
$ mysql -u another_username -p
五、移除测试(test)数据库
在默认安装的MySQL中,匿名用户能够访问test数据库。咱们能够移除任何无用的数据库,以免在不可预料的状况下访问了数据库。于是,在MySQL控制台中,执行:
> DROP DATABASE test;
六、禁用LOCAL INFILE
另外一项改变是禁用”LOAD DATA LOCAL INFILE”命令,这有助于防止非受权用户访问本地文件。在PHP应用程序中发现有新的SQL注入漏洞时,这样作尤为重要。
此外,在某些状况下,LOCAL INFILE命令可被用于访问操做系统上的其它文件(如/etc/passwd),应使用下现的命令:
mysql> LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE table1
更简单的方法是:
mysql> SELECT load_file("/etc/passwd")
为禁用LOCAL INFILE命令,应当在MySQL配置文件的[mysqld]部分增长下面的参数:
set-variable=local-infile=0
七、移除匿名帐户和废弃的帐户
有些MySQL数据库的匿名用户的口令为空。于是,任何人均可以链接到这些数据库。能够用下面的命令进行检查:
mysql> select * from mysql.user where user="";
在安全的系统中,不会返回什么信息。另外一种方法是:
mysql> SHOW GRANTS FOR ''@'localhost';
mysql> SHOW GRANTS FOR ''@'myhost';
若是grants存在,那么任何人均可以访问数据库,至少可使用默认的数据库“test”。其检查方法以下:
shell> mysql -u blablabla
若是要移除帐户,则执行命令:
mysql> DROP USER "";
从MySQL的5.0版开始支持DROP USER命令。若是你使用的老版本的MySQL,你能够像下面这样移除帐户:
mysql> use mysql;
mysql> DELETE FROM user WHERE user="";
mysql> flush privileges;
八、下降系统特权
常见的数据库安全建议都有“下降给各方的特权”这一说法。对于MySQL也是如此。通常状况下,开发人员会使用最大的许可,不像安全管理同样考虑许可原则,而这样作会将数据库暴露在巨大的风险中。
为保护数据库,务必保证真正存储MySQL数据库的文件目录是由”mysql” 用户和” mysql”组所拥有的。
shell>ls -l /var/lib/mysql
此外,还要确保仅有用户”mysql”和root用户能够访问/var/lib/mysql目录。
Mysql的二进制文件存在于/usr/bin/目录中,它应当由root用户或特定的”mysql”用户所拥有。对这些文件,其它用户不该当拥有“写”的访问权:
shell>ls -l /usr/bin/my*
九、下降用户的数据库特权
有些应用程序是经过一个特定数据库表的用户名和口令链接到MySQL的,安全人员不该当给予这个用户彻底的访问权。
若是攻击者得到了这个拥有彻底访问权的用户,他也就拥有了全部的数据库。查看一个用户许可的方法是在MySQL控制台中使用命令SHOW GRANT
>SHOW GRANTS FOR 'user'@'localhost';
为定义用户的访问权,使用GRANT命令。在下面的例子中,user1仅能从dianshang数据库的billing表中选择:
> GRANT SELECT ON billing.dianshang TO 'user1'@'localhost';
> FLUSH PRIVILEGES;
如此一来,user1用户就没法改变数据库中这个表和其它表的任何数据。
另外一方面,若是你要从一个用户移除访问权,就应使用一个与GRANT命令相似的REVOKE命令:
> REVOKE SELECT ON billing.ecommerce FROM 'user1'@'localhost';
> FLUSH PRIVILEGES;
十、移除和禁用.mysql_history文件
在用户访问MySQL控制台时,全部的命令历史都被记录在~/.mysql_history中。若是攻击者访问这个文件,他就能够知道数据库的结构。
$ cat ~/.mysql_history
为了移除和禁用这个文件,应将日志发送到/dev/null。
$export MYSQL_HISTFILE=/dev/null
上述命令使全部的日志文件都定向到/dev/null,你应当从home文件夹移除.mysql_history:$ rm ~/.mysql_history,并建立一个到/dev/null的符号连接。
十一、安全补丁
务必保持数据库为最新版本。由于攻击者能够利用上一个版本的已知漏洞来访问企业的数据库。
十二、启用日志
若是你的数据库服务器并不执行任何查询,建议你启用跟踪记录,你能够经过在/etc/my.cnf文件的[Mysql]部分添加:log =/var/log/mylogfile。
对于生产环境中任务繁重的MySQL数据库,由于这会引发服务器的高昂成本。
此外,还要保证只有root和mysql能够访问这些日志文件。
错误日志
务必确保只有root和mysql能够访问hostname.err日志文件。该文件存放在mysql数据历史中。该文件包含着很是敏感的信 息,如口令、地址、表名、存储过程名、代码等,它可被用于信息收集,而且在某些状况下,还能够向攻击者提供利用数据库漏洞的信息。攻击者还能够知道安装数 据库的机器或内部的数据。
MySQL日志
确保只有root和mysql能够访问logfileXY日志文件,此文件存放在mysql的历史目录中。
1三、改变root目录
Unix操做系统中的chroot能够改变当前正在运行的进程及其子进程的root目录。从新得到另外一个目录root权限的程序没法访问或命名此目录以外的文件,此目录被称为“chroot监狱”。
经过利用chroot环境,你能够限制MySQL进程及其子进程的写操做,增长服务器的安全性。
你要保证chroot环境的一个专用目录,如/chroot/mysql。此外,为了方便利用数据库的管理工具,你能够在MySQL配置文件的[client]部分改变下面的参数:
[client]
socket = /chroot/mysql/tmp/mysql.sock
1四、禁用LOCAL INFILE命令
LOAD DATA LOCAL INFILE能够从文件系统中读取文件,并显示在屏幕中或保存在数据库中。若是攻击者可以从应用程序找到SQL注入漏洞,这个命令就至关危险了。下面的命令能够从MySQL控制台进行操做:
> SELECT LOAD_FILE("/etc/passwd");
该命令列示了全部的用户。解决此问题的最佳方法是在MySQL配置中禁用它,在CentOS中找到/etc/my.cnf或在Ubuntu中找 到/etc/mysql/my.cnf,在[mysqld]部分增长下面一行:set-variable=local-infile=0。搞定。
固然,唇亡齿寒,保护服务器的安全对于保障MySQL数据库的安全也是相当重要的。服务器的安全对于数据库来讲可谓生死攸关。