Защита Mysql - Создание сервера - Форумы Lineage II - L2Best.net \ Форумы Lineage 2, lineage2 база знаний
Gracia Final
  Главная Форум Регистрация Контакты Правила RSS 2.0
   
Вы вошли как Гость | Группа "Гости"Приветствую Вас Гость | RSS На сайт | Регистрация | Выход
Среда, 17.03.2010, 08:48
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 11
L2Best.net » Форумы Lineage II » Создание сервера » Защита Mysql (Большая статья о защите баз данных)
Защита Mysql
pk Дата: Воскресенье, 01.02.2009, 22:56 | Сообщение # 1
JIEC TAM===>
Группа: Наблюдатели
Сообщений: 48
Статус: Offline

За 25 Сообщений
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 Копирование файлов конфигурации

После выполнения вышеупомянутых команд, мы должны скопировать заданный по умолчанию файл конфигурации в соответствии с ожидаемым размером базы данных (маленькая, средняя, большая, огромная). Например:

cp support-files/my-medium.cnf /etc/my.cnf
chown root:sys /etc/my.cnf
chmod 644 /etc/my.cnf

2.3 Запуск сервера

Теперь 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: Шаг за шагом, поэтому если Вы не знакомы с этой методикой или не знаете почему рекомендуется chrooting, пожалуйста прочтите эту статью.

3.1 Операционная система

Как и в предыдущих статьях, мы будем основываться на операционной системе FreeBSD 4.7. Однако представленные методы должны также применяться и на более современных unix и unix-подобных системах.

3.2 Подготовка chroot среды

Чтобы подготовить chrooted среду, мы должны создать следующую структуру каталога:

mkdir -p /chroot/mysql/dev
mkdir -p /chroot/mysql/etc
mkdir -p /chroot/mysql/tmp
mkdir -p /chroot/mysql/var/tmp
mkdir -p /chroot/mysql/usr/local/mysql/libexec
mkdir -p /chroot/mysql/usr/local/mysql/share/mysql/english

3.3 Установка прав доступа

Права доступа к вышеупомянутым каталогам должны быть установлены следующим образом:

chown -R root:sys /chroot/mysql
chmod -R 755 /chroot/mysql
chmod 1777 /chroot/mysql/tmp

3.4 Создание структуры каталогов

Затем, необходимо скопировать следующие файлы в новую структуру каталога:

cp/usr/local/mysql/libexec/mysqld/chroot/mysql/usr/local/mysql/libexec/

cp/usr/local/mysql/share/mysql/english/er rmsg.sys/chroot/mysql/usr/local/mysql/share/mys ql/english/

cp/etc/hosts/chroot/mysql/etc/

cp/etc/host.conf/chroot/mysql/etc/

cp/etc/resolv.conf/chroot/mysql/etc/

cp/etc/group/chroot/mysql/etc/

cp/etc/master.passwd/chroot/mysql/etc/passwords

cp/etc/my.cnf/chroot/mysql/etc/

3.5 Сжатие паролей и групп

Из файлов: /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:

cp-R/usr/local/mysql/var//chroot/mysql/usr/local/mysql/var

chown-R mysql:mysql/chroot/mysql/usr/local/mysql/var

3.7 Локализация

Если будет использоваться какой-либо язык кроме английского, то необходимо будет скопировать нужный набор символов из каталога /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 может быть загружена здесь .

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: Шаг за шагом", автор упомянул о проблеме связи между PHP и mysql, в случае, если одна из этих программ выполняется в chrooted среде. Поскольку локально PHP связывается с mysql, используя сокет /tmp/mysql.sock, размещение PHP в chrooted среде, означает, что они не могут связываться друг с другом. Для решения этой проблемы, каждый раз, запуская mysql, мы должны создавать постоянную связь с PHP chrooted средой:

ln /chroot/mysql/tmp/mysql.sock /chroot/httpd/tmp/

Обратите внимание на то, что сокет /chroot/mysql/tmp/mysql.sock и каталог /chroot/httpd/tmp должны быть физически помещены в том же самой файловой системе. Иначе программы не смогут связываться друг с другом, т.к. постоянные связи не работают между различными файловыми системами.

6. Финальные шаги

Теперь мы уже можем создавать все базы данных и учетные записи, которые будут использоваться определенными PHP приложениями. Необходимо подчеркнуть, что эти учетные записи должны иметь права доступа только к базам данных, используемым PHP приложениями. В частности они не должны иметь никаких прав доступа к базе данных mysql, и ни никаким системным или административным привилегиям (FILE, GRANT, ALTER, SHOW DATABASE, RELOAD, SHUTDOWN, PROCESS, SUPER и т.д.).

Наконец, необходимо создать основной сценарий, который будет использоваться для запуска mysql во время загрузки операционной системы. Пример такого сценария показан ниже,:
#!/bin/sh
CHROOT_MYSQL=/chroot/mysql
CHROOT_PHP=/chroot/httpd
SOCKET=/tmp/mysql.sock
MYSQLD=/usr/local/mysql/libexec/mysqld
PIDFILE=/usr/local/mysql/var/`hostname`.pid
CHROOTUID=/usr/local/sbin/chrootuid
echo -n " mysql"
case "$1" in
start)
rm -rf ${CHROOT_PHP}/${SOCKET}
nohup ${CHROOTUID} ${CHROOT_MYSQL} mysql ${MYSQLD} >/dev/null 2>&1 &
sleep 5 && ln ${CHROOT_MYSQL}/${SOCKET} ${CHROOT_PHP}/${SOCKET}
;;
stop)
kill `cat ${CHROOT_MYSQL}/${PIDFILE}`
rm -rf ${CHROOT_MYSQL}/${SOCKET}
;;
*)
echo ""
echo "Usage: `basename $0` {start|stop}" >&2
exit 64
;;
esac
exit 0

