Главная » Базы данных » Настройка минимальной безопасности MySQL и MariaDB после установки

Настройка минимальной безопасности MySQL и MariaDB после установки

Сразу после установки MySQL или MariaDB сервер работает, но настройки рассчитаны на удобство, а не на безопасность: где-то есть тестовая база и анонимные учётные записи, где-то сервер слушает все сетевые интерфейсы. Всё это стоит закрыть до того, как на сервер попадут рабочие данные.

Коротко: запустите mysql_secure_installation (в MariaDB — mariadb-secure-installation), удалите анонимных пользователей и тестовую базу, запретите удалённый вход root, оставьте сервер слушать только 127.0.0.1, если к нему не нужны внешние подключения, и создайте для каждого приложения отдельного пользователя с правами только на свою базу.

Шаг 1. Скрипт первичной настройки

В MySQL скрипт называется mysql_secure_installation. В MariaDB он переименован в mariadb-secure-installation, старое имя в большинстве сборок оставлено как ссылка. Запускается от root операционной системы:

sudo mariadb-secure-installation   # MariaDB 10.11, 11.x
sudo mysql_secure_installation     # MySQL 8.0, 8.4

Скрипт задаёт вопросы по порядку. По документации MySQL и MariaDB он позволяет:

  • задать или сменить пароль root;
  • удалить учётные записи root, доступные не с локального хоста;
  • удалить анонимных пользователей;
  • удалить базу test и права на базы с именами test_…;
  • перечитать таблицы привилегий.

На вопросы «Remove anonymous users?», «Disallow root login remotely?», «Remove test database and access to it?» и «Reload privilege tables now?» я всегда отвечаю Y. В свежих установках анонимных пользователей и тестовой базы может уже не быть — тогда эти шаги просто ничего не изменят.

MySQL дополнительно предлагает включить компонент validate_password, который проверяет сложность паролей. На сервере, где пароли создают люди, его стоит включить.

Учётная запись root: unix_socket и auth_socket

На Debian и Ubuntu root базы данных по умолчанию входит не по паролю, а по сокету: сервер проверяет, что клиент запущен от root операционной системы. Поэтому для администрирования достаточно sudo mariadb или sudo mysql, и пароль root никто не подберёт по сети.

MariaDB

Начиная с MariaDB 10.4 root@localhost создаётся с двумя способами входа: плагин unix_socket и mysql_native_password с заведомо неверным паролем. Поэтому скрипт пишет «You already have your root account protected, so you can safely answer ‘n’.» Вопросы «Switch to unix_socket authentication» и «Change the root password?» можно пропустить ответом n. Проверить, как настроен root:

sudo mariadb -e "SHOW CREATE USER 'root'@'localhost';"

MySQL

В пакете mysql-server из репозитория Ubuntu root получает плагин auth_socket. В старых сборках скрипт на шаге смены пароля падал с ошибкой «SET PASSWORD has no significance for user ‘root’@’localhost’ as the authentication method used doesn’t store authentication data in the MySQL server», в исправленных этот шаг пропускается. Менять плагин root на парольный ради скрипта не нужно. Посмотреть текущий плагин:

sudo mysql -e "SELECT user, host, plugin FROM mysql.user;"

В Debian MySQL штатно не поставляется, вместо него идёт MariaDB. Если MySQL ставится из репозитория Oracle, пароль root задаётся при установке пакета. В MySQL 8.4 плагин mysql_native_password по умолчанию отключён, новые пользователи создаются с caching_sha2_password.

Шаг 2. Только локальные подключения

Если база нужна только сайтам на этом же сервере, порт 3306 не должен быть доступен извне. Сначала посмотрите, на каком адресе слушает сервер:

sudo ss -tlnp | grep -E 'mysqld|mariadbd'

Нужная строка — 127.0.0.1:3306. Если там 0.0.0.0:3306 или *:3306, задайте адрес в секции [mysqld]:

[mysqld]
bind-address = 127.0.0.1
СборкаФайл конфигурацииЗначение по умолчанию
MariaDB в Debian и Ubuntu/etc/mysql/mariadb.conf.d/50-server.cnf127.0.0.1
MySQL в Ubuntu/etc/mysql/mysql.conf.d/mysqld.cnf127.0.0.1
MariaDB в AlmaLinux и Rocky/etc/my.cnf.d/mariadb-server.cnfне задан — все интерфейсы
MySQL без явной настройки—* — все интерфейсы

У MySQL 8 есть ещё порт 33060 (X Protocol), его адрес задаёт параметр mysqlx-bind-address. Если X Protocol не используется, его тоже стоит ограничить локальным адресом. После правки перезапустите службу: sudo systemctl restart mariadb или sudo systemctl restart mysql (в AlmaLinux — mysqld).

Если внешний доступ всё-таки нужен (отдельный сервер приложений, репликация), укажите конкретный внутренний адрес. MySQL 8 принимает список адресов через запятую. Дополнительно откройте порт в файрволе только для нужных IP.

Шаг 3. Отдельный пользователь на каждое приложение

Сайт не должен подключаться к базе под root. Для каждого приложения создаётся своя база и свой пользователь с правами только на неё:

CREATE DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'shop'@'localhost' IDENTIFIED BY 'длинный-случайный-пароль';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP,
      CREATE TEMPORARY TABLES, LOCK TABLES ON shop.* TO 'shop'@'localhost';

Набор прав зависит от приложения: CMS обычно нужны права на изменение структуры таблиц для обновлений, а сервису отчётов хватит SELECT. Не выдавайте ALL PRIVILEGES ON *.*, GRANT OPTION, FILE, SUPER и PROCESS пользователям приложений. Проверить, что получилось:

SHOW GRANTS FOR 'shop'@'localhost';
SELECT user, host FROM mysql.user;

Во втором запросе ищите лишние записи: пользователей с пустым именем, хост % там, где он не нужен, старые учётки удалённых сайтов. Если пароль root всё же утерян, порядок действий описан в статье Сброс пароля root в MySQL 8 и MariaDB.

Что ещё проверить

  • Обновления: ставьте MySQL и MariaDB из репозитория дистрибутива или официального репозитория проекта, а не вручную, чтобы получать исправления безопасности вместе с системой.
  • Права на каталог данных (/var/lib/mysql): владелец mysql, без доступа для остальных пользователей.
  • Резервные копии: их тоже нужно защищать, в дампе есть всё содержимое базы.

После защиты можно переходить к производительности — об этом статья Оптимизация MySQL 8 и MariaDB, MySQLTuner.

Частые вопросы

Нужно ли задавать пароль root, если работает unix_socket?

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

Как подключиться к базе через phpMyAdmin, если root входит по сокету?

phpMyAdmin работает от пользователя веб-сервера, поэтому войти под root через сокет не сможет. Создайте отдельного пользователя с паролем и нужными правами, а root оставьте для консоли.

Можно ли запустить mysql_secure_installation повторно?

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