Лучшие практики по усилению безопасности конфигураций сервера MySQL
Усилите MySQL с помощью пользователей с минимальными привилегиями, ограничений по хостам, TLS, более безопасных настроек my.cnf, установки обновлений и базового аудита.
Лучшие практики по усилению безопасности конфигураций сервера MySQL
Усиление MySQL начинается с простого вопроса: что получит злоумышленник, если один пароль приложения утечет? Если ответ — «все базы данных откуда угодно», вашему серверу нужны более строгие пользователи, сетевые правила и конфигурация.
Используйте эти практики, чтобы уменьшить радиус поражения при компрометации, не усложняя повседневное администрирование.
1. Управление пользователями и доступом: принцип минимальных привилегий
Эффективное управление пользователями является основой безопасности MySQL. Предоставление пользователям только тех разрешений, которые им абсолютно необходимы, имеет первостепенное значение.
Создавайте конкретных пользователей для конкретных приложений
Избегайте использования пользователя root для подключений приложений. Вместо этого создавайте выделенных пользователей с детальными разрешениями.
CREATE USER 'my_app_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON `your_database`.* TO 'my_app_user'@'localhost';
Применяйте надежные пароли
Надежные уникальные пароли — ваша первая линия защиты. Используйте встроенный плагин проверки паролей MySQL, если он доступен.
- Сложность: смешивайте заглавные, строчные буквы, цифры и символы.
- Длина: стремитесь к длине не менее 12-16 символов.
- Уникальность: никогда не используйте пароли повторно.
- Ротация: внедрите политику регулярной смены паролей.
Вы можете включить компонент validate_password (MySQL 8.0+) или плагин (MySQL 5.7+):
INSTALL COMPONENT 'file://component_validate_password';
-- ИЛИ для старых версий
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
-- Настройка политики сложности (например, MEDIUM для 8+ символов, смесь регистров, цифры, спецсимволы)
SET GLOBAL validate_password.policy = MEDIUM;
SET GLOBAL validate_password.length = 12;
Удалите стандартных и неиспользуемых пользователей
MySQL может включать административные и внутренние учетные записи. Оставьте необходимые системные учетные записи, такие как mysql.session и mysql.sys, но удалите анонимные учетные записи и любые учетные записи людей или приложений, которые вы больше не используете.
-- Чтобы определить анонимных пользователей:
SELECT user, host FROM mysql.user WHERE user = '';
-- Чтобы удалить анонимного пользователя (если найден):
DROP USER ''@'localhost';
-- Чтобы удалить тестовые базы данных (если они существуют):
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';
FLUSH PRIVILEGES;
Ограничьте доступ по хосту
Ограничьте учетные записи пользователей возможностью подключаться только с определенных IP-адресов или имен хостов. Избегайте использования % в качестве подстановочного знака для хоста, если это абсолютно необходимо и не сочетается с другими строгими мерами безопасности.
-- Пользователь может подключаться только с localhost
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'AnotherStrongPass!';
-- Пользователь может подключаться только с определенного IP-адреса
CREATE USER 'backup_user'@'192.168.1.100' IDENTIFIED BY 'BackupPass!';
Будьте осторожны с GRANT OPTION
Пункт WITH GRANT OPTION позволяет пользователю предоставлять свои собственные привилегии другим пользователям. Это может представлять значительный риск безопасности, если предоставлено ненадежным пользователям. Используйте его экономно и только для административных учетных записей, которым действительно требуется эта возможность.
-- Пользователь с возможностью предоставлять привилегии (используйте с крайней осторожностью)
CREATE USER 'superadmin'@'localhost' IDENTIFIED BY 'SuperAdminPass!';
GRANT ALL PRIVILEGES ON *.* TO 'superadmin'@'localhost' WITH GRANT OPTION;
2. Сетевая безопасность: изоляция вашей базы данных
Сетевые средства контроля критически важны для предотвращения несанкционированного внешнего доступа к вашему серверу MySQL.
Настройте брандмауэры
Разрешайте подключения к порту MySQL по умолчанию (3306) только с доверенных IP-адресов или сетей. Блокируйте все остальные входящие подключения к этому порту.
Пример (UFW на Linux):
sudo ufw enable
sudo ufw allow from 192.168.1.0/24 to any port 3306
sudo ufw deny 3306
sudo ufw status
Пример (CentOS/RHEL с firewalld):
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept'
sudo firewall-cmd --permanent --remove-port=3306/tcp --zone=public # Убедитесь, что порт не открыт глобально
sudo firewall-cmd --reload
Защитите соединения с помощью SSL/TLS
Шифруйте весь трафик между клиентами и сервером MySQL с помощью SSL/TLS, чтобы предотвратить перехват и атаки «человек посередине» (MitM). Это особенно важно для соединений через ненадежные сети.
Чтобы включить SSL/TLS, обычно необходимо сгенерировать SSL-сертификаты и ключи, а затем настроить ваш my.cnf:
# my.cnf
[mysqld]
ssl_ca=/etc/mysql/certs/ca.pem
ssl_cert=/etc/mysql/certs/server-cert.pem
ssl_key=/etc/mysql/certs/server-key.pem
Затем клиенты должны быть настроены на подключение с использованием SSL/TLS, часто с помощью REQUIRE SSL в операторе GRANT пользователя:
CREATE USER 'ssl_user'@'%' IDENTIFIED BY 'SSLUserPass!';
GRANT SELECT ON `your_database`.* TO 'ssl_user'@'%' REQUIRE SSL;
Привяжите к определенным IP-адресам
По умолчанию MySQL может прослушивать все доступные сетевые интерфейсы (0.0.0.0). Ограничьте его прослушивание только теми интерфейсами, которые должны принимать соединения (например, localhost для локальных приложений или IP-адрес частной сети для внутренних подключений).
# my.cnf
[mysqld]
bind-address = 127.0.0.1 # Только для локальных подключений
# ИЛИ
bind-address = 192.168.1.10 # Для определенного внутреннего IP
Совет: Если ваше приложение и сервер MySQL находятся на одной машине,
bind-address = 127.0.0.1(localhost) — самый безопасный вариант, так как он полностью предотвращает любые внешние подключения.
3. Усиление конфигурационного файла (my.cnf / my.ini)
Конфигурационный файл MySQL (my.cnf на Linux, my.ini на Windows) предлагает множество параметров для повышения безопасности.
Отключите неиспользуемые функции
Минимизируйте поверхность атаки, отключив функции, не требующиеся для вашего развертывания.
local_infile = 0: ОтключаетLOAD DATA LOCAL INFILE, который в противном случае может читать файлы с клиентского хоста, если это разрешено и клиентом, и сервером.[mysqld] local_infile = 0skip-networking: Если к вашей базе данных обращаются только приложения на том же сервере, отключите сеть полностью. Это заставляет все соединения использовать Unix-сокет или именованные каналы.[mysqld] skip-networkingsymbolic-links = 0: Предотвращает использование символических ссылок для табличных пространств базы данных, которые могут быть использованы для доступа к файлам за пределами каталога данных MySQL.[mysqld] symbolic-links = 0secure_file_priv: Ограничивает каталог, используемый для операций импорта и экспорта файлов, таких какLOAD DATA INFILEиSELECT ... INTO OUTFILE.[mysqld] secure_file_priv = /var/lib/mysql-files
Установите secure_file_priv в выделенный каталог, принадлежащий учетной записи службы MySQL. Не указывайте на /tmp, каталог загрузки приложения или путь, в который могут писать ненадежные пользователи.
Избегайте секретов в открытом виде в файлах параметров
Файлы параметров клиента могут случайно раскрыть пароли базы данных любому, кто может их прочитать. Если вы должны хранить учетные данные для автоматизации, ограничьте права доступа к файлу и используйте выделенную учетную запись с низкими привилегиями.
chmod 600 /home/backup/.my.cnf
chown backup:backup /home/backup/.my.cnf
Для интерактивного администрирования предпочтительнее запрашивать пароль:
mysql -u admin -p
4. Обновляйте и проверяйте сервер
Конфигурация безопасности не спасет необновленный сервер. Поддерживайте MySQL, клиентские библиотеки и операционную систему в актуальном состоянии через обычный процесс обновления пакетов или вендора.
После изменения my.cnf проверьте и перезапустите во время окна технического обслуживания:
mysqld --validate-config
sudo systemctl restart mysql
sudo systemctl status mysql
Имена пакетов и служб различаются в зависимости от дистрибутива. В некоторых системах используется mysqld вместо mysql.
5. Мониторинг доступа и проверка привилегий
Усиление не заканчивается после первого прохода. Регулярно проверяйте учетные записи и гранты, особенно после изменений в приложениях или смены персонала.
SELECT user, host, account_locked FROM mysql.user ORDER BY user, host;
SHOW GRANTS FOR 'my_app_user'@'localhost';
Следите за учетными записями, которые используют хосты %, широкие привилегии *.*, FILE, SUPER, SYSTEM_USER или WITH GRANT OPTION. Эти привилегии могут быть допустимы для небольшого числа административных учетных записей, но они никогда не должны появляться у обычных пользователей приложений.
Вывод
Усиливайте MySQL слоями. Начните с выделенных пользователей с минимальными привилегиями, ограничьте, откуда они могут подключаться, шифруйте трафик при пересечении сети, отключите рискованные функции, которые вы не используете, и поддерживайте сервер в обновленном состоянии. Затем запланируйте проверки привилегий, чтобы старый доступ незаметно не стал вашим следующим инцидентом.