В случае с нашей системой FreeBSD, вышеупомянутый сценарий должен быть помещен в каталог /usr/local/etc/rc.d, под именем mysql.sh.

Когда mysql запущен, постарайтесь следовать этим рекомендациям:

Никому не давайте доступ (кроме администратора mysql) к таблице user в базе данных mysql. Зашифрованный пароль - реальный пароль в mysql. Если Вы знаете пароль, перечисленный в таблице user для данного пользователя, вы можете легко войти как этот пользователь, если у вас есть доступ к компьютеру, перечисленному для этой учетной записи.

Изучите систему привилегии доступа mysql. Команды grant и revoke используются для управления доступом к mysql. Не предоставляйте больших привилегий, чем это необходимо. Никогда не предоставляйте привилегии всем компьютерам в сети. Команды контрольных проверок:

1. Пробуйте mysql -u root. Если вы сможете соединиться с сервером без запроса пароля, значит у вас проблемы. Любой сможет соединиться с вашим mysql сервером как mysql root пользователь с полными привилегиями. Тщательно читайте команды инсталляции mysql, обращая внимание на опции установки пароля.

2. Используйте команды show grants и check, чтобы видеть, кто имеет доступ к какой. Удалите лишние привилегии, используя команду revoke.

Не храните пароли в виде открытого текста в вашей базе данных. Когда ваш компьютер взломан, вторгшийся может получить полный список

паролей и использовать их. Вместо этого используйте md5 алгоритм или любой другой на основе односторонней хеш-функции.

Не выбирайте пароли из словарей. Имеются специальные программы, чтобы подбирать их. Даже пароли подобно " xfish98 " являются очень плохими. Намного лучше - " "duag98", который содержит то же самое слово " рыба " но напечатанное на одну клавишу влево на клавиатуре. Другой метод состоит в том, чтобы использовать пароли типа "УМББР", который состоит из первых слов в предложении " У Мэри был большой ребенок". Такие пароли просто запомнить и напечатать, но трудно подобрать злоумышленнику.

Используйте firewall. Он защитит вас, по крайней мере, от 50% эксплуатирующихся уязвимостей в любом программном обеспечении. mysql использует 3306 порт по умолчанию. Этот порт должен быть доступен только от доверенных компьютеров. Самый простой способ проверить, является ли ваш порт mysql открытым, состоит в том, чтобы пробовать следующую команду от некоторой отдаленной машины, где server_host - имя хоста вашего mysql сервера: telnet server_host 3306

Не доверяйте никаким данным, введенными пользователями. Они могут обмануть ваш код, вводя специальные символы в web форме или url. Убедитесь, что ваше приложение остается безопасным, если пользователь вводит что-то подобно: drop database mysql;. Это - критический пример, но множество утечек защиты и потеря данных могут происходить из-за хакеров, использующих подобные методы. Также, не забудьте проверять числовые данные. Обычная ошибка должна защитить только строки. Иногда люди думают, что, если база данных содержит только публично доступные данные, она не должна защищаться. Это неправильно. По крайней мере, dos атака может быть выполнена против таких баз данных. Самый простой способ защиты от такого типа нападения состоит в том, чтобы использовать апострофы вокруг числовых констант:

select * from table where id='234'. mysql автоматически преобразовывает эту строку к числу и убирает все нечисловые символы в запросе. Проверяем:

Все web приложения:

1. Попытка вводить ‘ ‘ ‘ ‘”’ в ваших web формах. Если Вы получаете любой вид ошибки mysql, сразу же исследуйте эту проблему.

2. Попытка изменить url, добавляя %22 (‘”’), %23(‘#’), %27‘’’.

3. Попытка изменить типы данных в динамических url от числовых символов к символам, приведенных в предыдущих примерах. Ваше приложение должно быть безопасно против этого и подобных нападений.

4. Попытка вводить символы, пробелы, и специальные символы вместо чисел в числовых полях. Ваше приложение должно удалить их перед их принятием mysql, или ваше приложение должно выдать ошибку.

5. Проверьте размеры данных перед принятием их mysql.

6. Ваше приложение должно соединяться с базой данных, используя пользователя, отличного от того, которого вы используете для административных целей. Не давайте вашим приложением больше прав, чем те, в которых они реально нуждаются.

Пользователи php:

Проверьте функцию addslashes(). После php 4.0.3, доступна функция mysql_escape_string (), которая является основанной на функции с таким же именем в mysql c api.

Пользователи mysql c api:

Проверьте api запрос mysql_escape_string ().

Пользователи mysql++:

Проверьте переходы и кавычки модификаторов в потоках запросов.

Пользователи perl dbi:

Проверьте метод quote() или используйте структурный нуль (placeholders).

Пользователи java jdbc:

Используйте объект preparedstatement и placeholders.

Не передавайте незашифрованные данные по internet. Эти данные доступны для каждого, кто имеет время и способность перехватить их и использовать для собственных целей. Вместо этого, используйте зашифрованный протокол типа ssl или ssh. mysql поддерживает внутренний ssl версии 3.23.9. ssh может использоваться для создания зашифрованных туннелей.

Научитесь использовать tcpdump. В большинстве случаев, вы можете проверить, действительно ли потоки данных mysql незашифрованны, используя следующую команду:

shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings

 
L2Best.net » Форумы Lineage II » Создание сервера » Защита Mysql (Большая статья о защите баз данных)
Страница 1 из 11
Поиск: