Лучшие практики предоставления и отзыва привилегий пользователей MySQL

Используйте MySQL GRANT, REVOKE, SHOW GRANTS и DROP USER безопасно с примерами минимальных привилегий для приложений и учетных записей администраторов.

Лучшие практики предоставления и отзыва привилегий пользователей MySQL

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

Используйте GRANT, REVOKE и SHOW GRANTS с принципом наименьших привилегий: каждая учетная запись должна иметь только те разрешения, которые ей нужны, и только с тех хостов, которые она использует.

Понимание привилегий MySQL

Прежде чем углубляться в GRANT и REVOKE, важно понять различные области и типы привилегий, доступных в MySQL. Привилегии определяют, какие действия может выполнять пользователь и над какими объектами базы данных.

Привилегии MySQL можно классифицировать по их области:

  • Глобальные привилегии (*.*): Применяются ко всем базам данных и таблицам на сервере MySQL. Примеры: SUPER, PROCESS, RELOAD, CREATE USER.
  • Привилегии базы данных (database_name.*): Применяются ко всем таблицам и объектам в конкретной базе данных. Примеры: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP.
  • Привилегии таблицы (database_name.table_name): Применяются ко всем столбцам в конкретной таблице. Примеры: SELECT, INSERT, UPDATE, DELETE, ALTER.
  • Привилегии столбца (database_name.table_name.column_name): Применяются к конкретным столбцам в таблице. Это менее распространено, но полезно для очень детального контроля.
  • Привилегии процедур (database_name.routine_name): Применяются к хранимым процедурам и функциям, контролируя EXECUTE и ALTER ROUTINE.
  • Прокси-привилегии: Позволяют одному пользователю действовать от имени другого, полезно для приложений, управляющих пользовательскими идентификаторами.

Некоторые распространенные конкретные привилегии включают:

  • SELECT: Чтение данных из таблиц.
  • INSERT: Добавление новых строк в таблицы.
  • UPDATE: Изменение существующих строк в таблицах.
  • DELETE: Удаление строк из таблиц.
  • CREATE: Создание баз данных, таблиц или индексов.
  • DROP: Удаление баз данных, таблиц или индексов.
  • ALTER: Изменение структур таблиц.
  • INDEX: Создание или удаление индексов.
  • REFERENCES: Установка ограничений внешнего ключа.
  • CREATE VIEW, SHOW VIEW: Управление представлениями.
  • CREATE ROUTINE, ALTER ROUTINE, EXECUTE: Управление и выполнение хранимых процедур и функций.
  • FILE: Чтение или запись файлов на хосте сервера (очень мощная, используйте с крайней осторожностью).
  • GRANT OPTION: Позволяет пользователю предоставлять свои привилегии другим пользователям. Это очень мощная привилегия, и ее следует предоставлять с осторожностью.

Команда GRANT: безопасное предоставление привилегий

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

Базовый синтаксис

Общий синтаксис команды GRANT:

GRANT privileges ON object TO 'user'@'host' [WITH GRANT OPTION];
  • privileges: Список привилегий, разделенных запятыми (например, SELECT, INSERT).
  • object: Указывает область (например, *.* для глобальной, database_name.*, database_name.table_name).
  • 'user'@'host': Учетная запись пользователя, включая имя пользователя и хост, с которого он может подключаться. host может быть IP-адресом, именем хоста или подстановочным знаком (% для любого хоста, localhost для локальных подключений).
  • WITH GRANT OPTION: (Необязательно) Позволяет пользователю предоставлять указанные привилегии другим пользователям.

Создавайте или изменяйте пароли с помощью CREATE USER и ALTER USER. В старых версиях MySQL допускалось GRANT ... IDENTIFIED BY, но современный синтаксис MySQL разделяет создание учетной записи.

Практические примеры

Давайте рассмотрим несколько распространенных сценариев.

  1. Создание нового пользователя и предоставление глобального доступа только для чтения (настоятельно не рекомендуется)

    CREATE USER 'global_reader'@'localhost' IDENTIFIED BY 'StrongPass123!';
    GRANT SELECT ON *.* TO 'global_reader'@'localhost';
    

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

  2. Предоставление полного доступа к конкретной базе данных для пользователя приложения

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

    CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'AppPassSecure!';
    GRANT SELECT, INSERT, UPDATE, DELETE ON `myapp_db`.* TO 'app_user'@'localhost';
    

    Здесь app_user может выполнять основные операции CRUD только в базе данных myapp_db, но не может создавать новые таблицы или изменять схему.

  3. Предоставление доступа только для чтения к конкретной таблице

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

    CREATE USER 'report_tool'@'%' IDENTIFIED BY 'ReportSecret!';
    GRANT SELECT ON `sales_db`.`orders` TO 'report_tool'@'%';
    

    Хост '%' позволяет report_tool подключаться с любого хоста, но только с доступом SELECT к таблице orders в sales_db.

  4. Предоставление GRANT OPTION (используйте с крайней осторожностью)

    Если администратору необходимо делегировать управление привилегиями для конкретной базы данных.

    CREATE USER 'db_admin'@'localhost' IDENTIFIED BY 'AdminPass#456';
    GRANT ALL PRIVILEGES ON `inventory_db`.* TO 'db_admin'@'localhost' WITH GRANT OPTION;
    

    Теперь db_admin может предоставлять любые привилегии на inventory_db другим пользователям. Это мощная привилегия, которая обходит централизованный контроль, и ее следует использовать только в случае крайней необходимости.

Советы по предоставлению привилегий

  • Принцип наименьших привилегий: Всегда предоставляйте минимальный набор привилегий, необходимых пользователю или приложению для работы. Избегайте ALL PRIVILEGES, если только это не учетная запись выделенного администратора базы данных.
  • Конкретные хосты: Ограничьте подключения пользователей конкретными IP-адресами или именами хостов ('user'@'192.168.1.10' или 'user'@'appserver.example.com') вместо '%', где это возможно.
  • Отдельные пользователи: Создавайте отдельные учетные записи пользователей для разных приложений или служб, даже если они обращаются к одной и той же базе данных. Это изолирует потенциальные нарушения безопасности.
  • Без root для приложений: Никогда не используйте учетную запись root для своих приложений. Создавайте выделенных пользователей с наименьшими привилегиями.

Команда REVOKE: эффективный отзыв привилегий

Команда REVOKE используется для удаления привилегий у пользователя MySQL. Она так же важна, как и GRANT, для поддержания безопасной среды базы данных, особенно когда меняются роли или приложения выводятся из эксплуатации.

Базовый синтаксис

Общий синтаксис команды REVOKE:

REVOKE privileges ON object FROM 'user'@'host';
  • privileges: Список привилегий для отзыва, разделенных запятыми.
  • object: Область, из которой отзываются привилегии (должна совпадать с областью, где были предоставлены привилегии).
  • 'user'@'host': Учетная запись пользователя, у которой отзываются привилегии.

Практические примеры

  1. Отзыв привилегии DELETE у пользователя приложения

    Если приложению больше не нужно удалять данные или вы хотите понизить его разрешения.

    REVOKE DELETE ON `myapp_db`.* FROM 'app_user'@'localhost';
    

    Теперь app_user все еще может выполнять SELECT, INSERT и UPDATE, но не может DELETE в myapp_db.

  2. Отзыв GRANT OPTION у делегированного администратора

    Если db_admin больше не нужно управлять разрешениями других пользователей для inventory_db.

    REVOKE GRANT OPTION ON `inventory_db`.* FROM 'db_admin'@'localhost';
    

    Примечание: Чтобы отозвать GRANT OPTION, вы должны явно указать GRANT OPTION в операторе REVOKE.

  3. Отзыв всех привилегий на конкретную базу данных

    Чтобы удалить все привилегии, которые пользователь имеет на определенную базу данных.

    REVOKE ALL PRIVILEGES ON `old_db`.* FROM 'old_app'@'%';
    

    Предупреждение: REVOKE ALL PRIVILEGES на *.* отзовет все глобальные привилегии, которые могут включать SUPER, CREATE USER и т.д. Будьте осторожны при использовании этой области глобально.

  4. Удаление учетной записи пользователя

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

    DROP USER 'report_tool'@'%';
    

    Эта команда удаляет пользователя и все связанные с ним привилегии.

Советы по отзыву привилегий

  • Совпадение области: При отзыве убедитесь, что область объекта (*.*, database_name.* и т.д.) точно соответствует тому, как привилегия была изначально предоставлена. Если вы предоставили SELECT на database_name.*, вы должны отозвать его с database_name.*, а не с database_name.table_name.
  • Проверка: Всегда используйте SHOW GRANTS FOR 'user'@'host'; после предоставления или отзыва привилегий, чтобы подтвердить изменения.
  • Пропустите ненужные сбросы: FLUSH PRIVILEGES не требуется после GRANT, REVOKE, CREATE USER или DROP USER; MySQL применяет эти операторы немедленно.
  • Учитывайте каскадные эффекты: Если пользователь с GRANT OPTION предоставил привилегии другим, отзыв его GRANT OPTION не отзывает автоматически предоставленные им привилегии. Вам нужно будет отозвать их отдельно.

Лучшие практики управления привилегиями пользователей MySQL

Внедрение надежной стратегии управления привилегиями имеет решающее значение для безопасности базы данных.

1. Принцип наименьших привилегий (PoLP)

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

  • Инструменту отчетности нужен SELECT.
  • Веб-приложению обычно нужны SELECT, INSERT, UPDATE, DELETE.
  • Процессу ETL могут понадобиться INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE (но только для конкретных промежуточных схем).

2. Выделенные учетные записи пользователей

  • Избегайте общих учетных записей: Каждое приложение, служба или административный пользователь должны иметь свою уникальную учетную запись пользователя MySQL. Это помогает в аудите и отслеживании активности.
  • Без root для приложений: Никогда не настраивайте свои приложения на подключение как пользователь root. Пользователь root имеет неограниченный доступ и должен использоваться только для критических административных задач администраторами-людьми.

3. Надежные пароли и ротация паролей

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

4. Ограничения по хосту

  • По возможности ограничивайте подключения пользователей конкретными IP-адресами или именами хостов. Замените '%' на localhost, IP-адрес сервера приложений или подсеть ('user'@'192.168.1.%'). Это предотвращает попытки несанкционированного доступа из неизвестных мест.

5. Регулярные аудиты и проверки

  • Периодически проверяйте все учетные записи пользователей и связанные с ними привилегии. Удаляйте устаревшие учетные записи или ненужные привилегии.
  • Используйте SHOW GRANTS FOR 'user'@'host'; для проверки разрешений.
  • Рассмотрите автоматизированные инструменты для аудита больших сред.

6. Документируйте разрешения

  • Ведите четкую документацию пользователей базы данных, их ролей и предоставленных каждому привилегий. Это помогает поддерживать согласованность и облегчает аудит безопасности.

7. Разделяйте среды разработки, тестирования и производства

  • Никогда не используйте производственные учетные данные в средах разработки или тестирования. Каждая среда должна иметь свой собственный набор различных пользователей и привилегий.

8. Избегайте GRANT OPTION, если это абсолютно необходимо

  • Предоставление WITH GRANT OPTION делегирует управление привилегиями этому пользователю, что может обойти центральные политики безопасности. Оставляйте это только для очень доверенных административных пользователей и в максимально ограниченной области.

Просмотр текущих привилегий

Чтобы проверить привилегии, назначенные пользователю, используйте команду SHOW GRANTS:

SHOW GRANTS FOR 'username'@'host';

Пример:

SHOW GRANTS FOR 'app_user'@'localhost';

Вывод может выглядеть так:

+-------------------------------------------------------------+
| Grants for app_user@localhost                               |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'app_user'@'localhost'                |
| GRANT SELECT, INSERT, UPDATE ON `myapp_db`.* TO 'app_user'@'localhost' |
+-------------------------------------------------------------+

Строка GRANT USAGE ON *.* указывает, что пользователь не имеет глобальных привилегий, только возможность подключаться.

Вывод

Поддерживайте управление привилегиями MySQL узким и проверяемым. Создавайте выделенные учетные записи, ограничивайте хосты, предоставляйте только необходимые действия в наименьшей полезной области и проверяйте каждое изменение с помощью SHOW GRANTS. Когда приложению или человеку больше не нужен доступ, отзывайте привилегию или удаляйте учетную запись, вместо того чтобы оставлять устаревшие учетные данные.