如何在没有密码的情况下使用 MySQL(以及安全风险)

如何在没有密码的情况下使用 MySQL(以及安全风险)

他们说最好的密码是您不必记住的密码。 对于 MySQL,这可以通过插件实现 auth_socket 及其 MariaDB 版本 - unix_socket.

这两个插件根本就不是什么新鲜事;在同一个博客中已经对它们进行了很多讨论,例如在关于 如何使用 auth_socket 插件更改 MySQL 5.7 中的密码。 然而,在研究 MariaDB 10.4 中的新增功能时,我发现 unix_socket 现在是默认安装的,并且是身份验证方法之一(“其中之一”,因为在 MariaDB 10.4 中,一个用户可以使用多个插件进行身份验证,这文档中有解释 MariaDB 10.04 中的“身份验证”).

正如我所说,这不是新闻,当使用 Debian 团队支持的 .deb 软件包安装 MySQL 时,会创建一个 root 用户用于套接字身份验证。 对于 MySQL 和 MariaDB 来说都是如此。

root@app:~# apt-cache show mysql-server-5.7 | grep -i maintainers
Original-Maintainer: Debian MySQL Maintainers <[email protected]>
Original-Maintainer: Debian MySQL Maintainers <<a href="mailto:[email protected]">[email protected]</a>>

对于 MySQL 的 Debian 软件包,root 用户的身份验证如下:

root@app:~# whoami
root=
root@app:~# mysql
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 4
Server version: 5.7.27-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> select user, host, plugin, authentication_string from mysql.user where user = 'root';
+------+-----------+-------------+-----------------------+
| user | host      | plugin | authentication_string |
+------+-----------+-------------+-----------------------+
| root | localhost | auth_socket |                       |
+------+-----------+-------------+-----------------------+
1 row in set (0.01 sec)

MariaDB 的 .deb 包也是如此:

10.0.38-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04

MariaDB [(none)]> show grants;
+------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                      |
+------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED VIA unix_socket WITH GRANT OPTION |
| GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION                                  |
+------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

来自官方 Percona 存储库的 .deb 包还在 auth-socket 和 Percona Server 下配置 root 用户身份验证。 让我们举个例子 Percona 服务器 MySQL 8.0.16-7 和 Ubuntu 16.04:

root@app:~# whoami
root
root@app:~# mysql
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 9
Server version: 8.0.16-7 Percona Server (GPL), Release '7', Revision '613e312'

Copyright (c) 2009-2019 Percona LLC and/or its affiliates
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> select user, host, plugin, authentication_string from mysql.user where user ='root';
+------+-----------+-------------+-----------------------+
| user | host      | plugin | authentication_string |
+------+-----------+-------------+-----------------------+
| root | localhost | auth_socket |                       |
+------+-----------+-------------+-----------------------+
1 row in set (0.00 sec)

那么有什么魔力呢? 该插件使用 SO_PEERCRED 套接字选项检查 Linux 用户是否与 MySQL 用户匹配,以收集有关运行客户端程序的用户的信息。 因此,该插件只能在支持 SO_PEERCRED 选项的系统上使用,例如 Linux。 SO_PEERCRED 套接字选项允许您找出与套接字关联的进程的 uid。 然后他已经收到与该 uid 关联的用户名。

这是用户“vagrant”的示例:

vagrant@mysql1:~$ whoami
vagrant
vagrant@mysql1:~$ mysql
ERROR 1698 (28000): Access denied for user 'vagrant'@'localhost'

由于MySQL中没有“vagrant”用户,因此我们被拒绝访问。 让我们创建一个这样的用户并重试:

MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'vagrant'@'localhost' IDENTIFIED VIA unix_socket;
Query OK, 0 rows affected (0.00 sec)

vagrant@mysql1:~$ mysql
Welcome to the MariaDB monitor.  Commands end with ; or g.
Your MariaDB connection id is 45
Server version: 10.0.38-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

MariaDB [(none)]> show grants;
+---------------------------------------------------------------------------------+
| Grants for vagrant@localhost                                                    |
+---------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'vagrant'@'localhost' IDENTIFIED VIA unix_socket |
+---------------------------------------------------------------------------------+
1 row in set (0.00 sec)

事实证明!

那么,默认情况下不提供此功能的非 Debian 发行版又如何呢? 让我们尝试在 CentOS 8 上安装 Percona Server for MySQL 7:

mysql> show variables like '%version%comment';
+-----------------+---------------------------------------------------+
| Variable_name   | Value                                   |
+-----------------+---------------------------------------------------+
| version_comment | Percona Server (GPL), Release 7, Revision 613e312 |
+-----------------+---------------------------------------------------+
1 row in set (0.01 sec)

mysql> CREATE USER 'percona'@'localhost' IDENTIFIED WITH auth_socket;
ERROR 1524 (HY000): Plugin 'auth_socket' is not loaded

真糟糕。 缺少什么? 插件未加载:

mysql> pager grep socket
PAGER set to 'grep socket'
mysql> show plugins;
47 rows in set (0.00 sec)

让我们向该流程添加一个插件:

mysql> nopager
PAGER set to stdout
mysql> INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
Query OK, 0 rows affected (0.00 sec)

mysql> pager grep socket; show plugins;
PAGER set to 'grep socket'
| auth_socket                     | ACTIVE | AUTHENTICATION | auth_socket.so | GPL     |
48 rows in set (0.00 sec)

现在我们已经拥有了我们需要的一切。 让我们再试一次:

mysql> CREATE USER 'percona'@'localhost' IDENTIFIED WITH auth_socket;
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON *.* TO 'percona'@'localhost';
Query OK, 0 rows affected (0.01 sec)

您现在可以使用用户名“percona”登录。

[percona@ip-192-168-1-111 ~]$ whoami
percona
[percona@ip-192-168-1-111 ~]$ mysql -upercona
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 19
Server version: 8.0.16-7 Percona Server (GPL), Release 7, Revision 613e312

Copyright (c) 2009-2019 Percona LLC and/or its affiliates
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> select user, host, plugin, authentication_string from mysql.user where user ='percona';
+---------+-----------+-------------+-----------------------+
| user    | host   | plugin   | authentication_string |
+---------+-----------+-------------+-----------------------+
| percona | localhost | auth_socket |                       |
+---------+-----------+-------------+-----------------------+
1 row in set (0.00 sec)

它又起作用了!

问题:是否可以使用相同的 percona 登录名但以不同的用户身份登录系统?

[percona@ip-192-168-1-111 ~]$ logout
[root@ip-192-168-1-111 ~]# mysql -upercona
ERROR 1698 (28000): Access denied for user 'percona'@'localhost'

不,它不会起作用。

结论

MySQL 在几个方面都相当灵活,其中之一就是身份验证方法。 正如您从这篇文章中看到的,根据操作系统用户,无需密码即可获得访问权限。 这在某些情况下很有用,其中之一是使用以下命令从 RDS/Aurora 迁移到常规 MySQL 时: IAM 数据库身份验证仍然可以获得访问权限,但无需密码。

来源: habr.com

添加评论