MySQL安全配置学习笔记

远程访问

将端口3306添加到防火墙:

Centos 7为firewall

firewall-cmd --permanent --add-port=13306/tcp #亲测可用

开启centos 6 防火墙3306端口方法

1)打开防火墙配置文件

vi /etc/sysconfig/iptables

2)增加下面一行

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

service iptables restart

 

安全配置

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

对于Mysql中的账户权限相关的安全配置,总结如下:

1. 针对每个网站建立一个单独的账户

2. 为每个网站单独建立一个专属数据库(虽然DEDE、DZ普通采用表前缀的方法来实现"一库多站",但好的做法还是"一库一站") 

3. 按照user->db->tables_priv->columns_pri的顺序进行细粒度的权限控制

4. 为每个用户单独配置一个专属数据库,保证当前用户的所有操作只能发生在它自己的数据库中,防止SQL注入发生后,黑客通过注入点访问到系统表

 

对Mysql的访问IP的限制,可以从应用层和主机层来分别达到目的

1. 主机层:         

1) windows可以通过windows防火墙         

2) Linux下可以通过iptables //Centos 6及以下为iptables 来限制允许访问mysql端口的IP地址 //只允许指定的IP进行访问 iptables -A INPUT -p tcp -s xxxx.xxxx.xxxx.xxxx/24 --dport 3306 -j ACCEPT iptables -A INPUT -p tcp -s xxxx.xxxx.xxxx.xxxx/24 --dport 3306 -j ACCEPT .. iptables -P INPUT DROP

可以看到,这种方法的缺点是硬编码导致灵活性低,如果mysql的默认端口3306被修改了(例如8890),则这条iptables规则也需要相应的修改

对于mysql运行账号的磁盘ACL配置,我们可以遵循以下原则

1. mysql运行账号需要给予程序所在目录的读取权限,以及data目录的读取和写入权限,保证mysql的正常运行

2. 不容许给予其他目录的写入和执行权限,特别是有网站的,这可以有效防御针对mysql的提权、或者webshell提权         

1) udf提权         

2) 系统关键目录、注册表写入启动文件 

3. 取消mysql运行账户对于cmd,sh等一些程序的执行权限,这可以防御当mysql核心帐号被黑客获取后进一步提权         

1) root账户被泄露     由于对cmd、sh等关键程序进行了权限控制,黑客无法继续深入操作系统提权

所以针对mysql程序帐号进行磁盘ACL控制,防止mysql越权读/写/执行非mysql目录下的文件。

目前基于SQL注入检测、防御的的数据库防火墙大概有以下几个:

1. 安华金和数据库防火墙系统(Xsecure-DBFirewall)

2. Snort入侵检测系统 能针对指定端口进行正则特征匹配方式的SQL注入检测

3. Java/J2EE 过滤器 对于J2ee的WEB应用来说,可以在HTTP请求上部署过滤器,并将SQL注入检测规律写在过滤器中

4. druid-sql-wall开源SQL检测、阻断系统

mysqld安全相关启动选项

1. --local-infile[={0|1}] 如果用–local-infile=0启动服务器,则客户端不能使用LOCAL in LOAD DATA语句,防止基于注入的直接文件读取数据泄漏 

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

3. (OBSOLETE) –safe-show-database         

1) 在MySQL 5.1以前版本的MySQL中,该选项使SHOW DATABASES语句只显示用户具有部分权限的数据库名         

2) 在MySQL 5.1中,该选项不再作为现在的 默认行为使用,有一个SHOW DATABASES权限可以用来控制每个账户对数据库名的访问。

4. --safe-user-create 如果启用,用户不能用GRANT语句创建新用户,除非用户有mysql.user表的INSERT权限。如果你想让用户具有授权权限来创建新用户,你应给用户授予下面的权限: mysql> GRANT INSERT(user) ON mysql.user TO "user_name"@"host_name";这样确保用户不能直接更改权限列,必须使用GRANT语句给其它用户授予该权限。

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

6. --skip-grant-tables 这个选项导致服务器根本不使用权限系统。这给每个人以完全访问所有的数据库的权力,这个选项常常在发生了忘记了msyql密码的情况使用这个方式在本机"无密码登录mysql"通过执行mysqladmin flush-privileges或mysqladmin eload命令,或执行FLUSH PRIVILEGES语句,你能告诉一个正在运行的服务器再次开始使用授权表。

忘记密码操作流程:

a:kill mysql 进行, ps -ef |grep mysql 或是在数据目录下localhost.localdomain.pid的文件中查看进程号

b:在mysql/bin下启动mysqld_safe -uroot --skip-grant-tables

c:update mysql.user set password=passwrod('123456') where user='root' and host='%'

d:flush privileges 因是为直接更新的表,所以需要重新加载权限表

 

7. --skip-name-resolve 主机名不被解析。所有在授权表的Host的列值必须是IP号或localhost 8. --skip-networking 在网络上不允许TCP/IP连接。所有到mysqld的连接必须经由Unix套接字进行 9. --skip-show-database 使用该选项,只允许有SHOW DATABASES权限的用户执行SHOW DATABASES语句,该语句显示所有数据库名。不使用该选项,允许所有用户执行SHOW DATABASES,但只显示用户有SHOW DATABASES权限或部分数据库权限的数据库名。请注意全局权限指数据库的权限。

10.--ssl

允许SSL连接,还必须指定--ssl-ca、--ssl-cert 和--ssl-key选项,如果不想启用,则可以指定为--skip-ssl或--ssl=0,例如:

grant select on *.* to 'user'@'host' require ssl;

--ssl-ca=file_name含可信ssl ca的清单文件的路径

--ssl-cert=file_name ssl证书文件名,用于建立安全连接

--ssl-key=file_name ssl密钥文件名,用于建立安全连接

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章