Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

加固mysql--1年前的文章

[复制链接]
soway 发表于 2004-9-25 16:14:57 | 显示全部楼层 |阅读模式
1年前的文章,不知道现在还有用没...
最近事情多了,很多技术性的东西不太愿意深究了.过几天写点solaris企业性能的文章来

加固你的mysql
前言:mysql已经成为当前网络中使用最多的数据库之一,特别是在web应用上,它已经占据了中小型应用的绝对优势。这一切都源于它的小巧,它的简单有效的安全机制,它的易用性,它的开放式许可,它的多平台,更主要的是它与三大web语言之一的php之间的完美结合。
但不幸的是,一个缺省安全的mysql,由于root密码为空,已经程序漏洞,导致被溢出,导致安装mysql的服务器成为一个被经常攻击的对象。更严重的是,常导致被攻击之后数据库被破坏,造成灾难性的后果。下面就将带你进入为了保卫数据而进行的保卫战中来。

1.1  系统环境
一台redhat9自定义安装的服务器,系统安装了gcc,以及一些其他要求的软件包,比如apache,php等。安装完系统后的第一件事就是升级系统的软件包。作为web服务器,系统接受php脚本的请求,php使用下面安装的mysql数据库作为动态发布的接触。
1.2  安全要求:
①        mysql运行在一个独立的(chroot)环境下;
②        mysqld进程运行于一个独立的用户/用户组下,此用户和用户组没有根目录,没有shell,也不能用于其他程序;
③        mysql的root帐号要被改名和修改一个复杂的密码;
④        只允许本地连接mysql,网络连接被启动mysql的时候禁止掉;
⑤        确实连接mysql的nobody帐号登陆被禁止;
⑥        test数据库被删除。

2.1  Mysql的安装准备
安装mysql之前,我们按照上面要求需要创建一个用于启动mysql的用户和组。
#groupadd mysql
#useradd mysql –C “start mysqld’s account” –d /dev/null –g mysql –s /sbin/nologin
    2.2  编译和安装
下载mysql源代码包:
wget http://mysql.linuxaid.com.cn/Dow ... ysql-3.23.52.tar.gz
解压缩:
tar –zxvf mysql-3.23.52.tar.gz
一般我们把mysql安装在/usr/local/mysql下面,如果你有自己的特殊设置,请自己注意调整,不过由于后面我们将chrooting,那样作没太大的必要,你到时候只是使用这里的客户工具而已,比如mysql,mysqladmin,mysqldump等。废话少说,开始编译安装吧。
#./configure  --prefix=/usr/local/mysql \
--with-mysqld-user=mysql \
--with-unix-socket-path=/tmp/mysql.sock \
--with-mysqld-ldflags=-all-static
#make && make install
#strip /usr/local/mysql/libexec/mysqld
#scripts/mysql_install_db
#chown -R root /usr/local/mysql
#chown -R mysql /usr/local/mysql/var
#chgrp -R mysql /usr/local/mysql
上面的步骤的具体作用在mysql手册里边已经有了介绍,唯一需要解释的和一般的步骤不同之处在于--with-mysqld-ldflags=-all-static。记得我们前面要求的地方吧!我们需要用到chroot环境,而mysql本身连接成静态后,就不用我们再创建一些库环境了。
2.3  配置并启动mysql
mysql的配置文件需要我们手工选择拷贝几个模板文件中的一个到/etc下,这几个模板文件位于源文件的support-files目录,一共4个(small,medium,large,huge).
#cp support-files/my-medium.cnf   /etc/my.cnf
#chown  root:sys  /etc/my.cnf
#chmod 644 /etc/my.cnf
启动mysql,注意使用用户为mysql
#/usr/local/mysq/bin/safe_mysqld  --user=mysql &
2.4  测试
为了测试安装的程序是否正确,以及mysql是否已经启动正常,最好的办法就是用mysql客户端来连接数据库。
#/usr/local/mysql/bin/mysql
[root@ftp bin]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 687 to server version: 3.23.58
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
    mysql> show databases;
+--------------+
| Database     |
+--------------+
| mysql       |
| test         |
+--------------+
2 rows in set (0.07 sec)
mysql>quit
连接成功,可以关闭数据库了:
#/usr/local/mysql/bin/mysqladmin –uroot shutdown
如果连接失败了呢,我们该怎么办?这个时候需要仔细分析出错原因。
#more /usr/local/mysql/var/`hostname`.err

