mysql空用户(user列为空)带来的影响

长平狐 发布于 2012/11/01 11:57
阅读 1K+
收藏 2
今天搭建一个测试环境时,遇到了一个很隐蔽的问题。有必要分享一下

| user | password                                  | host               |
+------+-------------------------------------------+--------------------+
| root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | localhost          |1
| root |                                           | db-2.photo.xxx.org |2
| root |                                           | 127.0.0.1          |3
| root |                                           | ::1                |4
|      |                                           | localhost          |5
|      |                                           | db-2.photo.xxx.org |6
| sys  | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    | db-2.photo.xxx.org |7
...
...
如上图所示,这个里面存在着两个用户名为空的情况。然后问题就是由此而起。


在本机(服务器,db-2.photo.xxx.org) mysql -usys -ppass -h`hostname` 或者 mysql -usys -ppass -h`hostname -i` 都提示无法连接。此时配置文件里面没有 --skip-name-resolve这个参数(DNS解析用的)而用户表里面明明有这个sys@db-2.photo.xxx.org 而且密码也对了啊?起初没有注意到这个空用户,没想到它的陷阱,搞了很久也没连上,后来只好请老大了,老大过来一看,直接drop user ''@db-2.photo.xxx.org(删掉这个空用户,老大V5),然后再连,OK 搞定。


这是什么原因呢?
因为mysql在验证权限的时候,首先是验证host列,如果host列在验证user列,再password列,而现在按照我之前的连接语句:按照host列首先找到第6行,然后发现这行的user列为空(空匹配所有用户名),所以匹配到了这条记录,然后发现这条记录的密码为空,而我的连接语句里面有密码,那么就会报错。


好了,你可能会说要是我在连接的时候 -h指定的是ip地址,而不是域名(db-2.photo.xxx.org)那么不就不会匹配到了这条记录么?但是我在前面说了--skip-name-resolve这个参数我没有指定,那么就会DNS解析,将域名解析成IP地址。所以还是会被匹配到的。于是我的连接语句改为 mysql -usys  -h`hostname -i` 或者  mysql -usys  -h`hostname` 此时就可以连接成功,但是请注意,虽然可以连接成功,但是实际上这个连上去的用户多大权限,也就是空用户所具有的权限。 而且,我后来模拟的时候,将第6行的存放顺序(物理磁盘上)和第7行反过来(这个可以通过optimize 一下table,然后顺序插入两条用户记录解决,虽然不能说绝对的成功,因为插在磁盘上的哪个位置不是我们能控制的,但是除非你RP败坏,可能会出现后插入的记录在物理磁盘上反而在前面) (在转移博客时发现之前的理解有误,实际上与数据在物理磁盘上的顺序无关,因为将数据读到内存时会按照<hostname,username>进行排序)然后再进行前面的连接测试  mysql -usys -ppass  -h`hostname -i` 或者  mysql -usys  -ppass -h`hostname`, ok没问题了。同时如果将上面的连接语句去掉 -p选项,那么就是密码错误,也不会再去判断第7行了(已经调换顺序的第7行)


所以解决办法就是:
1.刚装好mysql后就直接删除那个空用户
2.连接的时候,-h+ip连接,且在配置文件里面指定 --skip-name-resolve,这样同时还能消除DNS解析带来的性能影响
另外,如果直接指定了socket的话,也不会存在这个问题,此时连接就是通过socket,而不是tcp/ip。 同时,如果你在别的机器上连接肯定也没问题,因为空用户默认的host就是主机地址。
不明白mysql5.5为什么这样设计,在mysql5.1里面就没有这个空用户。(在这次转移博客的时候发现了mysql 5.5在bin目录下提供了一个mysql_secure_installation的脚本,里面就可以删除空用户等等,看来mysql还是知道这个安全问题是存在的)


原文链接:http://blog.csdn.net/zbszhangbosen/article/details/7434154
加载中
返回顶部
顶部