这是学习笔记的第 1873篇文章
MySQL里面的权限本身是没有硬性的限制的。整个权限体系总体是比较清晰的。
目前使用比较广泛的有几类玩法,一种是根据主机名的方式来进行管理,需要在/etc/hosts里面进行配置。
比如有3台服务器,分别对应3个业务,那么我们可以指定主机名为app1,app2,app3类似这种。
如果有3个IP,则对应C类地址,比如192.168.2.10,192.168.2.12,192.168.18.20则对应192.168.2.%和192.168.18.%两个网段。
至于使用哪一种,也是各有千秋,总体来说,使用网段的方式比较好管理一些,因为用户和业务是相对单一的,如果有几个用户不成问题,一旦用户规模和环境多了起来,就需要做到统筹管理。
对于权限管理有两种特殊的情况,总体的目标从安全的角度来说,是希望系统和应用之间是隔离的。即DBA不用刻意关心密码的意义和规则,业务无需关心密码的明文,如果两者能够基本隔离开来,其实也是各司其职,互相补充,避免一个单一的流程造成的全链路影响。归根节点,使用密码只是一种访问方式,在使用方式上也需要做到平衡。
在实际的工作中,经常会收到业务要增加权限的需求,其实有时候业务同学也不知道自己是否开通了权限,所以他们就会一股脑儿的把IP地址都写完整,如果你一台一台的去开通权限,显然是很冗余的管理方式,如果把信息都集成起来,对于后期的权限周期管理是很难以落地管理的。
目前主要有两类权限需求,一类是权限变更,即原来开通了10个客户端,现在增加2个,可能1分钟就能搞定,也可能得花个10多分钟才能梳理清楚。
怎么能够平滑的实现这个需求呢,我们把它暂且叫做权限克隆。比如用户test_db@192.168.12.%'已经开通了使用权限,现在需要新增一个客户端IP为192.168.11.12,则从MySQL的配置管理上来说,是需要新增一个数据库用户的。它的密码和权限怎么办,其实这里我们需要的就是通过权限克隆来平滑的实现权限变更。同时,通过权限克隆功能可以实现平滑的用户权限稽核和授权语句生成,对于管理和业务用来说也更加透明。
整个权限克隆的逻辑如下:
1.根据输入的IP,端口,得到数据库实例响应的用户列表
a) 用户信息包括用户名和主机
b) 其中主机按照C类网段来模糊匹配
2.如果输入的用户名在已有的用户列表中,并且所在网段也匹配,则提示用户权限已存在,无须重复申请,不会生成新的密码
3.如果输入的用户名在已有的用户列表中,但是网段不匹配,则需要使用克隆功能,密码克隆部分的逻辑如下:
a) 根据用户名得到匹配的用户列表
b) 通过循环得到用户名对应的密码信息,是否匹配
i. 如果不匹配则提示问题,需要进一步确认,原则上应该需要保持一致
ii. 如果匹配,则取出加密后的密码信息
c) 根据用户名和网段信息,加密密码,生成相应的创建用户语句,密码为加密方式,无须重复生成密码记录
以上是一些较粗的设计方向,如果要敲代码从头实现,其实这个梳理和需求分解的过程是很重要的,我们关注了设计,也需要关注实现,通过这样的一个梳理会发现原来比较纠结的问题也清晰起来。
详细设计的相关SQL和伪代码如下:
1.根据输入的IP,端口,得到数据库实例响应的用户列表
a) 用户信息包括用户名和主机
Select user,host,authentication_string from mysql.user;
生成一个列表 user_list
b) 其中主机按照C类网段来模糊匹配
Python根据小数点来做分隔
2.如果输入的用户名在已有的用户列表中,并且所在网段也匹配,则提示用户权限已存在,无须重复申请,不会生成新的密码
循环匹配user_list
3.如果输入的用户名在已有的用户列表中,但是网段不匹配,则需要使用克隆功能,密码克隆部分的逻辑如下:
a) 根据用户名得到匹配的用户列表
User_list[“username”]
b) 通过循环得到用户名对应的密码信息,是否匹配
根据user_list的信息来对比加密密码是否匹配
i. 如果不匹配则提示问题,需要进一步确认,原则上应该需要保持一致
ii. 如果匹配,则取出加密后的密码信息
c) 根据用户名和网段信息,加密密码,生成相应的创建用户语句,密码为加密方式,无须重复生成密码记录