From: http://SecurityLab.ru
Date: Mon, 22 Mar 2004 14:31:37 +0000 (UTC)
Subject: Увеличение безопасности MySql шаг за шагом
Оригинал: http://www.securitylab.ru/?ID=39981
Защищаем MySql. Шаг за шагом
1. Введение
MySQL является одной из наиболее популярных баз данных в Internet, и
часто используется вместе с PHP. Помимо её бесспорных преимуществ,
таких как простота использования и относительно высокая эффективность,
MySQL предлагает простые, но в то же время очень эффективные механизмы
защиты. К сожалению, заданная по умолчанию инсталляция MySQL, а в
особенности пустой пароль по умолчанию и потенциальная уязвимость к
атакам переполнения буфера, делают базу данных MySQL простым объектом
для нападений.
Эта статья описывает основные шаги, выполнение которых, максимально
защитит базу данных MySQL от локальных и удаленных нападений. Это
третья и последняя статья из цикла статей, посвященных защите Apache,
PHP и MySQL.
1.1 Функциональные возможности
В этой статье мы предполагаем, что Web-сервер Apache вместе с PHP
модулем, был установлен в соответствии с требованиями предыдущих
статей, и помещен в каталог /chroot/httpd.
Кроме этого мы также принимаем следующее:
* База данных MySQL будет использоваться только PHP приложениями,
установленными на том же самом хосте;
* Для управления базой данных будут использоваться стандартные
административные средства, типа mysqladmin, mysql, mysqldump и
т.д.;
* Для удаленного резервирования MySQL данных будет использоваться
SSH протокол.
1.2 Необходимые условия для защиты
Чтобы достигнуть самого высокого возможного уровня защиты, установка и
конфигурация mysql должна быть выполнена в соответствии со следующими
требованиями:
* база данных mysql должна быть выполнена в chrooted среде;
* процессы mysql должны выполняться под уникальным UID/GID,
неиспользуемым никаким другим системным процессом;
* Должен быть разрешен только локальный доступ к mysql;
* Основная учетная запись mysql должна быть защищена "сложным"
паролем;
* Будет переименована учетная запись администратора;
* Должен быть заблокирован анонимный доступ к базе данных (используя
учетную запись nobody);
* Должны быть удалены все типовые базы данных и таблицы.
2. Установка MySQL
Прежде чем начать осуществление защиты MySQL, мы должны установить
программное обеспечение на сервере. Как мы писали в предыдущих
статьях, мы запустим инсталляцию, создав уникальную, постоянную группу
и учетную запись пользователя на операционной системе, которая будет
посвящена базе данных MySQL:
pw groupadd mysql
pw useradd mysql-c " mysql Сервер "-d/dev/null-g mysql-s/sbin/nologin
2.1 Компиляция mysql
Мы скомпилируем и установим mysql в каталог /usr/local/mysql:
./configure --prefix=/usr/local/mysql --with-mysqld-user=mysql
--with-unix-socket-path=/tmp/mysql.sock
--with-mysqld-ldflags=-all-static
make
su
make install
strip /usr/local/mysql/libexec/mysqld
scripts/mysql_install_db
chown -R root /usr/local/mysql
chown -R mysql /usr/local/mysql/var
chgrp -R mysql /usr/local/mysql
Приведенный процесс установки сервера практически идентичен описанному
в руководстве к mysql. Единственным отличием является использование
нескольких дополнительных параметров, указанных в строке: ./configure.
Наиболее важным отличием является использование параметра --
with-mysqld-ldflags =-all-static, который делает MySQL сервер
статически связанным. Это значительно упрощает процесс chrooting
сервера, как описано в Разделе 3. Остальные параметры приказывают make
программе установить программное обеспечение в каталог
/usr/local/mysql, выполнить MySQL демон с привилегиями учетной записи
mysql, и создать сокет mysql.sock в каталоге /tmp.
2.2 Копирование файлов конфигурации
После выполнения вышеупомянутых команд, мы должны скопировать заданный
по умолчанию файл конфигурации в соответствии с ожидаемым размером
базы данных (маленькая, средняя, большая, огромная). Например:
Теперь mysql полностью установлен и готов к выполнению. Мы можем
запустить mysql сервер, выполнив следующую команду:
/usr/local/mysql/bin/mysqld_safe
2.4 Проверка подключений
Попробуйте установить связь с базой данных следующим образом:
/usr/local/mysql/bin/mysql -u root mysql
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 2 to server version: 4.0.13-log
Type 'help;' or 'h' for help. Type 'c' to clear the buffer.
mysql> show databases;
+----------+
| Database |
+----------+
| mysql |
| test |
+----------+
2 rows in set (0.00 sec)
mysql> quit;
Как только подключение успешно установлено, мы можем остановить работу
базы данных:
/usr/local/mysql/bin/mysqladmin -u root shutdown
и начать защиту программного обеспечения. Иначе, мы должны будем
проанализировать информацию, сохраненную в файле регистрации
/usr/local/mysql/var/`hostname`.err, и устранить причину проблемы.
3. Chrooting сервер
Первый шаг защиты mysql должен подготовить chrooted среду, в которой
будет выполняться mysql сервер. Chrooting методика была подробно
описана в первой статье этого цикла ("Защита Apache: Шаг за шагом
(http://www.securitylab.ru/?ID=38966), поэтому если Вы не знакомы
с этой методикой или не знаете почему рекомендуется chrooting,
пожалуйста прочтите эту статью.
3.1 Операционная система
Как и в предыдущих статьях, мы будем основываться на операционной
системе FreeBSD 4.7. Однако представленные методы должны также
применяться и на более современных unix и unix-подобных системах.
3.2 Подготовка chroot среды
Чтобы подготовить chrooted среду, мы должны создать следующую
структуру каталога:
Из файлов: /chroot/mysql/etc/passwords и /chroot/mysql/etc/group мы
должны удалить все строки кроме учетной записи mysql и группы. Затем,
мы должны, создать базу данных паролей (допустимо только в FreeBSD):
cd /chroot/mysql/etc
pwd_mkdb -d /chroot/mysql/etc passwords
rm -rf /chroot/mysql/etc/master.passwd
3.6 Специальные соображения
Как и в случае с Web-сервером Apache, мы должны создать специальный
файл устройства /dev/null:
ls -al /dev/null
crw-rw-rw- 1 root sys 2, 2 Jun 21 18:31 /dev/null
mknod /chroot/mysql/dev/null c 2 2
chown root:sys /chroot/mysql/dev/null
chmod 666 /chroot/mysql/dev/null
Теперь необходимо скопировать базу данных mysql, которая содержит
таблицы, созданные в процессе инсталляции mysql:
Если будет использоваться какой-либо язык кроме английского, то
необходимо будет скопировать нужный набор символов из каталога
/usr/local/mysql/share/mysql/charsets.
3.8 Проверка конфигурации
Теперь MySQL готов к запуску в chrooted среде. Мы можем проверить,
правильно ли запускается MySql, выполнив следующую команду:
chrootuid /chroot/mysql mysql /usr/local/mysql/libexec/mysqld &
Если произойдет какая-либо ошибка, то необходимо будет использовать
команду truss или подобную ей, типа ktrace/kdump, strace, и т.д. Это
поможет нам определить и устранить причину проблемы.
Заметьте, что для выполнения процесса mysqld, вместо chroot, как в
случае Apache или PHP, использовалась программа chrootuid. Главное
отличие состоит в том, что chrootuid меняет владельца запущенного
процесса. В нашем примере, mysqld выполняется в chrooted среде, но
владелец процесса - не root, а пользователь mysql. Chrootuid во многих
операционных системах не установлен по умолчанию, поэтому необходимо
загрузить и установить эту программу вручную. Программа Chrootuid
может быть загружена [14]здесь .
4. Конфигурирование сервера
Следующий шаг должен сконфигурировать сервер базы данных в
соответствии с нашими требованиями по защите.
В случае заданной по умолчанию инсталляции mysql, главным файлом
конфигурации является /etc/my.cnf. Однако, в нашем случае, из-за
выполнения сервера в chrooted среде, мы будем использовать два файла
конфигурации: /chroot/mysql/etc/my.cnf и /etc/my.cnf. Первый будет
использоваться сервером mysql, а второй - утилитами mysql (например:
mysqladmin, mysql, mysqldump и т.д.). В обоих случаях, потребуются
некоторые изменения конфигурации.
4.1 Отключение удаленного доступа
Первое изменение касается порта 3306/tcp, который mysql прослушивает
по умолчанию. Поскольку, согласно начальным предположениям по защите,
база данных будет использоваться только локально установленными PHP
приложениями, мы можем свободно отключить прослушивание этого порта.
Это ограничит возможность нападения на базу данных mysql прямыми
TCP/IP подключениями с других хостов. Чтобы отключить прослушивание
упомянутого порта, необходимо к разделу [mysqld] файла
/chroot/mysql/etc/my.cnf добавить следующий параметр:
skip-networking
Если, по некоторым причинам, все же требуется удаленный доступ к базе
данных (например, чтобы выполнить удаленное резервирование данных), то
можно использовать SSH протокол, как показано ниже:
backuphost$ ssh mysqlserver /usr/local/mysql/bin/mysqldump -A > backup
4.2 Улучшение локальной защиты
Следующее изменение должно отключить использование команды LOAD DATA
LOCAL INFILE, что поможет предотвратить несанкционированное чтение
данных из локальных файлов. Это имеет особенное значение, в случае
если в PHP будет найдена новая уязвимость к SQL инъекциям.
Для этой цели, в раздел [mysqld] файла /chroot/mysql/etc/my.cnf,
необходимо добавить следующий параметр:
Set-variable=local-infile=0
Кроме того, чтобы сделать более удобным использование административных
средств базы данных, в разделе [Client] файла /etc/my.cnf, должен быть
изменен следующий параметр:
socket = /chroot/mysql/tmp/mysql.sock
Благодаря этому, каждый раз при выполнении этих утилит, не будет
никакой потребности передавать в команды: mysql, mysqladmin, mysqldump
и т.д., параметр socket =/chroot/mysql/tmp/mysql.sock.
4.3 Изменение пароля администратора
Одним из наиболее важных шагов в защите MySQL, является изменение
пароля администратора базы данных, который является по умолчанию
пустым. Чтобы сделать это, мы должны запустить MySQL (если конечно, он
уже не запущен):
chrootuid /chroot/mysql mysql /usr/local/mysql/libexec/mysqld &
и изменить пароль администратора следующим образом:
/usr/local/mysql/bin/mysql -u root
mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password');
Хорошей привычкой является отказ от изменений паролей из командной
строки, например, используя команду "mysqladmin password". Это
особенно важно, если на сервере работают несколько пользователей. В
таком случае пароль можно легко узнать, например, используя команду
"ps aux" или просмотрев файлы истории команд (~/.history,
~/.bash_history и т.д), в случае если на них установлены неподходящие
права доступа.
4.4 Удаление значений по умолчанию users/db
Затем, мы должны удалить типовую базу данных (test) и все учетные
записи, кроме главной локальной учетной записи:
mysql> drop database test;
mysql> use mysql;
mysql> delete from db;
mysql> delete from user where not (host="localhost" and user="root");
mysql> flush privileges;
Это предотвратит нашу базу данных от установления анонимных
подключений, а также, независимо от параметра skip-networking в файле
/chroot/mysql/etc/my.cnf --, удаленных подключений.
4.5 Изменение имени учетной записи администратора.
Также рекомендуется изменить заданное по умолчанию имя учетной записи
администратора (root), на любое более сложное значение. Такая замена
затруднит выполнение "лобовых" и "словарных" атак на пароль
администратора. В этом случае, вторгшийся должен будет предположить не
только пароль, но и, прежде всего, имя учетной записи администратора.
mysql> update user set user="mydbadmin" where user="root";
mysql> flush privileges;
4.6 Удаление файлов истории команд
Наконец, мы должны удалить содержимое файла истории команд mysql
(~/.mysql_history), в котором сохраняются все выполненные SQL команды
(особенно пароли, сохраненные как открытый текст):
5. Связь между PHP и mysql
В предыдущей статье "Защищаем PHP: Шаг за шагом"
(http://www.securitylab.ru/?ID=39645), автор упомянул о проблеме
связи между PHP и mysql, в случае, если одна из этих программ
выполняется в chrooted среде. Поскольку локально PHP связывается с
mysql, используя сокет /tmp/mysql.sock, размещение PHP в chrooted
среде, означает, что они не могут связываться друг с другом. Для
решения этой проблемы, каждый раз, запуская mysql, мы должны
создавать постоянную связь с PHP chrooted средой:
Обратите внимание на то, что сокет /chroot/mysql/tmp/mysql.sock и
каталог /chroot/httpd/tmp должны быть физически помещены в том же
самой файловой системе. Иначе программы не смогут связываться друг с
другом, т.к. постоянные связи не работают между различными файловыми
системами.
6. Финальные шаги
Теперь мы уже можем создавать все базы данных и учетные записи,
которые будут использоваться определенными PHP приложениями.
Необходимо подчеркнуть, что эти учетные записи должны иметь права
доступа только к базам данных, используемым PHP приложениями. В
частности они не должны иметь никаких прав доступа к базе данных
mysql, и ни никаким системным или административным привилегиям (FILE,
GRANT, ALTER, SHOW DATABASE, RELOAD, SHUTDOWN, PROCESS, SUPER и т.д.).
Наконец, необходимо создать основной сценарий, который будет
использоваться для запуска mysql во время загрузки операционной
системы. Пример такого сценария показан ниже,:
В случае с нашей системой FreeBSD, вышеупомянутый сценарий должен быть
помещен в каталог /usr/local/etc/rc.d, под именем mysql.sh.
6.1 Заключение
Применение методов, описанных в данной статье, позволит нам
значительно увеличить степень защиты mysql. Запуская базу данных в
chrooted среде, отключая прослушивание 3306/tcp порта, и применяя
"строгие" пароли к учетным записям пользователей, мы можем сделать
базу данных неуязвимой ко многим видам нападений, которые были бы
возможны с заданной по умолчанию инсталляцией.
Хотя никакой метод не позволит нам достигнуть 100% защиты, но
применение, описанных данной статье методов, по крайней мере,
ограничит возможность нападения пользователей, посещающих наши
Web-сервера с недобросовестными намерениями.
384 Прочтений • [Увеличение безопасности MySql шаг за шагом (mysql security chroot)] [08.05.2012] [Комментариев: 0]