Mysql安全设置案例一

一、账户权限

mysql中存在4个控制权限的表,分别为

1. mysql.USER表
2. mysql.DB表
3. mysql.TABLES_PRIV表
4. mysql.COLUMNS_PRIV表
  • 要注意的是,Mysql中有一个数据库”information_schema“,似乎里面保存的也是一些权限信息,但是要明白的是,这个数据库”information_schema“是为系统管理员提供元数据的一个简便方式,它实际上是一个视图,可以理解为对Mysql中的一个信息的封装,对于Mysql主程序来说,身份认证和授权的信息的来源只有一个,就是”mysql“。

在我们进行数据库连接、登录的时候,mysql权限表的验证过程为: 
1. 先从user表中的:

1) Host
2) User
3) Password
  • 这3个字段中判断连接的ip、用户名、密码是否存在,存在则通过验证。 

2. 通过身份认证后,进行权限分配,按照下面的顺序进行验证。

1) user
2) db
3) tables_priv
4) columns_priv
  • 即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db,tables_priv,columns_priv 

如果全局权限表user对应的权限为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限 
如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推。逐级下降

用自己的话讲就是因为查找他们权限是否配置好根据情况查看mysql这个数据库中的user,db,tables_priv,columns_pri,一旦在某个级别设置好了权限就不需要网下一级去看他是否存在权限了,因为下面一级的表都不会显示,这是为了防止数据库数据冗余。就是例如你设置的是所有数据库及表的权限的话,到时候就直接select * from user;就可以查看对应的程序啦 
PNNSfK.md.png

对于Mysql中的账户权限相关的安全配置,总结如下: 
1. 针对每个网站建立一个单独的账户 
2. 为每个网站单独建立一个专属数据库(虽然DEDE、DZ普通采用表前缀的方法来实现”一库多站”,但好的做法还是”一库一站”) 
3. 按照user->db->tables_priv->columns_pri的顺序进行细粒度的权限控制 
4. 为每个用户单独配置一个专属数据库,保证当前用户的所有操作只能发生在它自己的数据库中,防止SQL注入发生后,黑客通过注入点访问到系统表,也就是说安全维护做得好发生注入你也看不到有用的信息。

账户权限安全配置需要的常用命令 

  • 1)新建一个用户并给予相应数据库的权限
grant select,insert,update,delete,create,drop privileges on 数据库名字.表名 to user@localhost identified by 'passwd';    //如果是*号就是代表全部*.*代表所有数据库下的全部表名
grant all privileges on database.* to user@localhost identified by 'passwd';
  • 2) 刷新权限
flush privileges;
  • 3)显示授权
show grants;  //这句话只显示当前登录用户的权限
  • 4) 移除授权
revoke delete on *.* from 'user'@'localhost';
  • 5) 删除用户
drop user 'user'@'localhost';
  • 6) 给用户改名
rename user 'jack'@'%' to 'jim'@'%';``
  • 7) 给用户改密码
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');

二、安全加固

1.修改root用户口令,删除空口令

缺省安装的MySQL的root用户是空密码的,为了安全起见,必须修改为强密码,所谓的强密码,至少8位,由字母、数字和符号组成的不规律密码。使用MySQL自带的命令mysaladmin修改root密码,同时也可以登陆数据库,修改数据库mysql下的user表的字段内容。

a.登录mysql

 /usr/local/mysql/bin/mysql -u root -p 123456

b.进入到mysql控制台后你会看到四个数据库information_schema,test,mysql,ftp(这些是针对mapn而言的)

  修改数据库mysql中的user表:

  update user set password=password("abcdef") where user="root";

c.#mysql> flush privileges; //强制刷新内存授权表,否则用的还是在内存缓冲的口令

2.删除默认数据库和数据库用户

一般情况下,MySQL数据库安装在本地,并且也只需要本地的php脚本对mysql进行读取,所以很多用户不需要,尤其是默认安装的用户。MySQL初始化后会自动生成空用户和test库,进行安装的测试,这会对数据库的安全构成威胁,有必要全部删除,最后的状态只保留单个root即可,当然以后根据需要增加用户和数据库。

#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管理员帐号

4.关于密码的管理

密码是数据库安全管理的一个很重要因素,不要将纯文本密码保存到数据库中。如果你的计算机有安全危险,入侵者可以获得所有的密码并使用它们。相反,应使用 MD5()、SHA1()或单向哈希函数。也不要从词典中选择密码,有专门的程序可以破解它们,请选用至少八位,由字母、数字和符号组成的强密码。在存取密码时,使用mysql的内置函数password()的sql语句,对密码进行加密后存储。例如以下方式在users表中加入新用户。

#mysql> insert into users values (1,password(1234),’test’);

5.使用独立用户运行msyql

绝对不要作为使用root用户运行MySQL服务器。这样做非常危险,因为任何具有FILE权限的用户能够用root创建文件(例如,~root/.bashrc)。mysqld拒绝使用root运行,除非使用–user=root选项明显指定。应该用普通非特权用户运行 mysqld。正如前面的安装过程一样,为数据库建立独立的linux中的mysql账户,该账户用来只用于管理和运行MySQL。

要想用其它Unix用户启动mysqld,,增加user选项指定/etc/my.cnf选项文件或服务器数据目录的my.cnf选项文件中的[mysqld]组的用户名。

#vi /etc/my.cnf

[mysqld]

user=mysql

该命令使服务器用指定的用户来启动,无论你手动启动或通过mysqld_safe或mysql.server启动,都能确保使用mysql的身份。也可以在启动数据库是,加上user参数。

# /usr/local/mysql/bin/mysqld_safe –user=mysql &

作为其它linux用户而不用root运行mysqld,你不需要更改user表中的root用户名,因为MySQL账户的用户名与linux账户的用户名无关。确保mysqld运行时,只使用对数据库目录具有读或写权限的linux用户来运行。

6.禁止远程连接数据库

在命令行netstat -ant下看到,默认的3306端口是打开的,此时打开了mysqld的网络监听,允许用户远程通过帐号密码连接数本地据库,默认情况是允许远程连接数据的。为了禁止该功能,启动skip-networking,不监听sql的任何TCP/IP的连接,切断远程访问的权利,保证安全性。假如需要远程管理数据库,可通过安装PhpMyadmin来实现。假如确实需要远程连接数据库,至少修改默认的监听端口,同时添加防火墙规则,只允许可信任的网络的 mysql监听端口的数据通过。

# vi /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.限制连接用户的数量

数据库的某用户多次远程连接,会导致性能的下降和影响其他用户的操作,有必要对其进行限制。可以通过限制单个账户允许的连接数量来实现,设置my.cnf 文件的mysqld中的max_user_connections变量来完成。GRANT语句也可以支持资源控制选项来限制服务器对一个账户允许的使用范围。

#vi /etc/my.cnf

[mysqld]

max_user_connections= 2

8.用户目录权限限制

默认的mysql是安装在/usr/local/mysql,而对应的数据库文件在/usr/local/mysql/var目录下,因此,必须保证该目录不能让未经授权的用户访问后把数据库打包拷贝走了,所以要限制对该目录的访问。确保mysqld运行时,只使用对数据库目录具有读或写权限的linux 用户来运行。

# chown -R root /usr/local/mysql/ //mysql主目录给root

# chown -R rotot  /usr/local/mysql/var //确保数据库目录权限所属mysql用户

9.命令历史记录保护

数据库相关的shell操作命令都会分别记录在.bash_history,如果这些文件不慎被读取,会导致数据库密码和数据库结构等信息泄露,而登陆数据库后的操作将记录在.mysql_history文件中,如果使用update表信息来修改数据库用户密码的话,也会被读取密码,因此需要删除这两个文件,同时在进行登陆或备份数据库等与密码相关操作时,应该使用-p参数加入提示输入密码后,隐式输入密码,建议将以上文件置空。

# rm .bash_history .mysql_history //删除历史记录

# ln -s /dev/null .bash_history //将shell记录文件置空

# ln -s /dev/null .mysql_history //将mysql记录文件置空

10.禁止MySQL对本地文件存取

在mysql中,提供对本地文件的读取,使用的是load data local infile命令,默认在5.0版本中,该选项是默认打开的,该操作令会利用MySQL把本地文件读到数据库中,然后用户就可以非法获取敏感信息了,假如你不需要读取本地文件,请务必关闭。应该禁止MySQL中用“LOAD DATA LOCAL INFILE”命令。网络上流传的一些攻击方法中就有用它LOAD DATA LOCAL INFILE的,同时它也是很多新发现的SQL Injection攻击利用的手段!黑客还能通过使用LOAD DATALOCAL INFILE装载“/etc/passwd”进一个数据库表,然后能用SELECT显示它,这个操作对服务器的安全来说,是致命的。可以在my.cnf中添加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. Mysqld安全相关启动选项

–local-infile[={0|1}]

如果用–local-infile=0启动服务器,则客户端不能使用LOCAL in LOAD DATA语句。

–old-passwords

强制服务器为新密码生成短(pre-4.1)密码哈希。当服务器必须支持旧版本客户端程序时,为了保证兼容性这很有用。

(OBSOLETE) –safe-show-database

在以前版本的MySQL中,该选项使SHOW DATABASES语句只显示用户具有部分权限的数据库名。在MySQL 5.1中,该选项不再作为现在的 默认行为使用,有一个SHOW DATABASES权限可以用来控制每个账户对数据库名的访问。

–safe-user-create

如果启用,用户不能用GRANT语句创建新用户,除非用户有mysql.user表的INSERT权限。如果你想让用户具有授权权限来创建新用户,你应给用户授予下面的权限:

mysql> GRANT INSERT(user) ON mysql.user TO ‘user_name’@'host_name’;

这样确保用户不能直接更改权限列,必须使用GRANT语句给其它用户授予该权限。

–secure-auth

不允许鉴定有旧(pre-4.1)密码的账户。

12.information_schema 安全

在用户角度来看,INFORMATION_SCHEMA只是一个以插件方式存在的存储引擎,编译安装的时候

–disable-information-schema 就行了

added TRIGGER_ACL check for I_S.TRIGGERS

猜你喜欢

转载自blog.csdn.net/wz_cow/article/details/82356188