本篇文章主要说一说MySQL中访问控制控制点的相关内容和理解。
a)应对登录的用户分配账户和权限; b)应重命名或删除默认账户,修改默认账户的默认口令; c)应及时删除或停用多余的、过期的账户,避免共享账户的存在; d)应授予管理用户所需的最小权限,实现管理用户的权限分离; e)应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则;f)访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级; g)应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问。
a)应对登录的用户分配账户和权限;
如果从字面意思来看,就是一个废话,用户都登录账户了,自然就存在着账户。
这里的意思是应该是你本来就存在“多个账户”,然后当用户使用时要适当的“分配账户”给用户,而账户再拥有不一样的权限,这样就实现了将权限通过账户分配给用户(自然人)。
所以,该测评项就需要MySQL中存在至少两个账户,且这两个账户的权限不一样。
在测评要求中测评实施如下:
在MySQL中,安装完成后默认存在的账户一般有3个,都是root:
先不管其中是否存在多余账户,这个账户如果使用的话一般当做超级管理员来用,默认状况下root账户也拥有着所有的全局权限,也不需要对root账户的权限做什么限制。
全局权限存储在user表中,里面有着权限列:
b)应重命名或删除默认账户,修改默认账户的默认口令;
默认账户root当然是可以修改用户名的,但是一般数据库和实际业务关联比较深,修改数据库用户的用户名肯定会影响到业务。
所以从实际角度来说,应该是建议修改root的用户名,但不强制要求。
如果没有修改用户名或者禁用账户的话,似乎MySQL安装好后root账户存在一个初始口令(随机生成的)。
无论存不存在初始口令,现在使用的口令应该是强口令,才符合测评要求。
c)应及时删除或停用多余的、过期的账户,避免共享账户的存在;
默认账户一般就是root账户,这里个人觉得是存在多余账户的:
在等保测评2.0:MySQL身份鉴别(上)中有说过:
对于MySQL来说,如上文所言,用户的身份标识为username + host,MySQL并没有禁止出现完全一样的username + host行,所以这里是可能出现身份标识不唯一的情况的。 这三个用户的User都是root,虽然Host看上去不一样,实际上也都是本机地址。 127.0.0.1就是本地的ip地址,localhost则是在hosts文件里(linux系统中)和ip地址进行了映射,其实映射的还是127.0.0.1地址,至于::1应该是ipv6格式的本机地址。 ::1这个我不知道要如何才能连上,当用户名为root的行只剩下host值为::1的行的时候,使用用户名root怎么连都不可能连上。 对于127.0.0.1和localhost,在windows系统上没啥区别,登录时其排序是不确定的(对于这种,应该是谁先创建谁在前)。 对于127.0.0.1和localhost,好像在linux上有一点区别:MySQL主机127.0.0.1与localhost区别总结 从正常的业务需求来说,明显这三个用户的身份标识是不唯一的,应该删掉::1和另外一个。 至于非默认账户,可以通过访谈或者权限查询来判断是否为多余账户。
d)应授予管理用户所需的最小权限,实现管理用户的权限分离;
MySQL的权限是有多个层级的,分别是,存储在各个表当中。
分别是:mysql.user表(全局权限)、mysql.db表(数据库权限)、mysql.tables_priv(表权限)、mysql.columns_priv(列权限)。
权限判断过程大概是这样的:
客户端操作核实阶段,当客户端的连接请求被MySQL服务器端通过其身份认证后。那么接下来就可以发送数据库的操作命令给服务器端处理,服务器检查用户要执行的操作,在确认权限时,MySQL首先检查user表,如果指定的权限没有在user表中被授权;MySQL将检查db表,db表时下一安全层级,其中的权限限定于数据库层级,在该层级的SELECT权限允许用户查看指定数据库的所有表中的数据;如果在该层级没有找到限定的权限,则MySQL继续检查tables_priv表以及columns_priv表,如果所有权限表都检查完毕,但还是没有找到允许的权限操作,MySQL将返回错误信息,用户请求的操作不能执行,操作失败。其过程大概如下图:
查询某用户的权限的话,可以去上述几个权限表中查看数据。
也可以使用show grants for ‘xx’@’xx’语句,这个语句应该会把某用户在这些表中的权限全部列出来:
+---------------------------------------------------------------------------------------------+| Grants for dba@localhost |
+---------------------------------------------------------------------------------------------+| GRANT RELOAD, SUPER, REPLICATION CLIENT ON *.* TO 'dba'@'localhost' |
| GRANT CREATE TEMPORARY TABLES ON `mysql`.* TO 'dba'@'localhost' |
| GRANT SELECT, INSERT, UPDATE, CREATE, DROP ON `mysql`.`backup_history` TO 'dba'@'localhost' |
| GRANT INSERT, UPDATE, CREATE, DROP ON `mysql`.`ibbackup_binlog_maker` TO 'dba'@'localhost' |
| GRANT INSERT, UPDATE, CREATE, DROP ON `mysql`.`backup_progress` TO 'dba'@'localhost' |
+---------------------------------------------------------------------------------------------+
其中第一行是全局权限,第二行是mysql数据库的权限,第三、四行则是表一级的权限。
两种查询方法如下图:
那么怎么才算是符合呢?应该要根据应用程序业务复杂程度来判断,应用程序业务越复杂或者越庞大,则数据库账户的权限就应该划分得越细致。
反正,一个root账户从头用到尾,那肯定是不符合的。
其余的内容,可以参考下初级教程:
e)应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则;
授权主体在数据库中也就是拥有设置用户权限的账户,也就是查看user表、db表中的grant_priv字段。
赋予用户权限的时候,加上With Grant Option,即该用户则拥有了将获得的权限再赋予其它人的权限(其实就是同时修改了grant_priv字段):
比如
mysql>grant all on *.* to test@’192.168.1.20’ identified by ‘123456’ WITH GRANT OPTION
mysql>flush privileges;
结果显示:Grant_priv为"Y"
对于测评项而言,也就看数据库内是否设置了此类账户,由此类账户(安全管理员)来制定访问控制策略。
f)访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级;
就是看权限控制粒度,对于客体,要看是否达到了数据库表的级别,也即单独对数据库表设置权限(视图、存储过程也可以)。如果仅达到了数据库级别或者服务器级别的权限,那肯定是不符合要求的。
至于主体就不说了,MySQL中也没存在用户组。
g)应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问。
MySQL自身应该不具备这个功能,可能要依靠操作系统或者第三方的什么软件来实现了。
关于安全标记,可以看看等保测评2.0:Windows访问控制中测评项g中的内容。
实际测评中,基本上就没有能实现的,不过也不用太在意,因为这一个测评项不属于高风险项。
*本文原创作者:起于凡而非于凡,本文属于FreeBuf原创奖励计划,未经许可禁止转载