- Home »

Как защитить базы данных MySQL и MariaDB на VPS с Linux
Если вы работаете с веб-приложениями или любыми проектами, которые требуют хранения данных, то вопрос безопасности баз данных стоит остро. MySQL и MariaDB — это те решения, которые крутятся практически везде, от небольших блогов до крупных корпоративных порталов. Но по умолчанию они настроены не самым безопасным образом, и если не принять соответствующие меры, можно получить серьезные проблемы — от утечки данных до полного компрометирования сервера.
В этой статье мы разберем, как правильно защитить MySQL и MariaDB на VPS с Linux. Рассмотрим базовые и продвинутые методы защиты, настройки файрвола, аудита, бэкапов и мониторинга. Все примеры будут с реальными командами и конфигурациями, которые можно сразу применять в продакшене.
Как работает безопасность баз данных
Прежде чем погружаться в настройки, важно понимать основные векторы атак на базы данных:
- Слабые пароли и учетные записи — самая частая причина взломов
- SQL-инъекции — атаки через веб-приложения
- Открытые порты — когда БД доступна извне без необходимости
- Отсутствие шифрования — данные передаются в открытом виде
- Логирование и мониторинг — никто не отслеживает подозрительную активность
- Старые версии ПО — неустраненные уязвимости
Базовая настройка безопасности
Начнем с основ. Если у вас еще нет VPS, можете заказать VPS здесь или взять выделенный сервер для более серьезных нагрузок.
Установка и первоначальная настройка
После установки MySQL/MariaDB первым делом запускаем скрипт безопасности:
sudo mysql_secure_installation
Этот скрипт поможет:
- Установить пароль для root
- Удалить анонимные учетные записи
- Запретить удаленный доступ для root
- Удалить тестовую базу данных
- Перезагрузить таблицы привилегий
Настройка конфигурационного файла
Редактируем основной конфиг (/etc/mysql/mysql.conf.d/mysqld.cnf
для MySQL или /etc/mysql/mariadb.conf.d/50-server.cnf
для MariaDB):
[mysqld]
# Привязка только к localhost
bind-address = 127.0.0.1
# Отключение загрузки локальных файлов
local-infile = 0
# Отключение символических ссылок
symbolic-links = 0
# Ограничение размера пакетов
max_allowed_packet = 16M
# Таймаут для неактивных соединений
wait_timeout = 600
interactive_timeout = 600
# Логирование медленных запросов
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# Общий лог запросов (осторожно, много места!)
# general_log = 1
# general_log_file = /var/log/mysql/general.log
После изменений перезапускаем службу:
sudo systemctl restart mysql
# или для MariaDB
sudo systemctl restart mariadb
Управление пользователями и привилегиями
Никогда не используйте root-пользователя для приложений. Создавайте отдельные учетные записи с минимальными правами:
# Входим в MySQL
sudo mysql -u root -p
# Создаем пользователя для приложения
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'SuperSecurePassword123!';
# Создаем базу данных
CREATE DATABASE myapp_db;
# Даем права только на нужную базу
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'appuser'@'localhost';
# Применяем изменения
FLUSH PRIVILEGES;
# Проверяем права
SHOW GRANTS FOR 'appuser'@'localhost';
Таблица рекомендуемых привилегий
Тип приложения | Рекомендуемые привилегии | Комментарий |
---|---|---|
Web-приложение | SELECT, INSERT, UPDATE, DELETE | Базовые операции CRUD |
Система отчетов | SELECT | Только чтение данных |
Миграции | CREATE, ALTER, DROP, INDEX | Структурные изменения |
Бэкапы | SELECT, LOCK TABLES | Для mysqldump |
Настройка файрвола
Если база данных используется только локально, блокируем внешние подключения:
# UFW (Ubuntu/Debian)
sudo ufw deny 3306
sudo ufw deny 3307
# Или для конкретного IP, если нужен удаленный доступ
sudo ufw allow from 192.168.1.100 to any port 3306
# iptables
sudo iptables -A INPUT -p tcp --dport 3306 -j DROP
sudo iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.100 -j ACCEPT
# Сохраняем правила
sudo iptables-save > /etc/iptables/rules.v4
Включение SSL/TLS шифрования
Для защиты данных в transit настраиваем SSL:
# Генерируем сертификаты
sudo mysql_ssl_rsa_setup --uid=mysql
# Проверяем поддержку SSL
mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"
Обязательное использование SSL для пользователей:
# Создаем пользователя с требованием SSL
CREATE USER 'secureuser'@'%' IDENTIFIED BY 'password' REQUIRE SSL;
# Или изменяем существующего
ALTER USER 'appuser'@'localhost' REQUIRE SSL;
Аудит и мониторинг
Включаем аудит для отслеживания подозрительной активности:
# Для MariaDB устанавливаем аудит-плагин
INSTALL PLUGIN server_audit SONAME 'server_audit.so';
# Настраиваем параметры аудита
SET GLOBAL server_audit_logging=ON;
SET GLOBAL server_audit_events='CONNECT,QUERY,TABLE';
SET GLOBAL server_audit_file_path='/var/log/mysql/audit.log';
Для MySQL Enterprise доступен MySQL Enterprise Audit, но для Community версии можно использовать McAfee MySQL Audit Plugin.
Настройка ротации логов
Создаем конфиг для logrotate (/etc/logrotate.d/mysql-audit
):
/var/log/mysql/audit.log {
daily
rotate 30
compress
missingok
notifempty
create 640 mysql mysql
postrotate
/bin/kill -HUP `cat /var/run/mysqld/mysqld.pid 2>/dev/null` 2>/dev/null || true
endscript
}
Бэкапы и восстановление
Автоматизируем создание бэкапов:
#!/bin/bash
# /opt/mysql-backup.sh
BACKUP_DIR="/backup/mysql"
DATE=$(date +"%Y%m%d_%H%M%S")
MYSQL_USER="backupuser"
MYSQL_PASS="BackupPassword123!"
DATABASES="myapp_db"
mkdir -p $BACKUP_DIR
for DB in $DATABASES; do
mysqldump -u$MYSQL_USER -p$MYSQL_PASS \
--single-transaction \
--routines \
--triggers \
--events \
$DB > $BACKUP_DIR/${DB}_${DATE}.sql
# Сжимаем бэкап
gzip $BACKUP_DIR/${DB}_${DATE}.sql
done
# Удаляем старые бэкапы (старше 7 дней)
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
Добавляем в cron:
# Ежедневный бэкап в 2:00
0 2 * * * /opt/mysql-backup.sh
Защита от SQL-инъекций на уровне БД
Помимо защиты в приложении, можно настроить дополнительную защиту в MySQL:
# Ограничиваем количество одновременных подключений
CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'password'
WITH MAX_CONNECTIONS_PER_HOUR 1000
MAX_QUERIES_PER_HOUR 10000
MAX_USER_CONNECTIONS 10;
# Включаем SQL_MODE для строгой проверки
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO';
Мониторинг производительности и безопасности
Создаем скрипт мониторинга:
#!/bin/bash
# /opt/mysql-monitor.sh
# Проверка подозрительных соединений
mysql -u root -p -e "SELECT USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND TIME > 60;"
# Проверка неудачных попыток входа
tail -n 100 /var/log/mysql/error.log | grep -i "access denied"
# Проверка медленных запросов
mysql -u root -p -e "SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;"
Дополнительные инструменты безопасности
Fail2ban для MySQL
Настраиваем защиту от брутфорса:
# /etc/fail2ban/jail.local
[mysqld-auth]
enabled = true
filter = mysqld-auth
port = 3306
logpath = /var/log/mysql/error.log
maxretry = 3
bantime = 3600
Создаем фильтр (/etc/fail2ban/filter.d/mysqld-auth.conf
):
[Definition]
failregex = ^%(__prefix_line)s.*\[ERROR\] Access denied for user.*.*$
ignoreregex =
Использование AppArmor/SELinux
Для Ubuntu/Debian с AppArmor:
# Проверяем статус профиля MySQL
sudo aa-status | grep mysql
# Переводим в режим enforce
sudo aa-enforce /etc/apparmor.d/usr.sbin.mysqld
Тестирование безопасности
Регулярно тестируем конфигурацию:
# Сканирование портов
nmap -p 3306 localhost
# Проверка SSL
mysql -u root -p -e "SHOW STATUS LIKE 'Ssl_cipher';"
# Тест подключения без SSL (должен быть запрещен)
mysql -u secureuser -p --ssl-mode=DISABLED
Сравнение инструментов безопасности
Инструмент | Функциональность | Сложность настройки | Производительность |
---|---|---|---|
MySQL Enterprise Audit | Полный аудит | Низкая | Высокая |
MariaDB Audit Plugin | Базовый аудит | Средняя | Высокая |
Fail2ban | Защита от брутфорса | Средняя | Минимальное влияние |
AppArmor/SELinux | Системная защита | Высокая | Минимальное влияние |
Автоматизация и скрипты
Создаем комплексный скрипт проверки безопасности:
#!/bin/bash
# /opt/mysql-security-check.sh
echo "=== MySQL Security Check ==="
# Проверка версии
mysql -V
# Проверка пользователей без пароля
mysql -u root -p -e "SELECT User, Host FROM mysql.user WHERE authentication_string = '';"
# Проверка пользователей с административными правами
mysql -u root -p -e "SELECT User, Host FROM mysql.user WHERE Super_priv = 'Y';"
# Проверка SSL
mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"
# Проверка логирования
mysql -u root -p -e "SHOW VARIABLES LIKE '%log%';"
# Проверка сетевых настроек
mysql -u root -p -e "SHOW VARIABLES LIKE 'bind_address';"
echo "=== Security Check Complete ==="
Интересные факты и нестандартные решения
Несколько полезных трюков для продвинутых пользователей:
- Honeypot-пользователи — создавайте пользователей-приманки для отслеживания атак
- Использование ProxySQL для дополнительной защиты и балансировки нагрузки
- Шифрование данных в покое — используйте InnoDB encryption для критичных данных
- Настройка MySQL в Docker с дополнительными мерами безопасности
Пример настройки InnoDB encryption
# В конфигурации MySQL
[mysqld]
default_table_encryption=ON
innodb_encrypt_tables=ON
innodb_encryption_threads=4
# Создание keyring
early-plugin-load=keyring_file.so
keyring_file_data=/var/lib/mysql-keyring/keyring
Заключение и рекомендации
Безопасность баз данных — это не разовая настройка, а постоянный процесс. Основные принципы, которые стоит соблюдать:
- Минимизация привилегий — давайте пользователям только те права, которые действительно нужны
- Регулярные обновления — следите за выходом патчей безопасности
- Мониторинг — настройте систему алертов для подозрительной активности
- Бэкапы — регулярно создавайте и проверяйте резервные копии
- Документирование — ведите документацию по всем изменениям
Помните, что безопасность — это баланс между защитой и удобством использования. Не стоит перегибать палку и усложнять систему до состояния, когда с ней невозможно работать. Начните с базовых настроек, описанных в этой статье, а затем постепенно добавляйте более сложные меры защиты по мере необходимости.
Для серьезных проектов рекомендую также рассмотреть возможность использования выделенных серверов вместо VPS — это даст дополнительный уровень изоляции и контроля над инфраструктурой.
Удачи в настройке безопасности ваших баз данных!
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.