一、数据库相关

1、 MySQL版本的选择

在正式生产环境中,建议使用5.6或以上系列的版本(5.7不建议,曾经用过这个版本,问题有点多)。

2、 运行用户与端口的配置

2.1、确保MySQL运行用户为一般用户

确保mysql用户登录shell为nologin

[root@localhost ~]# usermod -s /sbin/nologin mysql

对MySQL运行用户降权,以普通用户身份运行MySQL

[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即可。

注意存放目录权限:

[root@localhost ~]# chown -R mysql.mysql /data/mysql/

按照以上操作后,mysql就会以用户mysql身份来启动mysqld,并且会以该用户身份来接受连接。以上mysql用户也可以改为其它用户。(不改变safe_mysqld是必要的。)

2.2、修改默认端口

建议修改默认端口3306,改为其他的一些端口。

[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,加入如下两行

[root@localhost ~]# vim /usr/local/mysql/my.cnf
server-id = 1
log_bin = /data/mysql/mysql-bin

server-id标识着单个节点的id。在主从或者集群中会使用到,不能与其他节点相同。这里只有一台机,随机设置一个数字就好了。

第二行指定bin-log的名字与存储路径。

3.3、重启让配置生效

[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,查看现在的账号情况

一般我们在数据库安装之后就会删除匿名账户如下:

mysql> delete from mysql.user where user='';

如上图所示,User这一栏里面都有值,没发现空的,所以没有匿名账户。这一步略过。

发现Password栏有三行空的,所以本机有空口令账号root。(危险)

我们为空口令账户设置密码

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默认具有所有的权限,如上图(默认)。如果没有,则按照以下命令赋予最高权限:

mysql> grant all privileges on *.* to root@localhost identified by 'password' with grant option;
mysql> flush priveleges;

4.2.2、禁止root从远程访问,将主机为%并且用户为root行的删掉。

mysql> delete from mysql.user where User='root' and Host='%';
Query OK, 1 row affected (0.00 sec)

或者

mysql> update user set host = "localhost" where user = "root" and host = "%";
mysql> flush privileges;

此时,你已经无法通过root账户进行远程访问数据库了。

除了root账户外,其他账户也应该严格控制,尽量不要放开远程访问,如果必须的话,应严格控制权限。根据业务需要,配置其需要的最小权限。

如果不需要,应禁止远程访问

禁止网络连接,防止猜解密码攻击、溢出攻击、和嗅探攻击。

注意: 仅限于应用和数据库在同一台主机的情况。

如果数据库不需要远程访问,可以禁止远程 TCP/IP 连接,通过在 MySQL 服务器的启动参数中添加--skip-networking参数使 MySQL 服务不监听任何 TCP/IP 连接,增加安全性。

4.3、建立普通账户并授权

Root账户已经无法远程进行访问了,但是我们很多业务是需要远程访问的,所以为业务新建一个普通账户,并赋予他们需要的最小权限。权限最小化原则。

4.3.1、创建用户

创建用户有三种方式:

方式一:(create命令创建用户)
mysql> create user 'test1'@'%' identified by '123';
Query OK, 0 rows affected (0.08 sec)

如果用户已经存在会报错。

mysql> create user 'test1'@'%' identified by '123';
ERROR 1396 (HY000): Operation CREATE USER failed for 'test1'@'%'

创建成功后,查看用户如下:

方式二:(insert命令插入用户,禁止使用此方式)
mysql> insert into mysql.user (Host,User,Password) Values('%','test2',PASSWORD('123'));
ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value

直接insert报错,因为mysql默认禁止直接insert添加用户。如果还是要改,可以修改配置文件:

[root@localhost doubles]# vim /usr/local/mysql/my.cnf
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

定位到上面这一行,这一行指定了mysql为严格模式,为了安全,严格模式是禁止使用insert形式创建mysql用户的,如果坚持还是要用,把配置修改为:

sql_mode=NO_ENGINE_SUBSTITUTION

然后重启服务

[root@localhost doubles]# /etc/init.d/mysqld restart

再次插入成功。

mysql> insert into mysql.user (Host,User,Password) Values('%','test2',PASSWORD('123'));
Query OK, 1 row affected, 3 warnings (0.00 sec)

改完配置再次插入成功。

方式三:(grant命令创建用户)
mysql> grant select on *.* to 'test3'@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

这种方式连同授权一起了。

查看权限发现test3已经授权成功,只有select权限,如下图:

4.4、为新建用户授权

遵循权限最小化原则。

4.4.1、查看用户权限

方法一:

像上面一样,用select查询

mysql> select * from mysql.user where User='test3'\G;

方法二:

mysql> show grants for test3;

结果如下图:

因为test3用户时我们用grant命令创建的时候赋予了select权限,所以show grants for test3;时有select权限。

而test2与test1没有授权,现在查看到是USAGE权限。

USAGE介绍:

1、连接(登陆)权限,建立一个用户,就会自动授予其usage权限(默认授予)。

2、

mysql> grant usage on *.* to ‘p1′@’localhost’ identified by ‘123′;

3、该权限只能用于数据库登陆,不能执行任何操作;且usage权限不能被回收,也即REVOKE用户并不能删除用户。

4.4.2、授权

接下来为test2授权:

mysql> grant select,update on *.* to test2@'%';
Query OK, 0 rows affected (0.00 sec)

可以使用grant重复给用户添加权限,进行权限叠加。

授权之后,一定要记得flush,权限才会生效:

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

不需要的权限可以用revoke回收:

mysql> revoke select on *.* from test2@'%';
Query OK, 0 rows affected (0.00 sec)

拓展:

之前我们有为localhost的root用户授权,是这样子:

mysql> grant all privileges on *.* to root@localhost identified by 'password' with grant option;

all privileges:除了root,不建议赋予普通用户所有的权限。一般业务用户所需要的也只是增删改查,创建表等。根据需要赋予不同用户不同权限。(管理员一定要做好权限控制。)

on *.*:表示在所有的库和所有的表。这个一般是给管理员的。给业务用户一般是要指定库的,如:somedb.*。同样是all privileges,基于管理员(.) 的所有权限跟基于业务库(somedb.*) 上的所有权限也是不一样的。

with grant option:表示让用户具备grant(其他用户的)权限。(一般只给root)

4.5、MySQL权限列表

参考:https://www.cnblogs.com/tongxiaoda/p/7867796.html

Mysql支持的权限如下:

ALL或ALL PRIVILEGES  代表指定权限等级的所有权限。

ALTER   允许使用ALTER TABLE来改变表的结构,ALTER TABLE同时也需要CREATE和INSERT权限。重命名一个表需要对旧表具有ALTER和DROP权限,对新表具有CREATE和INSERT权限。

ALTER ROUTINE   允许改变和删除存储过程和函数

CREATE  允许创建新的数据库和表

CREATE ROUTINE  允许创建存储过程和包

CREATE TABLESPACE   允许创建、更改和删除表空间和日志文件组

CREATE TEMPORARY TABLES 允许创建临时表

CREATE USER 允许更改、创建、删除、重命名用户和收回所有权限

CREATE VIEW     允许创建视图

DELETE  允许从数据库的表中删除行

DROP    允许删除数据库、表和视图

EVENT   允许在事件调度里面创建、更改、删除和查看事件

EXECUETE    允许执行存储过程和包

FILE        允许在服务器的主机上通过LOAD DATA INFILE、SELECT ... INTO OUTFILE和LOAD_FILE()函数读写文件

GRANT OPTION    允许向其他用户授予或移除权限

INDEX   允许创建和删除索引

INSERT  允许向数据库的表中插入行

LOCK TABLE  允许执行LOCK TABLES语句来锁定表

PROCESS 允许显示在服务器上执行的线程信息,即被会话所执行的语句信息。这个权限允许你执行SHOW PROCESSLIST和mysqladmin processlist命令来查看线程,同时这个权限也允许你执行SHOW ENGINE命令

PROXY   允许用户冒充成为另外一个用户

REFERENCES  允许创建外键

RELOAD  允许使用FLUSH语句

REPLICATION CLIENT  允许执行SHOW MASTER STATUS,SHOW SLAVE STATUS和SHOW BINARY LOGS命令

REPLICATION SLAVE   允许SLAVE服务器连接到当前服务器来作为他们的主服务器

SELECT  允许从数据库中查询表

SHOW DATABASES  允许账户执行SHOW DATABASE语句来查看数据库。没有这个权限的账户只能看到他们具有权限的数据库。

SHOW VIEW   允许执行SHOW CREATE VIEW语句

SHUTDOWN    允许执行SHUTDOWN语句和mysqladmin shutdown已经mysql_shutdown() C API函数

SUPER   允许用户执行CHANGE MASTER TO,KILL或mysqladmin kill命令来杀掉其他用户的线程,允许执行PURGE BINARY LOGS命令,通过SET GLOBAL来设置系统参数,执行mysqladmin debug命令,开启和关闭日志,即使read_only参数开启也可以执行update语句,打开和关闭从服务器上面的复制,允许在连接数达到max_connections的情况下连接到服务器。

TRIGGER 允许操作触发器

UPDATE  允许更新数据库中的表

USAGE   代表没有任何权限,只能登陆

5、 连接数设置

使用mysql的时候,经常会遇到MySQL: ERROR 1040: Too many connections这样的问题,一种是访问量确实很高,MySQL服务器抗不住,这个时候就要考虑增加从服务器分散读压力,另外一种情况是MySQL配置文件中max_connections值过小,这时,我们就需要调整当前最大连接数。

5.1、查看当前连接数

查看系统最大连接数设置:

mysql> show variables like '%max_connections%';

查看当前连接数情况:

mysql> status;

或者:

mysql> show status like '%thread%';

详细查看当前连接数:

mysql> show full processlist;

5.2、修改最大连接数

5.2.1、命令行修改

mysql> set global max_connections=1000;

这种方式修改,只对当前环境有效,mysql重启连接数就失效了。要想永久生效需要修改配置文件my.cnf。

5.2.1、修改配置文件

[root@localhost ~]# vim /usr/local/mysql/my.cnf
[mysqld]
...
max_connections=1000

重启MySQL服务生效

[root@localhost ~]# /etc/init.d/mysql restart

修改连接数原则

使用show global status like 'Max_used_connections';查看当前MySQL响应的最大连接数,

mysql> show global status like 'Max_used_connections';

再用show variables like '%max_connections%';查看最大连接数。

对于mysql服务器最大连接数值的设置范围比较理想的是:服务器响应的最大连接数值占服务器上限连接数值的比例值在10%以上,如果在10%以下,说明mysql服务器最大连接上限值设置过高。

Max_used_connections / max_connections * 100% = 151/2000 * 100% ≈ 7.5%

这里连接数设置的还是偏高了。

6、 MySQL备份

待补充。。。

7、 研发数据库配置读取规范

A、所有开发人员都不能知道正式服数据库连接信息(包括数据库连接地址,用户名和密码)。

B、开发人员读取数据库连接信息的时候,只能从配置文件中读取。(测试环境一份,正式环境一份,代码部署上线时,将正式环境的覆盖测试环境的配置。)

C、配置文件可规定为某一种格式,如json格式。(可参考后端配置文件SrvNetIP.json)

{
"DebugLog":1,
"GmMode":1,
"AutoAccout":0,
"PlatformId":3,
"ServerId":19,
"GateSrv":
{
"Bind_Client_ipport" : "9000",
"Bind_Srv_ipport" : "tcp://127.0.0.1:8000"
},
"GameSrv":
{
"Bind_Srv_ipport" :"tcp://127.0.0.1:7000"
},
"WorldSrv":
{
"WorldSrvId":0,
"Bind_Srv_ipport" : "tcp://127.0.0.1:6000"
},
"DBCache":
{
"Bind_Srv_ipport" : "tcp://127.0.0.1:5000",
"DBLoginMySQL":
{
"MySQL_ip" : "127.0.0.1",
"MySQL_port" : 3369,
"User" : "doubles",
"PassWd" : "123",
"DBName" : "doublesDB"
}
}
}

MySQL安全优化的更多相关文章

  1. Mysql - 性能优化之子查询

    记得在做项目的时候, 听到过一句话, 尽量不要使用子查询, 那么这一篇就来看一下, 这句话是否是正确的. 那在这之前, 需要介绍一些概念性东西和mysql对语句的大致处理. 当Mysql Server ...

  2. Mysql性能优化三(分表、增量备份、还原)

    接上篇Mysql性能优化二 对表进行水平划分 如果一个表的记录数太多了,比如上千万条,而且需要经常检索,那么我们就有必要化整为零了.如果我拆成100个表,那么每个表只有10万条记录.当然这需要数据在逻 ...

  3. Mysql性能优化一

    下一篇:Mysql性能优化二 mysql的性能优化无法一蹴而就,必须一步一步慢慢来,从各个方面进行优化,最终性能就会有大的提升. Mysql数据库的优化技术 对mysql优化是一个综合性的技术,主要包 ...

  4. 关于MySQL数据库优化的部分整理

    在之前我写过一篇关于这个方面的文章 <[原创]为什么使用数据索引能提高效率?(本文针对mysql进行概述)(更新)> 这次,主要侧重点讲下两种常用存储引擎. 我们一般从两个方面进行MySQ ...

  5. [MySQL性能优化系列]提高缓存命中率

    1. 背景 通常情况下,能用一条sql语句完成的查询,我们尽量不用多次查询完成.因为,查询次数越多,通信开销越大.但是,分多次查询,有可能提高缓存命中率.到底使用一个复合查询还是多个独立查询,需要根据 ...

  6. [MySQL性能优化系列]巧用索引

    1. 普通青年的索引使用方式 假设我们有一个用户表 tb_user,内容如下: name age sex jack 22 男 rose 21 女 tom 20 男 ... ... ... 执行SQL语 ...

  7. 【MySQL】花10分钟阅读下MySQL数据库优化总结

    1.花10分钟阅读下MySQL数据库优化总结http://www.kuqin.com2.扩展阅读:数据库三范式http://www.cnblogs.com3.my.ini--->C:\Progr ...

  8. MySQL性能优化:索引

    MySQL性能优化:索引 索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序.数据库使用索引以找到特定值,然后顺指针找到包含该值的行.这样可以使对应于表的SQL语句执 ...

  9. 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  10. mysql 性能优化方向

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

随机推荐

  1. Android Notification通知

    /** * 在状态栏显示通知 */ private void showNotification(){ // 创建一个NotificationManager的引用 NotificationManager ...

  2. 如何使用google等一系列搜索引擎?

    对于我们经常使用的搜索引擎大家都都不陌生,但是,如何高效的利用呢?大家都知道空格是搜索多个关键词,那么有没有其他的快捷键呢?答案是肯定的,以下内容转自知乎 1.双引号 把搜索词放在双引号中,代表完全匹 ...

  3. ServerSocket的建立和使用

    -------------siwuxie095 工程名:TestMyServerSocket 包名:com.siwuxie095.socket 类名:MyServerSocket.java 工程结构目 ...

  4. php入门学习

    尤其不认可W3school之类的东西,不够深度,理解不深,比起这个更建议看官方文档,中文不清楚,看英文的. 入门视频:入门视频推荐:哈佛大学公开课:构建动态网站Beginner PHP and MyS ...

  5. 友善之臂smart210 3G网卡配置说明

    1.命令行输入 3g-ppp /etc/3g-modem/12d1.1446.12d1.1001 2.call-ppp wcdma 3.  你到etc目录里grep一下192.168.1.1 sant ...

  6. Windows Live Writer 使用指南

    一.简介 Windows Live Writer 是一个强大的离线博客编辑工具,通过它可以离线编辑内容丰富的博文,除了自身强大的编辑功能之外,还提供了接口,让其它开发人员通过插件提供工具自身没有提供的 ...

  7. 没事写写css

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  8. Pull项目失败

    1.网速原因 2.提示邮箱失效. 邮箱失效:解决方案 File->Setting: 然后,要记得重启,IDEA. 然后,在终端输入:git branch -l 查看项目分支 这样,设置好了用户名 ...

  9. java全栈day10--接口 多态

    接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义与 ...

  10. 校对双层PDF中的隐藏文本

    作者:马健邮箱:stronghorse_mj@hotmail.com发布:2012.06.11 目录一.背景二.能够校对的PDF需要满足的条件三.校对工具的选择四.校对过程五.延伸讨论 事先声明:本文 ...