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 表中的每一行表示一个帐号。UserHost 列是对应的用户名和主机名。 该表还保存有每个帐号的全局权限。
  • 其他授权表, 指定了每个帐号具有哪些数据库级和对象级权限。 这些表也使用 UserHost 列来保存帐号名称。 每一行都与 user 表中具有相同 UserHost 值的帐号进行关联。
  • 在执行权限校验时, 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.0198.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_帐号密码匹配规则与命名规范的主要内容,如果未能解决你的问题,请参考以下文章

MySQL_帐号密码匹配规则与命名规范

MySQL_帐号密码匹配规则与命名规范

MySQL帐号命名规范

正则表达式学习和常用正则验证规则(包括用户名,密码,手机号,网址等)

C语言怎样设置特定的密码帐号登录系统?

请教一个简单的C与C++的命名规则问题