
Говорят, что лучший пароль — тот, который не надо запоминать. В случае с MySQL это реально благодаря плагину auth_socket и его версии для MariaDB — unix_socket.
Оба эти плагина — вовсе не новы, о них много говорилось в этом же блоге, например в статье о том, как изменять пароли в MySQL 5.7, используя плагин auth_socket. Однако, разбирая, что новенького в MariaDB 10.4, я обнаружил, что unix_socket теперь устанавливается по умолчанию и является одним из методов аутентификации ("одним из", потому как в MariaDB 10.4 одному пользователю для аутентификации доступно больше одного плагина, что и объяснятется в документе "Аутентификация" от MariaDB 10.04).
Как я уже сказал, это — не новости, и когда устанавливаешь MySQL, используя поддерживаемые командой Debian пакеты .deb, пользователь с root-правами создается под аутентификацию через сокет. Это справедливо как для MySQL, так и для MariaDB.
root@app:~# apt-cache show mysql-server-5.7 | grep -i maintainers Original-Maintainer: Debian MySQL Maintainers <pkg-mysql-maint@lists.alioth.debian.org> Original-Maintainer: Debian MySQL Maintainers <<a href="mailto:pkg-mysql-maint@lists.alioth.debian.org">pkg-mysql-maint@lists.alioth.debian.org</a>>
С пакетами Debian для MySQL, 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)
То же и в случае с пакетом .deb для MariaDB:
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)
Пакеты .deb из официального репозитория Percona также настраивают аутентификацию пользователя с root-правами под auth-socket и для Percona Server. Приведем пример с Percona Server for 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)
Так в чем же магия? Плагин проверяет, что пользователь Linux соответствует пользователю MySQL, используя сокет-опцию SO_PEERCRED — чтобы собрать информацию о пользователе, запускающем клиентскую программу. Таким образом, плагин можно использовать только на системах, поддерживающих опцию 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 дистрибутива, где это не предусмотрено по умолчанию? Попробуем Percona Server for MySQL 8, установленный на CentOS 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, чтобы по-прежнему получать доступ, но без паролей.