3.1  chrooting环境
chroot是unix/类unix的一种手段,它的建立会将其与主系统几乎完全隔离,也就是说,一旦其遭到了什么问题,它也不会危及到正在的主系统。这是一个非常有效的办法,特别是在配置网络服务程序的时候。
3.2  chroot的准确工作
首先,应当建立如下目录结构
              |---  /dev
              |    /etc
/chroot/mysql--- |    /tmp
              |    /var/tmp       |-- /libexec
              |----  /local/mysql --- |  /share/mysql/english
                              
#mkdir –p /chroot/mysql/dev
# mkdir -p /chroot/mysql/etc
#mkdir -p /chroot/mysql/tmp
#mkdir -p /chroot/mysql/var/tmp
#mkdir -p /chroot/mysql/usr/local/mysql/libexec
#mkdir -p /chroot/mysql/usr/local/mysql/share/mysql/english
然后设定好目录权限
#chown -R root:sys /chroot/mysql
#chmod -R 755 /chroot/mysql
#chmod 1777 /chroot/mysql/tmp
3.3  拷贝mysql的程序和文件到chroot下
#cp /usr/local/mysql/libexec/mysqld /chroot/mysql/usr/local/mysql/libexec/
#cp /usr/local/mysql/share/mysql/english/errmsg.sys
/chroot/mysql/usr/local/mysql/share/mysql/english/
#cp /etc/hosts /chroot/mysql/etc/
#cp /etc/host.conf /chroot/mysql/etc/
#cp /etc/resolv.conf /chroot/mysql/etc/
#cp /etc/group /chroot/mysql/etc/
#cp /etc/passwd /chroot/mysql/etc/passwd
#cp /etc/my.cnf /chroot/mysql/etc/
3.4  编辑chroot下的passwd文件和group文件
#vi /chroot/etc/passwd
删除除了mysql的所有行
#vi /chroot/etc/group
删除除了mysql的所有行
3.5  创建特殊的设备文件/dev/null
参照系统的样子作就可以
#ls –al /dev/null
crw-rw-rw-    1 root     root       1,   3 Jan 30  2003 /dev/null
#mknod /chroot/mysql/dev/null c 2 2
chown root:root  /chroot/mysql/dev/null
chmod 666  /chroot/mysql/dev/null
3.6  拷贝mysql的数据库文件到chroot下
#cp -R /usr/local/mysql/var/ /chroot/mysql/usr/local/mysql/var
#chown -R mysql:mysql /chroot/mysql/usr/local/mysql/var
3.7  安装chrootuid程序
下载chrootuid
wget http://www.mirrors.wiretapped.ne ... chrootuid1.3.tar.gz
然后解压,然后编译,最后cp到/usr/bin目录。
3.8  测试chroot环境下的mysql配置
chrootuid /chroot/mysql mysql /usr/local/mysql/libexec/mysqld &
3.9  测试连接如chroot下的mysql
#/usr/local/mysql/bin/mysql –socket=/chroot/mysql/tmp/mysql.sock
…………..
mysql>show databases;
mysql>create database wgh;
mysql>quit;
#ls –al /chroot/mysql/var/
……………

