MySQL_帐号密码匹配规则与命名规范
Posted 铁锚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL_帐号密码匹配规则与命名规范相关的知识,希望对你有一定的参考价值。
mysql帐号命名规范
中英双语对照版请查看: GitHub中英对照版: MySQL帐号命名规范
MySQL用户的帐号名称(Account Name)由两部分组成:
- 1、用户名(user name)
- 2、主机名(host name)
所以即使用户名部分相同, 只要登录的客户端IP不同, MySQL服务器可能就会匹配到不同的帐号。
本文简要介绍帐号的命名规则, 以及特殊值(special value)处理规则和通配符规则(wildcard rule)。
MySQL角色的命名规则与帐号命名类似, 细微差别请参考: Section 6.2.5, “Specifying Role Names”。
在 CREATE USER
, GRANT
, 以及 SET PASSWORD
等SQL语句中, 帐号命名遵循以下规则:
- 1、帐号名称的格式为:
'user_name'@'host_name'
; - 2、如果只指定了 user_name, 则等价于
'user_name'@'%'
; 例如,'me'
等价于'me'@'%'
。 - 3、如果用户名和主机名是合法的标识符, 则可以省略引号。 否则必须用引号引起来, 包括以下情形:
- 用户名中包含特殊字符(例如空格或者横线
-
); - 主机名部分包含特殊字符或通配符(例如
.
或者%
)。 - 示例: 如果帐号名是
'test-user'@'%.com'
, 那么用户名部分和主机名部分都必须用引号引起来。
- 用户名中包含特殊字符(例如空格或者横线
- 4、可以使用反引号(`, backticks, 点顿号)、单引号(
'
, single quotation marks) 或者双引号("
, double quotation marks)将用户名和主机名当做标识符/字符串引起来。 关于字符串引用和标识符引用的具体规则, 请参考: Section 9.1.1, “String Literals” 和 Section 9.2, “Schema Object Names”。 - 5、用户名和主机名是两个部分, 要分别加引号。
- 正确示例:
'me'@'localhost'
; - 错误示例:
'me@localhost'
; 因为这样写就等价于'me@localhost'@'%'
。
- 正确示例:
- 6、对
CURRENT_USER
关键字和CURRENT_USER()
函数的引用, 会被MySQL服务器解析为当前客户端的用户名和主机名所组成的字符串。
帐号信息存储在内置的系统数据库 mysql
中, 使用多个授权信息表, 通过不同的列来存储 用户名 和 主机名:
user
表中的每一行表示一个帐号。User
和Host
列是对应的用户名和主机名。 该表还保存有每个帐号的全局权限。- 其他授权表, 指定了每个帐号具有哪些数据库级和对象级权限。 这些表也使用
User
和Host
列来保存帐号名称。 每一行都与user
表中具有相同User
和Host
值的帐号进行关联。 - 在执行权限校验时,
User
部分是大小写敏感的。 而Host
部分则不区分大小写。
授权信息表中用户名和主机名对应的列还有一些其他属性(例如最大长度), 可以参考 Grant Table Scope Column Properties。
用户名和主机名支持通配符以及一些特殊值, 如下所述。
用户名部分可以是:
- 如果用户名是非空白值(nonblank value), 客户端连接时使用的用户名必须在字符上与这个值完全一致,
- 如果用户名是一个空白值(空字符串), 则可以和任意用户名匹配。 帐号中用户名为空, 也就是匿名用户。 要在SQL中指定匿名用户, 请使用引号把空串作为用户名引起来, 例如
''@'localhost'
。
主机名可以支持多种格式, 还可以使用通配符:
-
主机名, 可以是域名(host name) 或者是 IP地址(支持IPv4/IPv6)。
'localhost'
表示本机。'127.0.0.1'
表示本机的IPv4回环地址。'::1'
则表示本机的IPv6回环地址。 -
%
和_
通配符可以模糊匹配主机名和IP地址。 匹配规则和SQL标准中的LIKE
语句一致。 例如, 百分号'%'
与所有主机名匹配, 而'%.mysql.com'
则与mysql.com
域中的所有主机匹配。 而'198.51.100.%'
则与 198.51.100 网段下的所有C类地址匹配。
特殊情况: 由于主机名可以使用IP地址通配符, 那么就会存在一个逻辑上的安全漏洞。 例如
'198.51.100.%'
本来是想要匹配子网网段的, 但如果有黑客通过映射域名198.51.100.somedomain.com
来攻击这个漏洞怎么办呢? 为了杜绝这种风险, MySQL服务器不会对以【数字加上英文点号(.
)】开头的域名执行模糊匹配。 例如, 如果客户端的主机名是1.2.example.com
, 则永远不会与任何帐号的主机部分进行模糊匹配。 IP通配符只会匹配IP地址, 不会匹配域名。
- 如果主机名指定为IPv4地址, 则可以同时指定子网掩码, 以标识出有多少bit用于子网编号。 子网掩码这种形式不支持IPv6地址。
- 具体的语法格式为
host_ip/netmask
。 - 示例:
- 具体的语法格式为
CREATE USER 'cncounter'@'198.51.100.0/255.255.255.0';
这个帐号允许 cncounter
用户从IP地址满足以下条件的所有客户端进行登录:
client_ip & netmask = host_ip
对于上面通过 CREATE USER
创建的用户 cncounter
来说:
# 按位与运算
client_ip & 255.255.255.0 = 198.51.100.0
满足此条件的IP地址的范围是 198.51.100.0
到 198.51.100.255
。
子网掩码通常以二进制位等于 1
的bit开始, 后面跟着bit是0的位, 示例:
198.0.0.0/255.0.0.0
: 以 198 打头的 A 类地址198.51.100.0/255.255.0.0
: 以 198.51 打头的 B 类地址198.51.100.0/255.255.255.0
: 以 198.51.100 打头的 C 类地址198.51.100.1
: 只匹配具有特定IP地址的主机
MySQL服务器对帐号中的host值进行匹配时, 可以使用客户端的IP地址, 也可以使用系统DNS解析返回的客户端主机名。
除了子网掩码格式的主机值, 服务器会对其他格式的主机值以字符串形式进行匹配, 即使是将帐号的主机值指定为IP地址也是如此。 也就是说, 我们应该以DNS返回的格式为准, 来指定帐号的host部分。
下面是需要注意的问题:
- 假设本地局域网中有一台主机的完全限定名称为
host1.example.com
。 如果DNS系统返回的值为host1.example.com
, 则帐号中的主机值部分就需要使用这个名称。 如果DNS系统返回的是host1
, 则应该使用host1
。 - 如果DNS为某个客户端返回了IP地址格式的主机名
198.51.100.2
, 则它将与帐号中的主机值198.51.100.2
相匹配, 但不会与多了个0的198.051.100.2
匹配。 同样, 这个IP可以匹配host模式为198.51.100.%
的帐号, 但不会匹配198.051.100.%
.
为了避免此类问题, 请确认DNS返回的主机名和地址格式。 在MySQL帐号的主机名称中也使用相同格式的值。
参考链接
以上是关于MySQL_帐号密码匹配规则与命名规范的主要内容,如果未能解决你的问题,请参考以下文章