之所以想写这篇文章,是因为在工作中,经常被MySQL的用户授权问题折腾一下.日积月累....忍不住吐槽一下.
MySQL的安全包括很多方面,主要分为内部安全,外部安全及数据传输安全.
   内部安全指MySQL的启动和安装目录权限,避免其他用户进入目录,随意访问数据.
   外部安全指网络访问,其中用户授权是重点,也是接下来我要吐槽的.
   加密传输,这个不多说,大部分数据库处于内网,很少有人使用.
mysql库的user表,是最常用来查看权限的,例如用下面的SQL查看当前实例有多少个授权用户和某一个用户的权限

  1. SELECTuser,host,passwordFROM mysql.user;

  2. SHOW GRANTS FOR 'username'@'hostname';

在MySQL中没有用户组的概念,它认为即使相同的用户名而从不同的主机连过来,也是不同的授权.比如我创建一个用户u01,分别授权从192.168.0.1和192.168.0.2连接,那么MySQL认为是两个不同的用户.说到这里,也许有人就能想到,为了安全,不能让其他人随意连接数据,每个授权最好精确到IP地址,而不用范围(%)匹配.这样固然于安全有好处,但是也有如下维护的"困难":
   1.权限表条目增多.如果有20台主机需要连数据库,那么需要根据20台主机分别授权.
   2.
权限混乱,很难保证相同的用户名具有相同的权限.
3.
追加授权操作成本太高.经常遇到这样的情况1,开发人员提交权限申请,密码处注明,"与原来一样".dba去MySQL查密码,结果同样的用户名,从不同IP连过来的密码不一致,分别查出权限后,再与开发确认后,进行授权.情况2,应用添加新机器,已经发布上线,突然发现没有权限,急忙催促dba添加.
4.
"脏授权"无法清理,很多因服务器更换,导致的旧IP授权留在数据库中,没人去清理.
因此,建议在内网的数据库,并且做了合理的网段隔离,应该把数据库授权的工作尽量简化,对网段授权.这虽然增加的连接MySQL的范围.但是如果有人要窃取数据的话,仍然要满足下面的条件:
   1.登录到内网并有权限登录到任意一台服务器
   2.
知道MySQL的连接地址和帐号/密码


与精确到IP地址唯一不同的地方,便是"登录到任意一台,还是指定一台",这其中的安全与效率问题,需要大家根据自己的环境,折中考虑授权策略.


自动化脚本MySQL权限管理-安全与效率的折中 _IP地址grant.py.txt
1.    脚本运行在python2.7环境中.
2.    如果grant.ini配置文件不存在,则会自动生成.
配置文件说明如下:

  1. [proposer]

  2. #申请人邮件地址

  3. to_email =

  4. # 抄送地址

  5. cc_email =


  6. [server]

  7. # 登录目标数据库主机的用户名

  8. srv_user =

  9. # 数据库主机名

  10. srv_host = db1

  11. # 服务器的密码(禁止填写)

  12. #srv_pwd =


  13. [db]

  14. # 登录数据库的用户名

  15. db_user = xxxx

  16. # 通过IP和端口连接

  17. db_host = 127.0.0.1

  18. db_port = 3306

  19. # 对程序提供的ip(vip)地址

  20. db_ip_writer = 192.168.250.1

  21. #db_ip_reader =

  22. # 登录数据库的密码(禁止填写)

  23. #db_pwd = xxx


  24. [grants]

  25. # 添加的权限

  26. permission = UPDATE,DELETE,INSERT,SELECT

  27. # 库范围

  28. database = *

  29. # 表范围

  30. table = *

  31. # 添加的用户名

  32. user = test1

  33. # 允许连接的主机

  34. host = 127.0.0.1,192.168.250.1,192.168.250.2

  35. # 连接的密码(不需要填写,脚本会自动生成16位的密码,由Aa-Zz,0-9组成),追加用户授权时,可修改为加密的密文.

  36. #password =

  37. # 其他

  38. #others =


脚本逻辑:
1.读取配置文件
2.拼接sql
3.显示/确认
4.确认后,写入用户目录的tempfile.sql文件中
5.将tempfile.sql文件传到目标服务器
6.在目标服务执行mysql ... -e 'source tempfile.sql'
7.删除本地和目标服务器的tempfile.sql文件
8.发送邮件通知申请人