Правильная установка покрывает большую часть чек-листа проверок, касающихся безопасности самого MySQL-сервера. Здесь будут приведены минимальные инструцкии по установке MySQL-сервера для некоторых операционных систем.
Следующие команды необходимо выполнить в консоли: Обновляем базу данных с доступными пакетами
sudo apt-get update
Устанавливаем mysql-server
sudo apt-get install mysql-server
Запускаем скрипт, конфигурирующий настройки безопасности, и пошагово делаем что от нас просят
sudo mysql_secure_installation
Вместе с mysql-server установится CLI, позволяющий манипулировать содержимым созданных дочерних баз данных и конфигурацией самого сервера. Запуск и вход осуществляются через консоль следующей командой
mysql -h %host% -u root -p
-
Флаг
-h
позволяет указать хост, на котором развернута база данных. Если база данных разернута локально, то данный флаг и аргумент после него можно опустить - по умолчанию подключение идет к localhost. -
Флаг
-u
позволяет указать пользователя, от имени которого будет вестись работа с базами данных.root
, к моменту после установки должен быть единственным доступным пользователем. -
При указанни флага
-p
после ввода команды будет запрошен пароль для указанного пользователя. Если пароль для пользователя не указан, то флаг можно опустить, но такого после выполнения скрипта настройки безопасности конфигурацииmysql_secure_installation
быть не должно.
Таким образом, на ненастроенном локальном MySQL-сервере будет достаточно ввести команду mysql
и будет произведен вход под root
-пользователем. Возсожно понадобится использовать sudo mysql
, поскольку даже при отсутствии пароля MySQL-сервер предоставляет некоторые гарантии безопасности.
Для обеспечения безопасности MySQL-сервера должно быть проверено выполнение следующих требований. Порядок проверки и действия на случай невыполнения требований приведены в инструкции.
Первостепенные проверки:
- Проверить наличие пароля у
root
и других пользователей; - Проверить чтобы
root
и другие пользователи аутентифицировались с SSL; - Проверить наличие доступа к таблице
user
только уroot
пользователя; - Проверить наличие у каждой учетной записи на сервере наличие только необходимых для нее глобальных привелегий;
- Убедиться в отсутствии анонимных пользователей;
- Убедиться в наличии брендмауэра;
- Проверить доступность MySQL-сервера только из необходимых узлов сети (для установки на удаленном сервере);
- Убедиться в том, что вход включен только для локальных пользователей (для локального использования);
- Проверить чтобы разрешения для работы с любыми MySQL-файлами были только у системного
root
-пользователя и пользователя, от которого запускаетсяmysqld
; - Проверить чтобы
mysqld
запускался на отдельном системном пользователе безroot
-привелегий; - Убедиться, что
mysqld
запускается с необходимыми флагами; - Проверить, что установлены только необходимые, невредоносные, плагины.
Дополнительные проверки:
- Убедиться в отсутствии базы данных
test
; - Убедиться в том, что не ведется файл
.mysql_history
, а если ведется, то к нему есть доступ только у системногоroot
-пользователя; - Убедиться в том, что
root
пользователя нет и аккаунт для администрирования находится под другим именем; - Убедиться в том, что был изменен порт, на котором работает MySQL-сервер;
- Ознакомиться с уязвимостями текущей версии MySQL-сервера.
Прочие рекомендации (в основном для самих пользователей MySQL):
- Убедиться в том, что нигде в базах данных пользовательские пароли не хранятся в открытом виде;
- Убедиться в том, что сервисы, использующие MySQL не предают пароль в самой команде (флаг
-p%password%
); - Убедиться в том, что пользовательский ввод всегда проверяется и исключены возможности SQL-инъекций;
Перед выполнением данных проверок необходимо войти под пользователем-администратором (по умолчанию root
) в mysql CLI при помощи команды mysql -u root -p
. В случае если понадобится системная консоль это будет явно указано. Пред внесением изменений в конфигурационные файлы рекомендуется выключить MySQL-сервер и сключить его заново, когда изменения будут совершены. Другой опцией является перезапуск MySQL-сервера (команда выполняется в системной консоли):
service mysqld restart
Выполнить команду:
select host, user, authentication_string from mysql.user;
Если в одной из строк ячейка authentication_string
пустая - соответствующему пользователю необходимо установить пароль.
Установить пароль для пользователя можно при помощи команд:
alter user 'username'@'localhost' IDENTIFIED BY 'password';
flush priveleges;
Выполнить команду:
select host, user, ssl_type from mysql.user;
Если в одной из строк ячейка ssl_type
пустая - соответствующему пользователю необходимо установить аутентификацию с SSL:
alter user 'user'@'localhost' require ssl;
Так же необходимо проверить чтобы SSL использовался по умолчанию для всех соединений с MySQL сервером. Для этого необходимо проверить наличие следующих строк в конфигурационном файле MySQL (найти расположения конфигурационных файлов можно выполнив команду mysql --help --verbose | grep .cnf
)
[mysql]
ssl_ca=ca.pem
ssl_cert=server-cert.pem
ssl_key=server-key.pem
require_secure_transport=ON
Первые три строки указывают на существующий сертификат, расположенный в /var/lib/mysql
.
В случае если готового сертификата нет, в новых версиях mysql-server можно указать опцию, при наличии которой сертификаты будут сгенерированы при запуске mysql-сервера.
[mysql]
auto_generate_certs=ON
Стоит отметить, что такие сертификаты будут самоподписанными, что не очень безопасно само по себе, поэтому рекомендуется использовать готовые сертификаты.
Выполнить команды:
select Table_priv, Column_priv, user, Db, Table_name from mysql.tables_priv where Db='mysql' and Table_name='user';
select Host, Db, User, Column_name, Column_priv from mysql.columns_priv where Table_name='user' and Db='mysql';
Если присутсвуют строки у которых в user не mysql.session
- привелегии соответствующих пользователей необходимо отозвать.
Сделать это можно при помощи следующей команды:
revoke privilege1, privilege2, ... on 'dbname'.'tablename' from 'user1'@'host1', 'user2'@'host2', ...;
Проверить наличие у каждой учетной записи на сервере наличие только необходимых для нее глобальных привелегий
Выполнить команду:
select host, user, process_priv, shutdown_priv, file_priv, super_priv, create_user_priv, show_db_priv, grant_priv from mysql.user;
Если в соответствующих ячейках не системных mysql пользователей (mysql.session. mysql.sys и некоторые другие, зависимые от платформы) присутствуют Y
- необходимо отозвать привелегии. Данная рекомендация применима только к статическим привелегиям MySQL. Привилегии можно отозвать при помощи следующей команды:
revoke privilege1, privilege2, ... on 'dbname'.'tablename' from 'user1'@'host1', 'user2'@'host2', ...;
В данном случае приведены только привелегии, относящиеся к администрированию mysql-server. Другие привелегии (select, update, insert, drop и так далее) можно отобразить добавив названия соответствующих колоник в mysql-команду. С названиями всех доступных привелегий и соответствующих колонок можно ознакомиться здесь.
Выполнить команду:
select user from mysql.user where user='';
Пользователей, выведенных после выполнения данной команды необходимо удалить или изменить. Удаление можно произвести при помощи следующей команды:
drop user 'username'@'host';
Изменение пользователя:
rename user 'old_username'@'host' to 'new_username'@'host';
В терминале системы (применимо только к Linux. Для Windows необходимо ознакомиться с документацией для Windows Firewall) выполнить:
systemctl list-units --type=service --state=active | grep 'firewalld\|ufw\|iptables\|shorewall'
Данная команда выведет состояние соответсвующего firewall-сервиса, если он зарегистрирован в системе. Важно помнить, что сервис может быть зарегистрирован, но отключен. Для выяснения текущего состояния используемого firewall-сервиса необходимо ознакомиться с соответствующей документацей. Кроме того, данная команда не покрывает все возможные firewall-решения, возможно наличие других, более специфичных сервисов. В случае отсутствия брендмауэра следует ознакомиться с соответствующей документацией по его уставновке.
Проверить доступность MySQL-сервера только из необходимых узлов сети (для установки на удаленном сервере)
Доступность сервера определяется настройками брендмауэра. Для проверки доступности из текущего узла в его консоли необходимо выполнить команду (предварительно заменив строки между %% соответствующими данными):
telnet %mysql_server_host% %mysql_server_port%
В случае если доступ есть -команда выполнится и будут выведены некоторые символы. В противном случае будет выведено сообщение о том, что соединение не может быть установлено или выполнение команды и вовсе не прекратится.
По умолчанию MySQL-сервер принимает соединения только в локальной сети. Для проверки текущего режима работы необходимо найти расположение конфигурационного файла MySQL my.cnf
для используемой системы и открыть его пользователем с соответствующими правами. В файле необходимо найти строки (в их отсутствии предполагается, что сервер работает в локальном режиме):
bind-address
skip-networking
Опция bind-address
указывает на тот ip-adress, соединения на котором будет обрабатывать MySQL-сервер. Если поставить перед этой строкой символ #
, то будут приниматься соединения только в локальной сети. При указании skip-networking=1
можно добиться аналогичного эффекта.
Проверить чтобы разрешения для работы с любыми MySQL-файлами были только у системного root
-пользователя и пользователя, от которого запускается mysqld
Расположении директории с данными можно выяснить выполнив следующую команду в MySQL CLI:
show variables where variable_name = 'datadir';
Для linux-систем ознакомиться с правами доступа для текущего пользователя можно выполнив команду ls -lah
в соответствующей директории. Убедиться что права на чтение и запись есть у отдельной группы mysql (в которую должен входить root-пользователь и пользователь, от которого запускается mysqld
) и ни у кого больше.
Всех пользователей группы mysql
при ее наличии можно получить выполнив команду в системной консоли (для Linux-систем):
grep 'mysql' /etc/group
В отсутсвии группы необходимо ее создать и сконфигурировать запуск mysqld
соответствующим образом.
Открыть конфигурационный файл и найти в нем строки:
[mysqld]
user=%user%
При отсутствии данных строк предполагается, что mysqld
запускается от root
-пользователя.
Нового пользователя можно создать при помощи следущих команд:
sudo useradd user;
sudo passwd user;
Так же его необходимо добавить в группу mysql
:
sudo usermod -a -G mysql user
В более новых версиях mysql-server создается польователь mysql
, от которого запускается mysqld
. Проверить это можно, например, при помощи утилиты htop. Следуеь запустить ее введя название утилиты в консоль и отфильтровать показанные процессы по строке mysql. В колонке пользователя можно будет наблюдать создателя процесса. Если там показан пользователь mysql
- сервер самостоятельно сконифгурировал запуск на нем. Проверить отсутствие root-прав у этого пользователя можно введя команду:
sudo grep root /etc/group
Если в показаном списке нет пользователя mysql
- у него нет соответствующих прав.
Выполнить команду в системной консоли:
mysqld --verbose --help
В результате ее выполнения будет выведен список системных переменных mysql с учетом всех использованных конфигуарционных файлов. Искать по выводу команды можно при помощи утилиты grep
:
mysqld --verbose --help | grep chroot
Проверить установку следующих значений:
Включает выполнение команд LOAD DATA
, модифицирующих локальные данные. По умолчанию опция отключена.
local-infile FALSE
Исключает возможность модифицирования таблицы mysql.user
пользователями без соответствующих привелегий. По умолчанию опция не используется.
safe-user-create TRUE
Ограничивает выполнение команд, работающих с файлами. При установке в NULL
команды не могут быть использованы. По усмолчанию опция не используется.
secure-file-priv NULL
При ON
выключает механизм контроля доступа. По умолчанию OFF
.
skip-grant-tables FALSE
Контролирует возможность выполнять команду SHOW DATABASES
. По умолчанию OFF
.
skip-show-database=ON
Установить указнные значения можно при помощи изменения файла конфигурации mysql-server. В нем следует написать:
[mysqld]
local_infile=OFF
safe_user_create=ON
secure_file_priv=NULL
skip_grant_tables=OFF
skip-show-database=ON
Выполнить команду:
show plugins;
Проверить список выведенных плагинов. Предположительно вредоносные отключить при помощи:
mysql_plugin %malicious_plugin% DISABLE;
Выполнить команду, предварительно убедившись (например, запустив describe test;
), что под данным именем действительно тестовая база данных MySQL:
drop database if exists test;
В случае если базы данных не было будет выведена ошибка. В противном случае база данных удалится.
Убедиться в том, что не ведется файл .mysql_history
, а если ведется, то к нему есть доступ только у системного root
-пользователя
В логах MySQL может храниться чувствительная информация. Чтобы проверить права доступа к лог-файлу MySQL необходимо выполнить следующую команду:
ls -l ~/.mysql_history
Убедиться, что к к этому файлу нет доступа ни у кого кроме root
. В случае отсутствия файла будет выведена ошибка (данная ситуация возможно, если вывод MySQL был ранее перенаправлен из данного файла в NULL)
Убедиться в том, что root
пользователя нет и аккаунт для администрирования находится под другим именем;
Выполнить команду:
select user, host from mysql.user;
Убедиться в отсутствии пользователя root
. В противном случае изменить имя пользователю root
при помощи команды alter user
.
Выполнить команду в системной консоли:
nmap localhost | grep 3306
Если строка с 3306 была выведена - на MySQL-сервер скорее всего использует именно этот порт для своей работы. Для изменения порта необходимо поменять соответствующую строку в конфигурационном файле MySQL, заменив %new_port%
на новое значение порта:
port=%new_port%