Статьи

Эмуляция ролей MySQL с помощью плагина Percona PAM и пользователей прокси

Время от времени люди задаются вопросом, как реализовать роли в MySQL. Это может быть полезно для компаний, имеющих дело со многими учетными записями пользователей, или для компаний с жесткими требованиями безопасности (например, PCI или HIPAA). Роли не существуют в обычном MySQL, но вот пример того, как их эмулировать, используя Percona Server, плагин PAM и прокси-пользователей.

Цель

Скажем, у нас есть 2 базы данных: db1 и db2, и мы хотим иметь возможность создавать 3 роли:

  • db1_dev: может читать и писать только на db1.
  • db2_dev: может читать и писать только на db2.
  • статистика: можно читать на db1 и db2

Для каждой роли мы создадим одного пользователя: joe (db1_dev), mike (db2_dev) и tom (stats).

Настройка плагина Percona PAM

Плагин Percona PAM распространяется с Percona Server 5.5 и 5.6. В этом посте я буду использовать Percona Server 5.6 и буду аутентифицировать пользователей с помощью /etc/shadow. Как объяснено здесь , настройка проста:

  • Убедитесь, что /etc/shadowпользователь mysql может прочитать его:
    # chgrp mysql /etc/shadow
    # chmod g+r /etc/shadow
  • Установите плагин:
    mysql> INSTALL PLUGIN auth_pam SONAME 'auth_pam.so';
  • Создайте /etc/pam.d/mysqldфайл, содержащий:
    auth       required     pam_warn.so
    auth       required     pam_unix.so audit
    account    required     pam_unix.so audit

Повозиться с разрешениями /etc/shadowможет из соображений безопасности. Аутентификация пользователей на сервере LDAP может быть лучшим вариантом. Конфигурация плагина PAM аналогична (замените pam_unix.soна pam_ldap.soи забудьте часть о /etc/shadow).

Тестирование аутентификации с помощью плагина PAM

Теперь давайте создадим пользователя:

# adduser test_pam
# passwd test_pam
mysql> GRANT ALL PRIVILEGES ON db1.* TO test_pam@localhost IDENTIFIED WITH auth_pam;

И давайте проверим, что аутентификация работает так, как мы ожидаем:

mysql -utest_pam -p
Enter password:
mysql> show grants;
+-----------------------------------------------------------+
| Grants for test_pam@localhost                             |
+-----------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test_pam'@'localhost'              |
| GRANT ALL PRIVILEGES ON `db1`.* TO 'test_pam'@'localhost' |
+-----------------------------------------------------------+

Это работает! Мы можем удалить пользователя и перейти к следующему шагу.

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

Ключом к эмуляции роли является создание учетной записи MySQL, для которой никто не будет знать пароль (тогда никто не сможет использовать его напрямую). Вместо этого мы будем использовать PROXYпривилегию, чтобы убедиться, что мы сопоставляем анонимную учетную запись, которая будет сопоставлять любого входящего пользователя с правильным пользователем MySQL.

Итак, первый шаг — создать анонимного пользователя:

mysql> CREATE USER ''@'' IDENTIFIED WITH auth_pam AS 'mysqld, pam_db1=db1_dev, pam_db2=db2_dev, pam_stats=stats';

Цель этого пользователя — просто сопоставить пользователей Unix в группе pam_db1 с пользователем MySQL db1_dev, пользователями Unix в группе pam_db2 с пользователем MySQL db2_dev и пользователями Unix в группе pam_stats с пользователем MySQL stats.

Создание прокси-аккаунтов

Теперь мы можем создавать пользователей MySQL, соответствующих каждой роли, которую мы хотим создать:

mysql> GRANT SELECT, INSERT ON db1.* TO 'db1_dev'@localhost IDENTIFIED BY 'XXXXX';
mysql> GRANT PROXY ON 'db1_dev'@'localhost' TO ''@'';
mysql> GRANT SELECT, INSERT ON db2.* TO 'db2_dev'@localhost IDENTIFIED BY 'YYYYY';
mysql> GRANT PROXY ON 'db2_dev'@'localhost' TO ''@'';
mysql> GRANT SELECT ON db1.* TO 'stats'@localhost IDENTIFIED BY 'ZZZZZ';
mysql> GRANT SELECT ON db2.* TO 'stats'@localhost;
mysql> GRANT PROXY ON 'stats'@'localhost' TO ''@'';

Создание учетных записей пользователей Unix

Последний шаг — создать пользователей Unix joe, mike и tom и назначить им правильную группу:

# useradd joe
# passwd joe
# groupadd pam_db1
# usermod -g pam_db1 joe
# useradd mike
# passwd mike
# groupadd pam_db2
# usermod -g pam_db2 mike
# useradd tom
# passwd tom
# groupadd pam_stats
# usermod -g pam_stats tom

Опять же, вы можете предпочесть использовать сервер LDAP, чтобы избежать создания пользователей на уровне ОС.

Тестирование это!

Давайте попробуем подключиться как майк:

# mysql -umike -p
Enter password:
mysql> show grants;
+----------------------------------------------------------------------------------------------------------------+
| Grants for db2_dev@localhost                                                                                   |
+----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'db2_dev'@'localhost' IDENTIFIED BY PASSWORD '*C1DDB6E980040762275B29A316FD993B4A19C108' |
| GRANT SELECT, INSERT ON `db2`.* TO 'db2_dev'@'localhost'                                                       |
+----------------------------------------------------------------------------------------------------------------+

Неплохо!

альтернативы

Плагин Percona PAM — не единственный вариант использования ролей:

  • MariaDB 10 поддерживает роли с версии 10.0.5
  • Oracle распространяет плагин PAM для MySQL 5.5 и MySQL 5.6 в рамках подписки MySQL Enterprise
  • Securich представляет собой набор хранимых процедур, который имеет много функций, касающихся управления пользователями
  • Google уже давно предлагает поддержку ролей через google-mysql-tools .

Вывод

Даже если они официально не поддерживаются, роли можно эмулировать с помощью плагина аутентификации и прокси-пользователя. Будем надеяться, что роли будут добавлены в MySQL 5.7!