教你一步一步地加强MySQL的安全性 |
|||||||||||||||||||||||||
本文的实验都假设PHP模块已经安装在了Apache Web服务器上了,并且被放在了目录 /chroot/httpd下。除此以外,我们还作了如下的假设: MySQL数据库仅被同主机上的PHP使用; 默认的管理工具像mysqladmin、mysql和 mysqldump,被用来管理数据库。另外,远程的数据备份将使用SSH协议执行。 为了获得更高的安全性能,对于MySQL的安装和配置,应该与以下的安全要求相符合: 1) MySQL数据库应该在被改变了默认根目录的环境下运行; 2) MySQL进程必须使用一个在系统进程中唯一的UID/GID; 3) 对MySQL的访问仅限于本地; 4) 保证MySQL根账户的密码不易被猜测; 5) 禁止对数据库的匿名访问; 6) 删除系统自带的所有的示例数据库和表; 安装MySQL 在我们开始加强MySQL的安全性之前,必须在服务器上安装它。我们在操作系统上来创建一个组和用户帐号,并使之唯一,使之与MySQL数据库相关联,方法如下:
1.编译MySQL 我们先来在目录/usr/local/mysql下编译和安装MySQL软件:
总的来说,在Apache服务器上安装MySQL的过程基本上与手动安装等同。可能唯一的不同点就是使用了一些参数而已,像指定了./configure行。这里最重要的不同点在于参数“--with-mysqld-ldflags=-all-static”的使用,它可以使MySQL服务器使用静态连接。就像在第三部分涉及到的其他参数一样,这将显著简化改变服务器的根路径的过程,它们通知make程序安装在目录/usr/local/mysql下,以mysql账户的权限运行MySQL的后台程序,并且在/tmp目录下创建mysql.sock套接字。 2.拷贝配置文件 在执行了上面的命令后,我们还必须拷贝默认的配置文件以与期望的数据库大小一致。例如:
3.启动服务器 到这里为止,MySQL已经完全安装了,并且整装待发了。我们可以通过执行下面的命令来启动MySQL的服务器:
4.测试连接 尝试与一个数据库建立连接:
如果连接成功,系统将显示如下内容:
然后,我们就可以看看本机上有哪些数据库,如下所示:
2 rows in set (0.00 sec) 然后退出当前命令,使用如下命令:
一旦连接成功建立,我们就可以通过如下命令关闭数据库:
如果不这样做,我们就应该分析一下存储在 /usr/local/mysql/var/`hostname`.err日志文件中的信息的安全性,以消除导致问题的因素。 改变服务器的默认根目录 接下来的第一步就是准备chrooted环境,以使MySQL服务能够运行。这里的目标操作系统是FreeBSD4.7。然而,本文中所讲授的方法同样适用于大多数的UNIX和类似UNIX的系统。 1.准备chroot环境 为了准备chrooted环境,我们必须创建如下的目录:
2.设置访问权利 上面对目录的访问权利应该如下设置:
3.创建目录结构 接下来,下面的这些文件应该拷贝到新的目录中:
4.强化密码和组 我们必须从文件/chroot/mysql/etc/passwords和/chroot/mysql/etc/group里删除除了账户和组以外的行,接下来,还应该按照如下方法build密码数据库:
5.特殊考虑 在Apache Web服务器上,我们还必须创建一个特殊的设备文件/dev/null:
系统将显示如下的信息:
然后,我们再使用如下的命令:
我们还必须拷贝那些包含着在MySQL安装过程中创建的包含授权表的mysql数据库:
6.本地化 如果主机上使用的默认语言不是英语,我们还应该拷贝合适的字符集,可以在目录/usr/local/mysql/share/mysql/charset下找到。 7.测试配置 现在,MySQL应该可以在chrooted环境中运行了。我们可以通过下面这个命令来验证一下它是否能正确的运行:
如果在执行了上面的命令后出现了错误,我们应该使用truss命令或者具有等价功能的命令如:ktrace/kdump、strace等等。这些命令可以帮助我们来找出和消除引起问题的原因。 (脚本小子:这里为了能够运行mysqld进程,使用的是chrootuid程序而不是chroot程序,因为假设是在Apache或者PHP的环境下,它们两个的主要不同在于chrootuid可以改变执行进程的所有者,在我们的例子里面,mysqld在一个chrooted环境下被执行的,但是进程的所有者不是root而是mysql用户,Chrootid在许多操作系统里并不是默认安装的,需要我们从网上下载下来,然后手动安装上去,可以到网址[url]ftp://ftp.porcupine.org/pub/security/chrootuid1.3.tar.gz[/url]下载。) 配置服务器 接下来的步骤,我们就要来配置数据库服务器,使之能够适合我们的安全性要求。 在假定MySQL进行默认安装的时候,主要的配置文件是/etc/my.cnf。然而,在我们的例子里,因为是在chrooted环境下运行服务,所以我们就要使用两个配置文件/chroot/mysql/etc/my.cnf和/etc/my.cnf。其中,前一个可以被MySQL服务器使用,而后一个要被MySQL工具(如mysqladmin,mysql,mysqldump等)使用。 1.禁止远程访问 我们知道,MySQL默认情况下使用TCP的3306端口,所以,我们首先要改变一下。因为,按照我们开始的设想,数据库仅仅是让本机的PHP应用程序访问,所以,我们可以将这个监听端口的功能禁止掉。这样就可以降低MySQL数据库遭受直接经由TCP/IP访问的外部主机攻击的可能性。而同时,本地的交互还可以通过mysql.sock套接字进行。为了能够禁止在3306端口上监听,我们要将参数skip-networking添加到/chroot/mysql/etc/my.cnf目录下[mysqld]部分。如果在有的时候还需要从外部访问数据库,可以按照如下方法使用SSH协议:
2.提高本地安全性 接下来,为了防止对本地文件进行未授权的访问,我们还需要禁止掉对LOAD DATA LOCAL INFILE命令的使用。这对于有效防止当在PHP应用程序中发现了新的SQL注入漏洞是非常有效的。这里,我们需要对在目录/chroot/mysql/etc/my.cnf下的[mysqld]部分加一个参数set-variable=local-infile=0。 另外,为了更方便的使用数据库管理工具,我们还必须改变/etc/my.cnf目录[client]部分的参数设置为socket = /chroot/mysql/tmp/mysql.sock。这样,当我们以后再需要用到管理工具的时候,就不用每次都来使用带有socket=/chroot/mysql/tmp/mysql.sock参数的命令了。 3.改变管理员的密码 在加强MySQL安全性的这些步骤里,改变管理员的密码是很重要的一步,但是,这首先需要MySQL运行起来,可以通过如下命令实现:
用下面的命令改变管理员的密码:
(脚本小子:不要直接在命令行里改变密码,如使用“mysqladmin password”命令,因为这就有可能被同时使用服务器的其他用户看到,从而泄漏密码。例如:其他用户可以使用“ps aux”命令或者查看历史文件,就可以看到我们设置的密码。) 4.删除默认的数据库和用户 接下来,我们必须删除示例数据库和除了root账户以外的所有的账户,可以使用如下命令来实现:
这就可以有效阻止对数据库的匿名连接和清除在/chroot/mysql/etc/my.cnf下的与skip-networking无关的参数,从而阻止远程连接。 5.改变管理员的登陆名称 我们同样也推荐将默认管理员的账户名称修改,这样,就可以使得外部用户很难猜测账户名称。这样一个改变,就可以有效的阻止对管理员密码的暴力攻击和字典攻击。因为,攻击者首先要猜出用户名称,然后才能猜测密码。可以通过如下方式改变:
6.删除历史纪录文件 最后,我们应该将MySQL中历史文件的内容删除,因为所有执行过的SQL命令都被以明文的形式存储在这里,很容易泄密。这可以通过如下方式实现:
如何在PHP和MySQL之间进行交互 因为本地的PHP与MySQL之间的交互通过/tmp/mysql.sock套接字进行,而将PHP放在chrooted环境中意味着它们之间不能交互。为了解决这个问题,在我们每次使用MySQL的时候,都必须先创建一个到PHP的chrooted环境的稳固连接。这可以通过如下命令实现:
(脚本小子:/chroot/mysql/tmp/mysql.sock套接字和/chroot/httpd/tmp目录必须处在相同的文件系统下,否则他们之间的稳固连接将不能正常工作。) 现在,我们要创建能够被指定的PHP应用使用的所有的数据库和账户,需要注意的是,这些帐户仅仅拥有通过PHP应用对数据库进行访问的权利。特别需要指出的就是,这些帐户不应该具有对mysql数据库访问的任何权力,当然更不用说对系统的访问和管理特权(FILE, GRANT, ALTER, SHOW DATABASE, RELOAD, SHUTDOWN, PROCESS, SUPER 等)了。 最后,我们也应该创建一个shell脚本,用来在启动系统的时候来运行MySQL,可以到[url]http://www.securityfocus.com/unix/images/mysql.sh[/url]上下载,而在我们的FreeBSD系统里,上面的脚本应该放在/usr/local/etc/rc.d目录下,取名为mysql.sh。 好了,大功告成,通过上面的设置,如果有人想通过mysql入侵你的服务器,估计不死都得掉层皮,嘿嘿! 采用上面陈述的方法,我们可以显著提高MySQL的安全性。通过在一个chrooted环境下运行数据库,禁止掉对TCP3306端口的监听,采用强壮的用户密码,我们就可以使数据库免受大多数的攻击。虽然没有方法能够使我们得到100%的安全性,但是使用描述的方法,至少可以降低来自访问我们的Web服务的用户的不明目的攻击的可能性。 (T114) |