资源描述
部署方案
一. Mysql数据库所处环境的设置:
1)、修改root用户口令,删除空口令
# /usr/local/mysql/bin/mysqladmin -u root password “upassword” //使用mysqladmin
#mysql> use mysql;
#mysql> update user set password=password('upassword') where user='root';
#mysql> flush privileges; //强制刷新内存授权表,否则用的还是在内存缓冲的口令
2)、删除默认数据库和数据库用户
#mysql> show databases;
#mysql> drop database test; //删除数据库test
#use mysql;
#delete from db; //删除存放数据库的表信息,因为还没有数据库信息。
#mysql> delete from user where not (user='root') ; // 删除初始非root的用户
#mysql> delete from user where user='root' and password=''; //删除空密码的root,尽量重复操作
Query OK, 2 rows affected (0.00 sec)
#mysql> flush privileges; //强制刷新内存授权表。
3)、改变默认mysql管理员帐号
mysql> update user set user="newroot" where user="root"; //改成不易被猜测的用户名
mysql> flush privileges;
4)、关于密码的管理
#mysql> insert into users values (1,password(1234),'test');
5)、使用独立用户运行msyql
#vim /etc/f
[mysqld]
user=mysql
6)、禁止远程连接数据库
# vim /etc/my.cf
将#skip-networking注释去掉。
# /usr/local/mysql/bin/mysqladmin -u root -p shutdown //停止数据库
#/usr/local/mysql/bin/mysqld_safe --user=mysql & //后台用mysql用户启动mysql
7)、限制连接用户的数量
#vim /etc/f
[mysqld]
max_user_connections 2
8)、用户目录权限限制
# chown -R root /usr/local/mysql/ //mysql主目录给root
# chown -R mysql.mysql /usr/local/mysql/var //确保数据库目录权限所属mysql用户
9)、命令历史记录保护
# rm .bash_history .mysql_history //删除历史记录
# ln -s /dev/null .bash_history //将shell记录文件置空
# ln -s /dev/null .mysql_history //将mysql记录文件置空
10)、禁止MySQL对本地文件存取
# vi sqlfile.txt
1,sszng,111
2,sman,222
#mysql> load data local infile 'sqlfile.txt' into table users fields terminated by ','; //读入数据
#mysql> select * from users;
+--------+------------+----------+
| userid | username | password |
+--------+------------+----------+
| 1 | sszng | 111 |
| 2 | sman | 222 |
+--------+------------+----------+
可以在f中添加local-infile=0,或者加参数local-infile=0启动mysql。
#/usr/local/mysql/bin/mysqld_safe --user=mysql --local-infile=0 &
#mysql> load data local infile 'sqlfile.txt' into table users fields terminated by ',';
#ERROR 1148 (42000): The used command is not allowed with this MySQL version
--local-infile=0选项启动mysqld从服务器端禁用所有LOAD DATA LOCAL命令,假如需要获取本地文件,需要打开,但是建议关闭。
11)、MySQL服务器权限控制
#mysql> load data infile 'sqlfile.txt' into table loadfile.users fields terminated by ',';
Query OK, 4 rows affected (0.00 sec) //读取本地信息sqlfile.txt'
Records: 4 Deleted: 0 Skipped: 0 Warnings: 0
#mysql> update user set File_priv='N' where user='root'; //禁止读取权限
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges; //刷新授权表
Query OK, 0 rows affected (0.00 sec)
#mysql> load data infile 'sqlfile.txt' into table users fields terminated by ','; //重登陆读取文件
#ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) //失败
# mysql> select * from loadfile.users into outfile 'test.txt' fields terminated by ',';
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
为了安全起见,随时使用SHOW GRANTS语句检查查看谁已经访问了什么。然后使用REVOKE语句删除不再需要的权限。
二.保证数据目录访问的安全
以下是对权限的修正,使得只用服务器用户可访问它们:
1. 进入该目录
% cd DATADIR
2. 设置所有在数据目录下的文件属主为由用于运行服务器的账号拥有(以root执行这步)。下列命令之一可改变属主:
1)# chown mysqladm.mysqlgrp .
2)# find . -follow -type d -print | xargs chown mysqladm.mysqlgrp
3. 设置数据目录和数据库目录的模式使得他们只能由mysqladm读取,可阻止其他用户访问自己的数据库目录的内容。下列命令之一以root或mysqladm身份运行。
1)% chmod -R go-rwx .
2)% find . -follow -type d -print | xargs chmod go-rwx
4. 数据目录内容的属主和模式为mysqladm设置。保证总是以mysqladm用户运行服务器,因为现在这是唯一由访问数据库目录权限的用户(除root)。
在完成这些设置后,最终应该得到下面的数据目录权限:
% ls –l
total 10148
drwxrwx--- 11 mysqladm mysqlgrp 1024 May 8 12:20 .
drwxr-xr-x 22 root wheel 512 May 8 13:31 ..
drwx------ 2 mysqladm mysqlgrp 512 Apr 16 15:57 menagerie
drwx------ 2 mysqladm mysqlgrp 512 Jan 25 20:40 mysql
drwx------ 7 mysqladm mysqlgrp 512 Aug 31 1998 sql-bench
drwx------ 2 mysqladm mysqlgrp 1536 May 6 06:11 test
drwx------ 2 mysqladm mysqlgrp 1024 May 8 18:43 tmp
三、保证网络访问的安全
给数据库用户加口令,一下有三种方法:
1)在shell提示符下用MySQLadmin命令来改root用户口令:
shell>MySQLadmin -uroot password test
2)用set password修改口令:
MySQL> set password for root@localhost=password('test');
3)直接修改user表的root用户口令:
mysql> use MySQL;
MySQL> update user set password=password('test') where user='root';
MySQL> flush privileges;
我们还看到user为空的匿名用户,为了安全起见删除它:
MySQL> delete from user where user='';
删除Host字段为%的记录:
MySQL>delete from user where host='%';
删除匿名用户:
MySQL> delete from user where user='';
四、数据库加密
双向加密
下面是一个简单的实例:
mysql> INSERT INTO users (username, password) VALUES ('joe', ENCODE('guessme', 'abracadabra'));
Query OK, 1 row affected (0.14 sec)
其中,Joe的密码是guessme,它通过密钥abracadabra被加密。要注意的是,加密完的结果是一个二进制字符串,如下所示:
mysql> SELECT * FROM users WHERE username='joe';
+----------+----------+
| username | password |
+----------+----------+
| joe | ¡?i??!? |
+----------+----------+
1 row in set (0.02 sec)
下面是它的使用方法:
mysql> SELECT DECODE(password, 'abracadabra') FROM users WHERE username='joe';
+---------------------------------+
| DECODE(password, 'abracadabra') |
+---------------------------------+
| guessme |
+---------------------------------+
1 row in set (0.00 sec)
很容易看到它在Web应用程序里是如何运行的——在验证用户登录的时候,DECODE()会用网站专用的密钥解开保存在数据库里的密码,并和用户输入的内容进行对比。若把PHP用作自己的脚本语言,那么可以像下面这样进行查询:
$query = "SELECT COUNT(*) FROM users WHERE username='$inputUser' AND DECODE(password, 'abracadabra') = '$inputPass'";?>
提示:虽然ENCODE()和DECODE()这两个函数能够满足大多数的要求,但是有的时候需要使用强度更高的加密手段。在这种情况下,则使用AES_ENCRYPT()和AES_DECRYPT()函数,它们的工作方式是相同的,但是加密强度更高。
单项加密
下面是如何使用它的一个简单例子:
mysql> INSERT INTO users (username, password) VALUES ('joe', MD5('guessme'));
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM users WHERE username='joe';
+----------+----------------------------------+
| username | password |
+----------+----------------------------------+
| joe | 81a58e89df1f34c5487568e17327a219 |
+----------+----------------------------------+
1 row in set (0.02 sec)
测试用户输入的内容是否与已经保存的密码匹配的方法是取得用户输入密码的MD5校验码,并将它与已经保存的密码进行比对,像下面这样:
mysql> SELECT COUNT(*) FROM users WHERE username='joe' AND password=MD5('guessme');
+----------+
| COUNT(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
下面一个例子说明如何使用它:
mysql> INSERT INTO users (username, password) VALUES ('joe', ENCRYPT('guessme', 'ab'));
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM users WHERE username='joe';
+----------+---------------+
| username | password |
+----------+---------------+
| joe | ab/G8gtZdMwak |
+----------+---------------+
1 row in set (0.00 sec)
结果是:
mysql> SELECT COUNT(*) FROM users WHERE username='joe' AND password=ENCRYPT('guessme', 'ab');
+----------+
| COUNT(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
提示:ENCRYPT()只能用在*NIX系统上,因为它需要用到底层的crypt()库。
五、数据库备份与还原
1、mysqldump
1.1 备份
使用以下 SQL 来备份 MyISAM 表:
/usr/local/mysql/bin/mysqldump -uyejr -pyejr --default-character-set=utf8 --opt --extended-insert=false \
--triggers -R --hex-blob -x db_name > db_name.sql
使用以下 SQL 来备份 Innodb 表:
/usr/local/mysql/bin/mysqldump -uyejr -pyejr --default-character-set=utf8 --opt --extended-insert=false \
--triggers -R --hex-blob --single-transaction db_name > db_name.sql
1.2 还原
用 mysqldump 备份出来的文件是一个可以直接倒入的 SQL 脚本,有两种方法可以将数据导入。
· 直接用 mysql 客户端
例如:
/usr/local/mysql/bin/mysql -uyejr -pyejr db_name < db_name.sql
· 用 SOURCE 语法
其实这不是标准的 SQL 语法,而是 mysql 客户端提供的功能,例如:
SOURCE /tmp/db_name.sql;
这里需要指定文件的绝对路径,并且必须是 mysqld 运行用户(例如 nobody)有权限读取的文件。
2、 mysqlhotcopy
2.1 备份
mysqlhotcopy 支持一次性拷贝多个数据库,同时还支持正则表达。以下是几个例子:
root#/usr/local/mysql/bin/mysqlhotcopy -h=localhost -u=yejr -p=yejr db_name /tmp (把数据库目录 db_name 拷贝到 /tmp 下)
root#/usr/local/mysql/bin/mysqlhotcopy -h=localhost -u=yejr -p=yejr db_name_1 ... db_name_n /tmp
root#/usr/local/mysql/bin/mysqlhotcopy -h=localhost -u=yejr -p=yejr db_name./regex/ /tmp
perldoc /usr/local/mysql/bin/mysqlhotcopy
2.2 还原
mysqlhotcopy 备份出来的是整个数据库目录,如下例:
root#cp -rf db_name /usr/local/mysql/data/
root#chown -R nobody:nobody /usr/local/mysql/data/ (将 db_name 目录的属主改成 mysqld 运行用户)
3、 SQL 语法备份
3.1 备份
例子:
BACK TABLE tbl_name TO '/tmp/db_name/';
SELECT INTO OUTFILE 则是把数据导出来成为普通的文本文件,可以自定义字段间隔的方式,方便处理这些数据。例子:
SELECT INTO OUTFILE '/tmp/db_name/tbl_name.txt' FROM tbl_name;
3.2 恢复
用 BACKUP TABLE 方法备份出来的文件,可以运行 RESTORE TABLE 语句来恢复数据表。例子:
RESTORE TABLE FROM '/tmp/db_name/';
用 SELECT INTO OUTFILE 方法备份出来的文件,可以运行 LOAD DATA INFILE 语句来恢复数据表。例子:
LOAD DATA INFILE '/tmp/db_name/tbl_name.txt' INTO TABLE tbl_name;
六 触发器在mysql数据库安全的应用
1)将信息检索系统数据库中的记录设为“只读
触发器设计如下:
Create trigger 触发器名
On 所要保护的表
Before update,insert,delete
For each row
Begin
……#可以显示’forbid modify this table!’
……#可以编写记录日志功能的代码
end
2)自定义权限表过滤非法操作
该触发器的设计实现如下:
Create trigger 触发器名
On 所要保护的表
After delete
For each row
Begin
If((select delete_of from 自定义权限表名where cuser_id=user_id(@currentuse))!=1)
Rollback transaction #表明是非法删除进行回滚
……#可进行一些日志记录的工作
……#可以发现非法用户名及其id,记录或直接删除用户
end
展开阅读全文