Password management

MySQL Passwords in ProxySQL

ProxySQL是一个感知协议代理 

ProxySQL是根据流量负载来路由连接的,所以连接到ProxySQL的客户端是不能通过目的主机组的认证的,因此ProxySQL需要对客户端进行验证

所以,ProxySQL需要和用户密码相关的信息:足够通过认证的信息

ProxySQL还需要与后端建立连接的信息,来对当前的连接做change_user

三层机构的配置体系同样适用于用户信息的配置.

ProxySQL存储用户信息到mysql_users表:

  • MySQL_Authentication()是负责存储用户runtime状态信息的对象
  • main.mysql_users缓存内存配置
  • disk.mysql_users持久化用户配置

不管是在内存还是磁盘,mysql_users都将认真信息存储在username和password列中。

Password formats

mysql_users.password中的密码用两种存储形式,不管在内存还是磁盘都是一样的:

  • 明文文本
  • hash加密

明文密码简单易读,如果数据库和配置文件都保存在访问受限的目录,还是可以的。hash加密的密码和MySQL server存储在mysql.user.password的密码有相同的格式。

ProxySQL会把以*开头的密码当作经过hash加密的密码。

Hashed passwords and authentication

在MySQL和ProxySQL中,密码是这样被hash的:SHA1(SHA1('clear_password'))

把一个hash密码转换为明文是根本不可能的

当客户端连接到ProxySQL时,是能通过hash密码进行认证的。

在这第一次客户端认证的过程中,ProxySQL能够获取经过一层加密的密码:SHA1('clear_password')。这个密码是被存储在runtime的,通过它ProxySQL就能够连接后端的mysql server。

How to input new passwords

ProxySQL admin接口没有PASSWORD()函数,也就是说:

  • 密码就是以他们插入的形式存储,明文或者是被hash过的
  • 当从admin输入密码的时候,他获取到的不可能是一个从明文经过加密的hash密码(但是你能在MySQL server上执行select password('password')并复制粘贴这个结果)

Variable admin-hash_passwords

为了支持hash密码加密,从ProxySQL v1.2.3开始引入了一个全局的布尔变量admin-hash_passwords,这个变量默认是启用的

当admin-hash_passwords=true时,只有在LOAD MYSQL USERS TO RUNTIME时密码会被自动加密。mysql_users表中的密码是不会被自动hash的。

但是,在mysql_users表中,密码是很容易被hash的,不管是缓存在内存中,还是持久化到磁盘。其实,从runtime状态复制就好了,比如执行LOAD MYSQL USERS TO RUNTIME后在SAVE MYSQL USERS FROM RUNTIME,然后在SAVE MYSQL USERS TO DISK

如下:

 1 Admin> SELECT * FROM mysql_users;
 2 Empty set (0.00 sec)
 3 
 4 Admin> INSERT INTO mysql_users(username,password) VALUES ('user1','password1'), ('user2','password2');
 5 Query OK, 2 rows affected (0.00 sec)
 6 
 7 Admin> SELECT username,password FROM mysql_users;
 8 +----------+-----------+
 9 | username | password  |
10 +----------+-----------+
11 | user1    | password1 |
12 | user2    | password2 |
13 +----------+-----------+
14 2 rows in set (0.00 sec)
15 
16 Admin> LOAD MYSQL USERS TO RUNTIME;
17 Query OK, 0 rows affected (0.00 sec)
18 
19 Admin> SELECT username,password FROM mysql_users;
20 +----------+-----------+
21 | username | password  |
22 +----------+-----------+
23 | user1    | password1 |
24 | user2    | password2 |
25 +----------+-----------+
26 2 rows in set (0.00 sec)
View Code

上面这一步,runtime的密码是被hash了的,但是mysql_users表中的任然没有被hash,为了是mysql_users表中的也hash:

 1 Admin> SAVE MYSQL USERS FROM RUNTIME;
 2 Query OK, 0 rows affected (0.00 sec)
 3 
 4 Admin> SELECT username,password FROM mysql_users;
 5 +----------+-------------------------------------------+
 6 | username | password                                  |
 7 +----------+-------------------------------------------+
 8 | user1    | *668425423DB5193AF921380129F465A6425216D0 |
 9 | user2    | *DC52755F3C09F5923046BD42AFA76BD1D80DF2E9 |
10 +----------+-------------------------------------------+
11 2 rows in set (0.00 sec)
View Code

然后我们就可以将他保存到磁盘:SAVE MYSQL USERS TO DISK

备注:

admin-hash_passwords是一个admin-变量,不是一个mysql-变量,这是因为他影响了admin的行为

这个细节很重要,因为你需要执行的是LOAD ADMIN VARIABLES TO RUNTIME,而不是LOAD MYSQL VARIABLES TO RUNTIME。

参考文档

原文地址:https://www.cnblogs.com/geek-ace/p/9566969.html