网站开发:MySQL安全优化
TIME:2018-09-30
一、数据库相关
1、 MySQL版本的选择
在正式生产环境中,建议使用5.6或以上系列的版本(5.7不建议,曾经用过这个版本,问题有点多)。
2、 运行用户与端口的配置
2.1、确保MySQL运行用户为一般用户
确保mysql用户登录shell为nologin
01
|
[root@localhost ~]# usermod -s /sbin/nologin mysql
|
对MySQL运行用户降权,以普通用户身份运行MySQL
01
02
03
04
05
06
|
[root@localhost ~]# vim /usr/local/mysql/my.cnf
user = mysql
[root@localhost ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@localhost ~]#
|
如果是用命令启动的,则在参数后面加上--user=mysql即可。
注意存放目录权限:
01
|
[root@localhost ~]# chown -R mysql.mysql /data/mysql/
|
按照以上操作后,mysql就会以用户mysql身份来启动mysqld,并且会以该用户身份来接受连接。以上mysql用户也可以改为其它用户。(不改变safe_mysqld是必要的。)
2.2、修改默认端口
建议修改默认端口3306,改为其他的一些端口。
01
02
03
04
05
06
07
|
[root@localhost ~]# vim /usr/local/mysql/my.cnf
[mysqld]
port = 3389
[root@localhost ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@localhost ~]#
|
3、 开启binlog
开启mysql二进制日志,在误删除数据的情况下,可以通过二进制日志恢复到某个时间点
3.1、登录MySQL查看bin-log状态
登录MySQL后,输入show variables like '%log_bin%';查看到binlog日志为OFF关闭状态;
3.2、开启binlog
先quit退出MySQL
修改MySQL配置文件my.cnf,加入如下两行
01
02
03
|
[root@localhost ~]# vim /usr/local/mysql/my.cnf
server-id = 1
log_bin =/data/mysql/mysql-bin
|
server-id标识着单个节点的id。在主从或者集群中会使用到,不能与其他节点相同。这里只有一台机,随机设置一个数字就好了。
第二行指定bin-log的名字与存储路径。
3.3、重启让配置生效
01
02
03
04
|
[root@localhost ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@localhost ~]#
|
查看数据库日志目录:
注意:每次服务器(数据库)重启,服务器会调用flush logs;,新创建一个binlog日志
由于我之前重启过数据库,因此这里有mysql-bin.000001到mysql-bin.000003这三个文件。这里你们看到的应该只有mysql-bin.000001和mysql-bin.index两个文件
此时再次进入MySQL,查看binlog日志的状态。显示binlog日志为ON开启状态
到这里,binlog日志开启成功。
4、 用户认证和授权
4.1、删除匿名账号和空口令账号
登录MySQL,查看现在的账号情况
一般我们在数据库安装之后就会删除匿名账户如下:
01
|
mysql>delete from mysql.user where user='';
|
如上图所示,User这一栏里面都有值,没发现空的,所以没有匿名账户。这一步略过。
发现Password栏有三行空的,所以本机有空口令账号root。(危险)
我们为空口令账户设置密码
01
02
03
|
mysql>update mysql.user set password=password('$MYSQL_PASSWORD')where User="root" and Host="localhost";
mysql>update mysql.user set password=password('$MYSQL_PASSWORD')where User="root" and Host="127.0.0.1";
mysql>update mysql.user set password=password('$MYSQL_PASSWORD')where User="root" and Host="::1";
|
设置完毕后,再查看如下:
此时已经没有空口令和匿名账户了。
4.2、禁止root账户远程访问
Root权限太高,为了安全,一般我们禁止root账户从远程访问,root账户只允许从本地访问。
4.2.1、赋予localhost的root账户最高权限(以后维护用)。
查看localhost的root权限:
一般,localhost的root默认具有所有的权限,如上图(默认)。如果没有,则按照以下命令赋予最高权限:
01
02
|
mysql>grant all privileges on *.*to root@localhost identifiedby 'password' with grant option;
mysql> flush priveleges;
|
4.2.2、禁止root从远程访问,将主机为%并且用户为root行的删掉。
01
02
|
mysql>delete from mysql.user where User='root' and Host='%';
Query OK, 1 row affected (0.00 sec)
|
或者
01
02
|
mysql>update user set host ="localhost" where user ="root" and host ="%";
mysql> flushprivileges;
|
此时,你已经无法通过root账户进行远程访问数据库了。
除了root账户外,其他账户也应该严格控制,尽量不要放开远程访问,如果必须的话,应严格控制权限。根据业务需要,配置其需要的最小权限。
如果不需要,应禁止远程访问
禁止网络连接,防止猜解密码攻击、溢出攻击、和嗅探攻击。
注意: 仅限于应用和数据库在同一台主机的情况。
如果数据库不需要远程访问,可以禁止远程 TCP/IP 连接,通过在 MySQL 服务器的启动参数中添加--skip-networking参数使 MySQL 服务不监听任何 TCP/IP 连接,增加安全性。
4.3、建立普通账户并授权
Root账户已经无法远程进行访问了,但是我们很多业务是需要远程访问的,所以为业务新建一个普通账户,并赋予他们需要的最小权限。权限最小化原则。
4.3.1、创建用户
创建用户有三种方式:
方式一:(create命令创建用户)
01
02
|
mysql>create user 'test1'@'%' identifiedby '123';
Query OK, 0rows affected (0.08 sec)
|
如果用户已经存在会报错。
01
02
|
mysql>create user 'test1'@'%' identifiedby '123';
ERROR 1396 (HY000): OperationCREATE USER failedfor 'test1'@'%'
|
创建成功后,查看用户如下:
方式二:(insert命令插入用户,禁止使用此方式)
01
02
|
mysql>insert into mysql.user (Host,User,Password)Values('%','test2',PASSWORD('123'));
ERROR 1364 (HY000): Field'ssl_cipher' doesn't have adefault value
|
直接insert报错,因为mysql默认禁止直接insert添加用户。如果还是要改,可以修改配置文件:
01
02
|
[root@localhost doubles]# vim /usr/local/mysql/my.cnf
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
定位到上面这一行,这一行指定了mysql为严格模式,为了安全,严格模式是禁止使用insert形式创建mysql用户的,如果坚持还是要用,把配置修改为:
01
|
sql_mode=NO_ENGINE_SUBSTITUTION
|
然后重启服务
01
|
[root@localhost doubles]# /etc/init.d/mysqld restart
|
再次插入成功。
01
02
|
mysql>insert into mysql.user (Host,User,Password)Values('%','test2',PASSWORD('123'));
Query OK, 1 row affected, 3 warnings (0.00 sec)
|
改完配置再次插入成功。
方式三:(grant命令创建用户)
01
02
03
04
|
mysql>grant select on *.*to 'test3'@'%' identifiedby '123';
Query OK, 0rows affected (0.00 sec)
mysql> flushprivileges;
Query OK, 0rows affected (0.00 sec)
|
这种方式连同授权一起了。
查看权限发现test3已经授权成功,只有select权限,如下图:
4.4、为新建用户授权
遵循权限最小化原则。
4.4.1、查看用户权限:
方法一:
像上面一样,用select查询
01
|
mysql>select *from mysql.user where User='test3'\G;
|
方法二: