Skip to content

Instantly share code, notes, and snippets.

@mocurin
Last active December 29, 2021 17:06
Show Gist options
  • Save mocurin/f8ecca9fd7b60f204c1f12afb53dac82 to your computer and use it in GitHub Desktop.
Save mocurin/f8ecca9fd7b60f204c1f12afb53dac82 to your computer and use it in GitHub Desktop.
Инструкция по проверке безопасности конфигурации реляционной СУБД MySQL. Алексеев Антон, ИУ8-71. Вариант №5.

Инструкция по проверке безопасности конфигурации реляционной СУБД MySQL

Установка MySQL

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

Linux

Следующие команды необходимо выполнить в консоли: Обновляем базу данных с доступными пакетами

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-сервера

Для обеспечения безопасности 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-инъекций;

Инструкции по проверке безопасности MySQL-сервера

Перед выполнением данных проверок необходимо войти под пользователем-администратором (по умолчанию root) в mysql CLI при помощи команды mysql -u root -p. В случае если понадобится системная консоль это будет явно указано. Пред внесением изменений в конфигурационные файлы рекомендуется выключить MySQL-сервер и сключить его заново, когда изменения будут совершены. Другой опцией является перезапуск MySQL-сервера (команда выполняется в системной консоли):

service mysqld restart
Проверить наличие пароля у root и других пользователей

Выполнить команду:

select host, user, authentication_string from mysql.user;

Если в одной из строк ячейка authentication_string пустая - соответствующему пользователю необходимо установить пароль.

Установить пароль для пользователя можно при помощи команд:

alter user 'username'@'localhost' IDENTIFIED BY 'password';
flush priveleges;
Проверить чтобы root и другие пользователи аутентифицировались с SSL

Выполнить команду:

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

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

Проверить наличие доступа к таблице user только у root пользователя

Выполнить команды:

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 запускался на отдельном системном пользователе без root-привелегий

Открыть конфигурационный файл и найти в нем строки:

[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 запускается с необходимыми флагами

Выполнить команду в системной консоли:

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;
Убедиться в отсутствии базы данных test

Выполнить команду, предварительно убедившись (например, запустив 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.

Убедиться в том, что был изменен порт, на котором работает MySQL-сервер

Выполнить команду в системной консоли:

nmap localhost | grep 3306

Если строка с 3306 была выведена - на MySQL-сервер скорее всего использует именно этот порт для своей работы. Для изменения порта необходимо поменять соответствующую строку в конфигурационном файле MySQL, заменив %new_port% на новое значение порта:

port=%new_port%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment