一直以为MySQL的访问控制规则是先匹配username再去匹配host,没想到不是这样的。如果MySQL用户管理不当,可能出现实际登陆的用户与期望连接的用户不一致的情况。
在创建用户的时候,user和host都可以为空值。当host为空值时,等同于%,代表any hosts。当user为空值时,也会匹配any user,但匹配上的用户会被当成no name的匿名用户。
由于通配符的存在,当一个用户登陆的时候,username@host形式的认证信息是可能在mysql.user表中匹配到多行的,当这种情况发生时,MySQL 就必须判断该匹配哪一行。它是这样做的:
1. 只要 MySQL 将`mysql.user`表读入内存,就对它排序;
2. 当有链接尝试连入的时候,MySQL 就按顺序从内存读取`user`表的行;
3. MySQL 使用匹配 username@host 的第一行。
mysql.user表排序的规则是most-specific Host values first,即最具体的 host 值优先。字符的host和ip是most specific的,其中 ip 的具体度不受它是否携带子网掩码影响,像198.51.100.13 and 198.51.100.0/255.255.255.0就可以看成是同样specific的。通配符%是least specific的,blank值同样代表any host,但排序在%后面。
相同host的按most-specific User values first规则排序,如果是blank值则是least specific的。
相同具体读的host和user行排序是不确定的。
某个库的user表如下:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
排序后就是这样
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
如果正在尝试连接的是jeffrey@localhost,那么在user表中会有两行匹配:’’@localhost和Jeffrey@%。按照顺序 MySQL 选择的应该是’’@localhost,因此这个链接会以一个匿名用户的身份登录而不是Jeffrey。这往往很容易造成误解。
MySQL :: MySQL 5.6 Reference Manual :: 6.2.4 Access Control, Stage 1: Connection Verification
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.