06_ProxySQL配置之密码管理

备注:文章编写时间201904-201905期间,后续官方在github的更新没有被写入 ~ ~

一、ProxySQL中的MySQL密码[MySQL Passwords in ProxySQL]

ProxySQL是一种协议感知代理。 由于ProxySQL基于流量执行路由,因此当客户端连接时,它无法识别目标HostGroup,因此ProxySQL需要对客户端进行身份验证。 因此,它需要具有与用户密码相关的一些信息:一些足以允许身份验证的信息。

ProxySQL也需要这些信息与后端建立连接,或在已建立的连接中发出CHANGE_USER。

3层配置架构也适用于用户信息。 ProxySQL将用户信息存储在表mysql_users中: 1)对象MySQL_Authentication()负责在RUNTIME层存储这些信息; 2)main.mysql_users是MEMORY层的数据库; 3)disk.mysql_users是DISK层上的数据库。

二、密码格式[Password formats]

无论是内存还是磁盘上,密码都可以在mysql_users.password表中以2种格式存储: 1)纯文本(明文)[plain text] 2)哈希密码[hashed password]

纯文本中的密码很简单,非常容易阅读。即使数据库和配置文件保存在安全位置,则安全问题仍然存在。散列密码与MySQL服务器 存储在mysql.user.password列中的密码格式相同。

ProxySQL认为以*开头的密码具有散列密码。

三、散列密码和身份验证[Hashed passwords and authentication]

在MySQL和ProxySQL中,从明文到散列密码的转换为SHA1[SHA1('clear_password')];而从散列密码是无法导出纯文本密码的。当客户 端连接到ProxySQL时,可以使用散列密码对其进行身份验证。在第一次客户端身份验证期间,ProxySQL可以生成出部分哈希的密码 SHA1('clear_password'),在运行期间,该信息将在内部进行存储,并允许ProxySQL连接到后端。

四、如何输入新密码[How to input new passwords]

在ProxySQL的Admin interface界面是没有PASSWORD()类似的函数的,这意味着: 1)密码以插入的格式存储,可以是纯文本或散列; 2)在Admin interface界面输入密码时,无法从纯文本密码中获取散列密码(而在MySQL中运行SELECT PASSWORD('password')是可以的);

五、admin-hash_passwords参数[Variable admin-hash_passwords]

为了便于支持散列密码,ProxySQL v1.2.3引入了一个新的全局布尔参数admin-hash_passwords,默认情况下是启用的。 当admin-hash_passwords=true时,仅当执行LOAD MYSQL USERS TO RUNTIME时,密码才会在RUNTIME自动散列。mysql_users表中的密码 不会自动被散列。尽管如此,但对内存和磁盘上的mysql_users表中密码进行散列还是很容易的,只需要从RUNTIME层复制用户配置就足够 了: 例如,在LOAD MYSQL USERS TO RUNTIME之后再运行SAVE MYSQL USERS FROM RUNTIME,然后SAVE MYSQL USERS TO DISK ,这样就将哈希 后的密码信息保存到了内存和磁盘(推荐)。

示例:

Admin> SELECT username,password FROM mysql_users;
+----------+------------+
| username | password   |
+----------+------------+
| user01   | password01 |
| user02   | password02 |
+----------+------------+
2 rows in set (0.00 sec)

Admin> LOAD MYSQL USERS TO RUNTIME;
Query OK, 0 rows affected (0.00 sec)

Admin> SELECT username,password FROM mysql_users;
+----------+------------+
| username | password   |
+----------+------------+
| user01   | password01 |
| user02   | password02 |
+----------+------------+
2 rows in set (0.00 sec)

在此阶段,密码在RUNTIME层已经做了哈希处理,但mysql_users中的名为仍然没有进行哈希处理。 对MEMORY层mysql_users表上的密码进行散列:

Admin> SAVE MYSQL USERS FROM RUNTIME;
Query OK, 0 rows affected (0.00 sec)

Admin> SELECT username,password FROM mysql_users;
+----------+-------------------------------------------+
| username | password                                  |
+----------+-------------------------------------------+
| user01   | *F9A4855A538E726D743CAE9D5D28240B20CC69C1 |
| user02   | *8B4C9476A1542A79AA4AE86926B0344C4C4E2082 |
+----------+-------------------------------------------+
2 rows in set (0.00 sec)

此时,MEMORY层中的密码已经是哈希值了,现在可以通过运行 SAVE MYSQL USERS TO DISK 即可将散列密码保存到磁盘上。

Admin> SAVE MYSQL USERS TO DISK;
Query OK, 0 rows affected (0.01 sec)

注意:admin-hash_passwords是一个admin参数,而不是一个mysql参数。这是因为它会影响Admin的行为。

这个细节非常重要,因为为了应用对参数admin-hash_passwords的更改,需要运行LOAD ADMIN VARIABLES TO RUNTIME而不是LOAD MYSQL VARIABLES TO RUNTIME。

完毕!