正文
这是数据库基础的安全设置脚本:
-
设置root密码
-
移除匿名用户
-
禁止远程root登录
-
移除test数据库
以上是5.6版本,5.7有所加强但也仅此而已,看看你的环境是否存在上述问题,这个算是最基本的安全吧。
2、连接访问安全
常见创建用户时你需要指定你的IP访问地址范围或者固定IP,一般而言,只有特定唯一的几个IP才会访问,或者说你可以采用代理访问的方式,减少应用直接访问你的数据库,而且现在很多中间件也都有白名单机制,原则上是把非法请求防止在数据库以外的地方。
规范数据库管理软件,实现管理软件的标准、统一化,还有严禁杜绝开启外网访问,如果客户端在远程,就根本不应该直接访问数据库,而应该使用中间件堡垒机或其它替代方案。
为了防止连入数据库的应用程序存在后门,造成数据库安全隐患,检查所有连接数据库程序的安全性。通过使用堡垒机或者其它监控登录数据库,禁止对数据库的直接操作。
对已经连接的IP网段进行规范化、统一化的管理,定期进行权限复核操作,对系统所属IP、用户进行权限梳理工作。
对员工进行安全培训,增强员工的系统安全观念,做到细心操作,安全操作。确保访问数据库的主机为已知用户或者主机,使用专门主机与数据库进行连接。
对重要业务表的所有行为全部审计,审计同时所有包括即使是DBA的DDL操作行为。
最后是报表系统,利用审计的相关日志,出具系统化的审计报告。
3、权限安全
权限这块无可厚非,在建立之初遵循最小权限原则,坚持最小权限原则,是数据库安全的重要步骤。
以上说的是白话,下面说说正题。
很多时候我们不知道具体的最小权限是什么,你说一个账号到底需要什么样权限才合适,才不会影响业务?这个不是很好界定。我们需要知道在设置权限时的信息,要授予的权限级别、库级别、表级别、列级别,或者其它超级权限、要授予的权限类型,增删改查等。
从mysql.user表来看
用户名、IP地址,是否需要连接数控制、SSL、过期时间等,不要怕麻烦,可能前期设置的时候比较繁琐,但是一个好的基础设置,才是安全地保障,做到需要什么给什么。
4、账户安全
用户账户划分原则:
-
超级管理员账号
-
系统应用账号(比如备份,监控,审计等)
-
应用业务账号
-
业务人员账号
-
开发人员账号
-
测试人员账号
-
其它专用账号
主要是防止泄漏,非必要人员不需要知道账号的名称,同时需要制定相应的命名规则,还有就是合理使用自己的账号密码,保护好你的账号密码,对于绝无必要的用户,先禁用,后期删除,要做到无匿名账户和无废弃账户。
5、目录文件安全
提高本地安全性,主要是防止MySQL对本地文件的存取,会对系统构成威胁,还有Load DATA LOCAL INFILE,禁用该功能。
这个主要是防止误删除,非权限用户禁止访问目录,还有就是数据文件禁止访问,或者采用更改常用的目录路径,或者通过chroot,要保证该目录不能让未经授权的用户访问后把数据库打包拷贝走了,所以要限制对该目录的访问。
6、密码安全
尽量并且不要使用固定密码,实行每个用户单独密码,长度在16位以上 0-9a-zA-Z~!@#$%^&*()-+ 随机组合。
根据公司的情况设定密码过期时间,定期更改,同时不可使用重复密码。
为了方便管理,可能会采用一个密码表,要加强对于密码表的维护更新,最重要的是保证不泄漏。
7、漏洞安全
常规的方式是安装补丁,不过这个往往比较麻烦,主要是版本升级,还有就是防护策略。
8、被忽视的SSL
由于性能或者其它方面原因,很多生产环境并没有使用,不过从5.7+开始,已经好很多了,有需要的加强安全防范其实可以尝试下了。
https://dev.mysql.com/doc/refman/5.7/en/mysql-ssl-rsa-setup.html
9、防火墙安全
一般化数据库前面都会有主备的墙,不过从成本上考虑,很多企业都是单个或者裸奔的,有自己的硬件防火墙最好,没有的话也可以使用系统自带的防火墙,然后在加上其它白名单和中间件白名单过滤辅助措施,也能防止一部分问题。
10、端口安全
默认端口是3306,这个最好修改下,为了方便记忆,你可以根据的IP地址来加密动态调整,不过如果生产网络允许,也可以定期修改,最好不要影响研发进度。
11、记录安全
删除操作系统记录的敏感数据,比如.mysql_history、.bash_history 等,及时清理,移除和禁用.mysql_history文件。
人是安全的主导,管理的对象要从两个角度来看,从信息角度来说就是MySQL本身的安全,要防止数据的丢失和免遭破坏;从技术角度来说就是整个系统的安全,要防止系统的瘫痪和免遭破坏。
最后说句题外话,监控和审计,安全主要是防患于未然,没有谁希望一天到晚接到各种警报,最好根据公司的实际情况订个详细的规章制度,不要觉得这个麻烦,有些你可能并不觉得有用,但是呢?我希望是没有但是。
不以规矩,不成方圆。
无可否认,很多时候由于项目的开发迭代过于频繁,实时的需求反馈,可以及时调整产品的方向,不过由于各种大大小小的功能的耦合交错,还有研发人员对数据库的了解参差不齐,他们可能更加关注的是功能的实现,其次可能才是响应速度,这就导致了由于数据量小时看不出问题的SQL,一旦遇到大数据量,查询性能或者说系统的响应速度会变慢,这是个值得关注的地方,为了防止出现这种情况,你需要做点什么。
1、使用什么
-
使用 InnoDB 存储引擎,默认使用utf8mb4 字符集
-
使用自增主键,尽量每个表都有而且是非业务键值
-
使用合适的字段类型,比如 VARCHAR 代替 CHAR 等,最好确定好长度
-
使用尽可能小的 VARCHAR 字段
-
使用合适的 INTEGER、INT、SMALLINT、TINYINT、MEDIUMINT、 BIGINT 数据类型。
https://dev.mysql.com/doc/refman/5.7/en/integer-types.html
-
使用 UNSIGNED 存储非负数值,比如自增等
-
使用 INT UNSIGNED 存储 IPV4 INET_ATON、INET_NTOA。
更多 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html
-
必须使用 DECIMAL 代替 FLOAT 和 DOUBLE 存储精确浮点数,比如与货币、金融相关的数据,防止运算丢失精度问题
-
使用注释,所有表都需要添加注释;除自增主键外的其他字段都需要增加注释
-
使用默认值,所有字段都必须拥有默认值,不在表中存储 NULL
-
使用 PREPARED STATEMENT,防止SQL注入
-
使用合理的 LIMIT 分页方式以提高分页效率
-
使用 EXISTS 适用于子查询不返回实际数据,而表较大的情况,如果子查询表较少可以考虑用in
-
使用 IN 代替 OR,同时 SQL 语句中IN包含的值不应过多,应少于1000个,否则使用转为字符串LIKE
-
使用 UNION ALL代替 UNION,减少不必要的去重消耗
-
使用 COUNT(1) 统计行数,如果使用字段的话可能存在空值或NULL不准的情况
-
使用 INDEX,所有 WHERE 条件必须有索引,特别是 DELETE / UPDATE
-
使用 EXPLAIN EXTENDED 判断SQL语句是否合理使用索引
-
使用 SHOW PROFILES 跟踪资源使用
-
使用事务,增删改必须有,程序应有捕获SQL异常的处理机制
-
使用从库,不是必要的查询一律使用从库查询,减轻主库压力
2、减少什么
3、避免什么
-
避免使用TEXT、BLOB类型等
-
避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理
-
避免使用子查询 IN ,必要时使用JOIN。
-
避免出现NOW()、RAND()、SYSDATE()、CURRENT_USER()等不确定结果的函数
-
避免在索引列上使用IS NULL和IS NOT NULL
-
避免同一个表上索引过多,重复索引,太多的索引可能提高了查询效率,但是也增加了增删改的开销
4、禁止什么
-
禁止在数据库中存储图片、文件等大数据
-
禁止使用order by rand(),类似的有很多替代方案
-
禁止使用SELECT *,根据需要获取相对应需要的字段
-
禁止使用预留字段,无论从流程和规范上都说不过去
-
禁止在MySQL中进行数学运算和函数运算
-
禁止隐式转换,数值类型禁止加引号,字符串类型必须加引号
-
禁止使用 INSERT INTO TABLE(),需要指定相应的字段,最好是顺序的
-
禁止使用前置百分号,例如:WHERE A LIKE ‘%B’