一直以为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.