Создание нового пользователя и настройка прав в MySQL

GuDron

dumpz.ws
Admin
Регистрация
28 Янв 2020
Сообщения
7,690
Реакции
1,445
Credits
24,921

фронт.png

Введение​

Речь пойдет о работе с пользователями открытой реляционной системы управления базами данных (СУБД) MySQL, появившейся в 1994 году. В 2008 году Sun Microsystems купил MySQL AB, а в 2010 уже Sun была поглощена Oracle. Эти продажи побудили авторов исходной СУБД создать форк — MariaDB, свободный от лицензионных ограничений текущего владельца и совместимый с Oracle MySQL. Помимо «Марии» известен другой форк, Percona, — от Петра Зайцева и Вадима Ткаченко. Оба форка совместимы с MySQL.

БД от Percona обладает дополнительными функциями, направленными на повышение производительности. Многие дистрибутивы (например, Red Hat) перешли на MariaDB из-за предсказуемой лицензионной политики. В своих проектах автор использует MariaDB.

Есть несколько способов работы с БД MySQL: через графические phpMyAdmin, MySQL WorkBench и т.д.

Поскольку работа с пользователями задача больше административная и нерегулярная, рассмотрим наиболее надежный способ — через консоль.

Для этого понадобится минимум — консольный клиент mysql. Запускать его можно на своей рабочей станции (mysql —host=<адрес сервера> [—user=<name>] [—password=<pass>] [database]) или через ssh на самом сервере (в случае ОС Linux).

Зачем нужны пользователи​

После установки MySQL технически мы можем подключаться из нашего ПО от имени root’а, но это не безопасно. Работая с информационными системами, мы всегда должны помнить и соблюдать принцип наименьших привилегий. Для более безопасной работы и создаются пользователи БД. Привилегии должны быть предоставлены пользователю строго только те, что действительно необходимы.

Администратору MariaDB в работе требуется создавать учетные записи «обычных» пользователей с ограниченным доступом к данным, определять права доступа, при необходимости — создавать дополнительных (привилегированных) суперпользователей. Также важно проводить аудит — просматривать выданные полномочия и корректировать их по мере необходимости.

Имя пользователя MySQL​

В MySQL имя пользователя состоит из 2-х частей: имени пользователя (обязательно) и хоста (может быть опущена, тогда она означает ‘%’):
‘someuser’@’somehost’, аналогично, почтовому адресу.
Поняв это правило, посмотрим, как по умолчанию выглядит суперпользователь. На самом деле полностью учетка записывается трижды: ‘root’@’localhost’, ‘root’@’127.0.0.1’ и ‘root’@’::1’ с одинаковым парольным хешем.
В хостовой части могут использоваться DNS-имена, IP-адреса и символ подстановки %, обозначающий любой (любые) символы.
Примеры записи хоста:
Код:
somehost.example.com
localhost
127.0.0.1
::1
192.168.123.%
192.168.123.0/255.255.255.0
%
Примечание: имена и адреса следует указывать в том формате, в каком возвращает системный DNS resolver сервера.

Просмотр всех пользователей​

Давайте проверим, какие пользователи есть в нашей БД. Выведем основную информацию о пользователях:
Код:
SELECT host, user, password, password_expired FROM mysql.user;

Когда список получается большим, мы можем добавить фильтр (в примере — по хостам, начинающимся с msk):
Код:
SELECT host, user, password FROM mysql.user WHERE host LIKE 'msk%';

Или использовать в конце модификатор \G, оптимизирующий вывод для отображения в консоли:
Код:
SELECT host, user, password FROM mysql.user\G;

Подробная информация:
Код:
SELECT * FROM mysql.user[\G];

Создание нового пользователя MySQL​

Новый пользователь в MySQL добавляется командой:
Код:
CREATE USER 'some_user'@'somehost.somedomain' IDENTIFIED BY 'some_password';

Теперь давайте создадим нашего первого пользователя:
Код:
CREATE USER 'test'@'localhost' IDENTIFIED BY 'secret';
FLUSH PRIVILEGES;

Полезная возможность — добавление комментария:
Код:
CREATE USER 'test'@'localhost' COMMENT 'My 1st user for app';

FLUSH PRIVILEGES​

Обратите внимание на эту команду: она дает серверу команду перечитать привилегии. Как следует из Для просмотра ссылки Войди или Зарегистрируйся, команда FLUSH PRIVILEGES в MySQL нужна только в случае прямой модификации таблиц привилегий MySQL операторами типа INSERT, UPDATE или DELETE. Но для простоты запоминания будем указывать ее и для «правильных» операторов таких как GRANT, REVOKE, SET PASSWORD и RENAME USER, как в примере выше и остальных, используемых в статье.

Удаление пользователя MySQL​

Для удаления пользователя используется команда
Код:
DROP USER 'some_user'@'somehost.somedomain';

На нашем предыдущем примере:
Код:
DROP USER 'test'@'localhost';
FLUSH PRIVILEGES;

Создание дополнительного суперпользователя​

Это не лучшая практика, но бывают ситуации, когда у СУБД несколько хозяев и всем нужно быть суперпользователями. В MySQL добавить пользователя с root-правами можно так:
Код:
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Теперь пользователь root безопасно хранится у нас, а для административной работы с БД мы можем передать коллегам или партнерам учетную запись admin.

Отзыв полномочий у пользователя​

Команда отзыва привилегий функционально обратна GRANT, “TO” заменяется на “FROM”:
Код:
REVOKE SELECT ON `somedb`.* FROM 'someuser'@'somehost';
REVOKE ALL PRIVILEGES ON `somedb`.* FROM 'someuser'@'somehost';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'someuser'@'somehost';

Смена пароля​

Для изменения пароля учетной записи пользователя применяется команда ALTER USER:
Код:
ALTER USER 'test_user'@'localhost' IDENTIFIED BY 'new_password';

Предоставление доступа пользователю MySQL​

Доступ предоставляется командой:
Код:
GRANT SELECT ON `some_db`.* TO 'some_user'@'somehost.somedomain';
FLUSH PRIVILEGES;

Допустим, наше ПО использует базу данных test_db. Для его работы мы создали пользователя test_user, а FQDN хоста, где работает ПО — наш локальный хост (localhost). Наше приложение только считывает данные из БД — выполняет SELECT.

Создадим пользователя и БД (часто БД называют схемой, в терминах MySQL):
Код:
CREATE SCHEMA test_DB;
CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'secret';

Команда для предоставления доступа будет выглядеть так:
Код:
GRANT SELECT ON `test_db`.* TO 'test_user'@'localhost';
FLUSH PRIVILEGES;

Наследование привилегий​

В предыдущем примере наш пользователь сможет только читать данные из базы test_db, но передать свои права другому пользователю не сможет. Используя GRANT OPTION, мы можем позволить ему сделать это. Тогда пользователь получит возможность передавать другим то, что разрешено ему самому.
Код:
GRANT SELECT, INSERT, UPDATE, DELETE ON `some_db`.* TO 'some_user'@'somehost' WITH GRANT OPTION;

В этом примере some_user может поделиться правами на SELECT, INSERT, UPDATE, DELETE для базы some_db.
Из соображений безопасности использовать GRANT OPTION небезопасно! В случае компрометации учетной записи злоумышленник сможет не только получить доступ к данным, но и сделать закладку в виде копии учетной записи.

Доступ к таблице​

Примеры выше дают доступ ко всей БД. Часто доступ должен быть ограничен строго определенным набором таблиц:
Код:
GRANT SELECT ON `test_db`.`table_users` TO 'test_user'@'localhost';

Выполнение команды приведет к ошибке, т.к. этой таблицы еще нет.
Создадим ее
Код:
CREATE TABLE `test_db`.`table_users` (id INT AUTO_INCREMENT PRIMARY KEY, user_name VARCHAR(16) NOT NULL, password VARCHAR(32));

и повторим предоставление доступа:
Код:
GRANT SELECT ON `test_db`.`table_users` TO 'test_user'@'localhost';

Доступ к столбцу​

Предоставляется перечислением столбцов:
Код:
GRANT SELECT (id, user_name), UPDATE (user_name) ON `test_db`.`table_users` TO 'test_user'@'localhost';
В этом примере пользователю дано право читать идентификатор, читать и менять имя пользователя, а парольный хэш доступен не будет.

Просмотр привилегий пользователей MySQL​

Часто возникает задача выяснить полномочия учетной записи или определить, кому дан доступ к базе или таблице. Остановимся на этом подробнее.

Проверка текущих полномочий пользователя​

Нам пригодится команда:
Код:
SHOW GRANTS FOR 'someuser'@'somehost.somedomain';

Пример:
SHOW GRANTS FOR 'appuser'@'srv14.example.com';
+--------------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected] |
+--------------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'appuser'@'srv14.example.com' IDENTIFIED BY PASSWORD '*F4E0A7F0B10264F70558CF07A4ABD4E041182D6E' |
| GRANT SELECT ON `net_database`.* TO 'appuser'@'srv14.example.com' |
+--------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

Проверка полномочий к данным​

Через read-only БД Для просмотра ссылки Войди или Зарегистрируйся доступно множество метаданных — системной информации. Информация о доступе на БД (схемы), таблицы и столбцы доступны в таблицах schema_privileges, table_privileges и column_privileges. Работа с ними — обычные SQL-запросы:
Код:
SELECT * FROM information_schema.schema_privileges;
SELECT * FROM information_schema.table_privileges;
SELECT * FROM information_schema.column_privileges;
SELECT * FROM information_schema.column_privileges WHERE GRANTEE="'test_user'@'localhost'";

Пример:
MariaDB [information_schema]> select * from information_schema.column_privileges WHERE GRANTEE="'test_user'@'localhost'";
+-------------------------+---------------+--------------+------------+-------------+----------------+--------------+
| GRANTEE | TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | PRIVILEGE_TYPE | IS_GRANTABLE |
+-------------------------+---------------+--------------+------------+-------------+----------------+--------------+
| 'test_user'@'localhost' | def | test_db | table_usr | id | INSERT | NO |
| 'test_user'@'localhost' | def | test_db | table_usr | user_name | UPDATE | NO |
+-------------------------+---------------+--------------+------------+-------------+----------------+--------------+
2 rows in set (0.001 sec)

Просмотр привилегий через системную БД mysql​

Аналогичных результатов можно добиться, обратившись к системным таблицам напрямую.

Информация о пользователях:
Код:
SELECT * FROM mysql.user;

Привилегии на базы данных:
Код:
SELECT * FROM mysql.db;

Права, назначенные на таблицы:
Код:
SELECT * FROM mysql.tables_priv;

И на столбцы:
Код:
SELECT * FROM mysql.columns_priv;

Просмотр глобальных привилегий​

Для просмотра ссылки Войди или Зарегистрируйся полномочия смотрим здесь:
Код:
SELECT * FROM information_schema.user_privileges;

Заключение​

Полученная информация поможет выполнить базовые операции при работе с пользователями: создание и удаление учетных записей, предоставление и отзыв привилегий, а также просмотр прав доступа.

При выдаче прав избегайте избыточности. Права не нужно выдавать с запасом, часто выполнение GRANT ALL PRIVILEGES ON *.* TO ‘myUser’@’%’ — не лучший выход. Другой важный момент, часто упускаемый из виду новичками, — наличие в имени хостовой части. Игнорирование хоста может привести к ошибкам.