4.0  配置服务器
为了更加安全地使用mysql,我们需要对mysql地数据库进行安全配置。并且由于chroot的愿意,我们的配置文件也要有些不同之处。
4.1  关闭远程连接
首先,应该关闭3306端口,这是MySQL的默认监听端口。由于我们的MySQL只服务于本地教本,不需要远程连接。尽管MySQL内建的安全机制已经很严格了,但监听一个tcp端口仍然是危险的行为,因为如果MySQL程序本身有问题的话,那么未授权的访问可以绕过MySQL的内建安全机制。关闭网络监听的方法很简单,在/chroot/mysql/etc/my.cnf文件中[mysqld]部分,加上skip-networking即可。
那么关闭了网络,本地程序是怎么连接MySQL数据库的呢?
本地程序通过mysql.sock来连接,速度比网络连接快很多。后面会提到关于mysql.sock的具体情况。MySQL 的备份通常使用ssh来执行!
4.2  禁止MySQL导入本地文件
下面,我们将禁止MySQL中用” LOAD DATA LOCAL INFILE”命令。我记得网络上流传的一些攻击方法中就有用它!这个命令会利用mysql来读本地文件到数据库中,然后用户就可以非法获取敏感信息了。这个也是很多新发现的SQL Injection攻击利用的手段!
为了禁止上述命令,在/chroot/mysql/etc/my.cnf文件的[mysqld]部分加入: set-variable=local-infile=0
为了管理方便,我们一般在系统中用的MySQL管理命令mysql,mysqladmin,mysqldump等,他们使用的是系统的/etc/my.cnf文件,如果要连接,它会寻找/tmp/mysql.sock文件,试图连接MySQL服务器,但是我们这里要连接的是chroot下的MySQL服务器,解决办法有两个:
一个就是在管理命令后面加入—socket=/chroot/mysql/tmp/mysql.sock
例如:#/usr/local/mysql/bin/mysql –root –p --socket=/chroot/mysql/tmp/mysql.sock
第二个就是在/etc/my.cnf的[client]部分加入socket=/chroot/mysql/tmp/mysql.sock
显然,第二个方便多了。
4.3  修改MySQL的root用户ID和密码
#chrootuid /chroot/mysql mysql /usr/local/mysql/libexec/mysqld &
#/usr/local/mysql/bin/mysql –uroot
……………
mysql>SET PASSWORD FOR root@localhost=PASSWORD('new_password');
尽量养成在mysql下输入密码的习惯,以为如果shell下面输入的时候可能让其他人看见。
mysql>update user set user="wghgreat" where user="root";
修改一个不容易猜的ID
mysql>flush privileges;
4.4  删除历史命令记录
这些历史文件包括~/.bash_history  ~/.mysql_history等,如果你打开他们,你会大吃一惊,怎么居然有一些明文的密码在这里?!
#cat /dev/null > ~/.bash_history
#cat /dev/null > ~/.mysql_history

5        PHP和MySQL通信
默认情况下,php会通过/tmp/mysql.sock奈何MySQL通信,但这里有一个大问题,就是MySQL根本不是生成的它,而是生成的/chroot/mysql/tmp/mysql.sock,解决办法就是做一个连接 #ln /chroot/mysql/tmp/mysql.sock /tmp/mysql.sock
注意:由于hard links不能在文件系统的分区之间做,这个地方的连接必须位于同一分区内部!

6        自启动配置
在配置它之前先提示一点,即用于php的数据库需要用一个新建的帐号,其上有数据库权限设置,比如(FILE,GRANT,ACTER,SHOW DATABASE, RELOAD, SHUTDOWN, PROCESS, SUPER等)。
自启动教本示例
#!/bin/sh
CHROOT_MYSQL=/chroot/mysql
SOCKET=/tmp/mysql.sock
MYSQLD=/usr/local/mysql/libexec/mysqld
PIDFILE=/usr/local/mysql/var/`hostname`.pid
CHROOTUID=/usr/bin/chrootuid
echo -n " mysql"
case "$1" in
start)
        rm -rf ${SOCKET}
        nohup ${CHROOTUID} ${CHROOT_MYSQL} mysql ${MYSQLD} >/dev/null 2>&1 &
        sleep 5 && ln ${CHROOT_MYSQL}/${SOCKET} ${SOCKET}
        ;;
stop)
        kill `cat ${CHROOT_MYSQL}/${PIDFILE}`
        rm -rf ${CHROOT_MYSQL}/${SOCKET}
        ;;
*)
        echo ""
        echo "Usage: `basename $0` {start|stop}" >&2
        exit 64
        ;;
esac
exit 0
文件位于/etc/rc.d/init.d下,名为mysqld,注意要可执行!
#chmod +x /etc/rc.d/init.d/mysqld

结论:尽管我们不能做到100%的安全,但是这些措施可以保护我们的系统更加安全!


                                       
参考资料:Artur Maj的《Securing MySQL》
          xuzhikun的《MySQL数据库安全配置》一文
          晏子翻译的《MySQL中文参考手册》
上海狮王 发表于 2004-9-25 20:33:51 | 显示全部楼层
谢谢,我比较喜欢新的文章
回复

使用道具 举报

ejew 发表于 2004-9-30 02:19:36 | 显示全部楼层
老文章 也回味 一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-11-17 00:32 , Processed in 0.024691 second(s), 4 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表