Обеспечиваем безопасность инфраструктуры веб-сервера
Сергей «grinder» Яремчук (grinder@ua.fm, )
По последним данным британской компании Netcraft самым популярным Web-сервером в Интернете является Apache, его доля за последние три года постепенно увеличивалась и сегодня составляет 67% рынка. Успех Apache объясняется стабильностью работы, он имеет хорошую репутацию в плане безопасности и прост в администрировании. Но нельзя забывать, что обычно Apache используется не один, а в связке LAMP – Linux, Apache, MySQL и PHP/Perl. Поэтому сегодня мы разберем, как можно повысить безопасность LAMP с помощью ModSecurity, Suhosin, модуля mod_chroot и встроенных средств индейца.
Содержание:
Не смотря на репутацию компонентов LAMP, сегодня только и слышно о PHP Include, SQL Injection, Cross site scripting (XSS) и других атаках, направленных на веб-сервисы. По статистике именно они занимают первые места по количеству зафиксированных инцидентов. Среди основных причин такой негативной тенденции называют широкую доступность инструментов, необходимых для проведения атаки, и недостаточное внимание со стороны разработчиков сайтов к вопросам безопасности. Условно можно выделить два фактора, влияющих на безопасность: ошибки в администрировании и ошибки в программировании веб-ресурса. С ними и будем разбираться. Советы и рекомендации даны применительно к Ubuntu/Debian, подправив расположение файлов, их можно использовать и в любом другом дистрибутиве.
По умолчанию веб-сервер не скрывает название операционной системы, свою версию и информацию о некоторых установленных модулях. Все это злоумышленник может использовать при подготовке атаки. Чтобы сделать индейца менее болтливым, в конфигурационный файл apache2.conf (в некоторых дистрибутивах httpd.conf) следует добавить следующие строки:
ServerSignature Off
ServerTokens Prod
Директива ServerSignature отвечает за вывод информации внизу страницы, например, страницы ошибки 404 или листинга файлов каталога. Что именно выводится, определяет ServerTokens, значение которой по умолчанию Full. При установке в Prod[uctOnly] будет выведено название сервера Apache без номера версии, без информации о модулях и версии операционной системы. Как вариант, можно сразу залезть в исходники (файл httpd.h в Apache 1.3 и ap_release.h в 2.x) и перед компиляцией подправить информацию по своему усмотрению.
В некоторых статьях рекомендуют запускать веб-сервер под отдельной учетной записью, приводя в качестве примера «nobody». Запуск нескольких различных серверов под этим пользователем делает его не менее могущественным, чем root, поэтому для запуска любого сервера следует использовать отдельную учетную запись. Например, в Ubuntu и некоторых дистрибутивах — это www-data:
$ sudo grep User /etc/apache2/apache2.conf
User www-data
Создаем пользователя, от имени которого будет запускаться и работать Web-сервер:
$ sudo adduser --no-create-home --disabled-password --disabled-login www-data
Затем в конфигурационном файле указываем:
User www-data
Group www-data
Теперь установим необходимые права:
$ sudo chown -R root:root /etc/apache2 $ sudo /etc/apache2 -type d | xargs chmod 755 $ sudo /etc/apache2 -type f | xargs chmod 644
Аналогичные команды выполняем для каталогов /var/log/apache2 (здесь хранятся журналы) и /var/www (соответствует «DocumentRoot» в Ubuntu). Нет никаких препятствий для того, чтобы убрать и право на чтение конфигурационных файлов Apache:
$ sudo chmod -R go-r /etc/apache2
По умолчанию индеец загружает довольно большое количество модулей. Чтобы просмотреть те, что скомпилированы вместе с Apache, используй «apache2ctl –l» или «apache2 -l«. К сожалению, «лишнее» из полученного списка можно убрать только путем полной пересборки индейца. Все динамически загружаемые модули (Dynamic Shared Object) можно просмотреть, введя:
$ sudo grep –R LoadModule /etc/apache2/*
Внимательно изучаем полученный список и в конфиге комментируем то, что не нужно. Вот список модулей, которые можно безболезненно отключить, естественно, убедившись, что они действительно нами не используются: mod_imap, mod_autoindex, mod_include, mod_info, mod_userdir, mod_status.
Apache поддерживает два типа аутентификации: basic и digest (обеспечивается модулем mod_auth_digest). В первом случае пароль передается в открытом виде. При его использовании у злоумышленника есть возможность перехватить логин и пароль и получить доступ ко всей «охраняемой» области. В digest передается Response, который представляет собой контрольную (обычно MD5) сумму от комбинации логина, пароля, запрашиваемого URL, метода HTTP и строки nonce, генерируемой сервером при ответе. Последняя позволяет сделать эту строку поистине уникальной. Для включения digest-аутентификации используем:
AuthType Digest
Одной из особенностей Apache является использование типового доступа, когда многие параметры либо устанавливаются по умолчанию, либо наследуются от родительского каталога. Чтобы избежать неприятностей, следует принудительно ограничить выполнение CGI-скриптов, SSI (Server Side Includes) включений, индексирования каталога и следование символическим ссылкам. Для этого в описании ресурса необходимо деактивировать следующие директивы:
Options All -Indexes -Includes –ExecCGI -FollowSymLinks
Либо отключить все сразу:
Options None
Чтобы злоумышленник не смог прочитать временные или конфигурационные файлы, используй следующую конструкцию:
<Files «(^.ht|~$|.bak$|.BAK$)»>
Order Allow,Deny
Deny from all
</Files>
Во избежание доступа к файлам, расположенным вне корневого каталога веб-сервера, нужно сначала принудительно ограничить доступ, а затем явно разрешить его только для требуемых каталогов. При нормальном раскладе подключившийся пользователь не может выйти за DocumentRoot, но для страховки стоит указать:
<Directory />
Order Deny,Allow
Deny from all
Options None
AllowOverride None
</Directory>
<Directory /var/www>
Order Allow,Deny
Allow from all
</Directory>
При необходимости значения директив AllowOverride и Options переопределяются в конкретном каталоге.
Другим выходом не выпустить пользователя за «DocumentRoot» является использование chroot, речь о котором пойдет далее.
Не всегда веб-сервер или отдельный ресурс должен быть виден из сети. Например, используется прокси, либо это внутренний сервер компании. Если нет возможности закрыть доступ брандмауэром или использовать отдельный интерфейс, тогда доступ к ресурсу следует ограничить на основании IP-адреса или диапазона IP-адресов:
Order Deny,Allow
Deny from all
Allow from 192.168.0.0/24
Несмотря на то, что директива Satisfy имеет всего два параметра All и Any, она предоставляет возможность более гибко контролировать доступ к ресурсу. Например, нам нужно, чтобы доступ к приватной папочке могли получить только зарегистрированные пользователи и только с указанных адресов. Как это сделать? Очень просто:
Order Deny,Allow
Deny from all
Require valid-user
Allow from 192.168.0.0/24
Satisfy All
А для того чтобы пользователи внутренней сети могли вообще не регистрироваться, ставим вместо All — Any.
Если изменить значения некоторых параметров, можно смягчить эффект DoS-атаки. Например, Timeout определяет, в течение какого времени сервер будет ожидать ответ клиента. В более ранних версиях Apache значение этой директивы равнялось 1200 секундам, затем оно было уменьшено до 300. Мы можем спокойно его урезать, например, до 60 (отразится только на пользователях с плохим соединением):
Timeout 60
По умолчанию размер клиентского запроса не ограничен. Этот также может быть использовано для организации DoS-атаки. Администратор в силах принудительно указать размер запроса в пределах от 0 (неограничен) до 2147483647 (2 Гб) как для всего сервера, так и для отдельных ресурсов. Например, чтобы ограничить размер запроса 100 килобайтами, пишем:
LimitRequestBody 102400
Если клиент загружает на сервер некоторые данные (например, содержимое заполненных форм), то этот параметр следует скорректировать.
Для противодействия атакам «отказ в обслуживании» существует целый ряд директив: LimitRequestFields, LimitRequestFieldSize и LimitRequestLine, MaxRequestsPerChild, MaxClients и некоторые другие. При необходимости их значения, возможно, стоит пересмотреть, выставив оптимальные для конкретных условий. Как вариант, для борьбы с DoS-атаками можно применять специальный модуль mod_evasive (.
Значительно повысить защищенность веб-ресурса можно с помощью ModSecurity. Этот проект, созданный Иваном Ристиком в 2003 году, позволяет защищать веб-приложения как от известных, так и еще неизвестных атак. ModSecurity может работать в виде модуля веб-сервера Apache, либо в автономном режиме. Его использование прозрачно, установка и удаление не требуют изменения настройки сервисов и сетевой топологии, кроме того, при обнаружении уязвимого места теперь нет необходимости править исходные коды, создавая новые ошибки, достаточно добавить новое правило, запрещающее вредоносную комбинацию.
В репозитарии некоторых дистрибутивов уже включен нужный пакет, следует поискать что-то вроде mod-security. В Debian достаточно в /etc/apt/sources.list добавить новый репозитарий:
deb http://etc.inittab.org/~agi/debian/libapache-mod-security2/ etch/
И затем можно инсталлировать:
# apt-get update # apt-get install libapache2-mod-security2
Установить ModSecurity из исходных текстов также просто. Для сборки необходимы заголовочные файлы Apache, поэтому забираем исходные тексты веб-сервера из репозитария или с сайта проекта:
$ sudo apt-get apache2-src libxml2-dev
Если используются исходные тексты, взятые с сайта проекта, то перед компиляцией mod_security следует сконфигурировать веб-сервер командой «./configure» с нужными параметрами (для работы модуля понадобится ′--enable-unique-id′), а затем выполнить следующие действия:
$ wget –c www.modsecurity.org/download/modsecurity-apache_2.1.1.tar.gz $ tar xzvf modsecurity-apache_2.1.1.tar.gz $ cd modsecurity-apache_2.1.1/apache2
Теперь редактируем Makefile:
$ mcedit Makefile # Меняем apxs на apxs2 (APache eXtenSion tool) APXS = apxs2 # Каталог с исходными текстами Apache top_dir = /home/grinder/source/httpd-2.2.4
Компилируем модуль, останавливаем Apache, устанавливаем модуль:
$ make $ sudo /etc/init.d/apache2 stop $ sudo make install
В конфигурационный файл веб-сервера добавляем две строчки:
LoadFile /usr/lib/libxml2.so
LoadModule security2_module /usr/lib/modules/mod_security2.so
Для удобства все настройки mod_security лучше вынести в отдельный файл, взяв за пример готовый шаблон и подключив его в apache2.conf директивой:
Include /etc/apache2/mod_security.conf
Копируем шаблон и правим:
$ sudo cp modsecurity-apache_2.1.1/modsecurity.conf-minimal /etc/apache2/mod_security.conf $ sudo mcedit /etc/apache2/mod_security.conf
<IfModule mod_security2.c>
SecRuleEngine On
…
SecFilterDefaultAction «deny,log,status:430″
</IfModule>
Активируем модуль mod_unique_id:
$ sudo a2enmod unique_id
Теперь можно запускать апач:
$ sudo /etc/init.d/apache2 start
Если все работает нормально, можно добавлять правила. Команда разработчиков уделяет большое внимание усовершенствованию кода mod_security, оставляя создание правил на откуп пользователю, поэтому оригинальный конфигурационный файл имеет всего несколько рулесетов, находящихся в подкаталоге rules. На сайте проекта лежит отдельный архив modsecurity-core-rules. Для подключения входящих в его состав правил достаточно скопировать все conf-файлы в каталог /etc/apache2 и в секции mod_security2.c указать:
Include rules/*.conf
Include rules/blocking/*.conf
Подключать все сразу не стоит. Некоторые из правил требуют редактирования под конкретные условия, лучше разбираться постепенно.
Защищаем PHP с помощью Suhosin
Задача проекта — защита серверов и пользователей от целого ряда известных проблем в приложениях и ядре PHP, так как «safe_mode» помогает далеко не всегда. Сам Suhosin состоит из двух независимых частей, которые могут использоваться как раздельно, так и совместно. Первая часть – небольшой патч к ядру, осуществляющий низкоуровневую защиту структур данных против переполнения буфера, уязвимости форматной строки и от ошибок в реализации функции realpath, присущей некоторым платформам, а также других потенциальных уязвимостей ядра PHP. Вторая часть реализована в виде расширения, которое фактически и осуществляет всю основную защиту, при необходимости его очень просто доустановить в уже рабочую систему без полной пересборки PHP. С полным списком возможностей можно познакомиться на .
В случае нарушения установленных правил возможна блокировка переменных, отсылка определенного HTTP кода ответа, перенаправление браузера пользователя, выполнение другого PHP скрипта. Все события заносятся в журналы, для чего может использоваться syslog, свой модуль или внешний скрипт. Последние версии расширения Suhosin совместимы практически со всеми версиями PHP.
Установка Suhosin состоит из двух этапов: наложение патча на PHP, с последующей его пересборкой, и компиляция модуля расширения. Хотя возможна и сборка со встроенным расширением. Чтобы не было проблем с зависимостями, в Ubuntu перед началом установки рекомендую дать команду «sudo apt-get build-dep php5«.
Скачиваем PHP, затем патч suhosin под используемую версию PHP и модуль расширения. Все это распаковываем, накладываем патч и компилируем:
$ tar xvjf php-5.2.3.tar.bz2 $ gunzip suhosin-patch-5.2.3-0.9.6.2.patch.gz $ cd php-5.2.3 $ patch -p 1 -i ../suhosin-patch-5.1.6-0.9.5.patch $ ./configure [--enable-so и другие параметры при необходимости] $ make $ make test $ sudo make install
Теперь собираем модуль расширения:
$ tar xzvf suhosin-0.9.20.tgz $ cd suhosin-0.9.20 $ phpize $ ./configure --prefix=/usr/lib/php5/20060613+lfs/ $ make $ make test $ sudo make install
Проверить сборку можно, введя команду:
$ php –v PHP 5.2.3 with Suhosin-Patch 0.9.6.2 (cli) (built: Jul 26 2007 11:35:13)
Все настройки Suhosin производятся в файле php.ini. Патч поддерживает только опции регистрации, поэтому первой записью обязательно подключаем модуль suhosin.so (он должен быть виден переменной LD_RUN_PATH):
extension=suhosin.so
После установки Suhosin будет работать с настройками по умолчанию, которые достаточны, но, возможно, не оптимальны для твоей конфигурации.
Для построения chroot-окружения нам понадобится модуль mod_chroot. В репозитарии Ubuntu он присутствует:
$ sudo apt-get install libapache2-mod-chroot
Параллельно будет установлен пакет mod-chroot-common, содержащий документацию (/usr/share/doc/mod-chroot-common). Для самостоятельной сборки mod_chroot достаточно распаковать свежескаченный архив и ввести команду «apxs2 -cia mod_chroot.c». Далее следует указать, что рабочий каталог теперь является корневым, т.е. в apache2.conf прописываем:
<IfModule mod_chroot.c>
LoadFile /lib/libgcc_s.so.1
PidFile /var/run/httpd.pid
ChrootDir /var/www
DocumentRoot /
</IfModule>
Значение DocumentRoot изменяем с /var/www на / и все ссылки на ресурсы даем относительно корня. В apache2.conf не забываем подключить модуль:
LoadModule chroot_module /usr/lib/apache2/modules/mod_chroot.so
Либо в Ubuntu правильней:
$ sudo a2enmod mod_chroot
При использовании Apache2 понадобится создать каталог для PID файла.
$ sudo mkdir -p /var/www/var/run $ sudo chown -R root:root /var/www/var/run $ sudo ln -s /var/www/var/run/httpd.pid /var/run/httpd.pid
Перезапускаем индейца и проверяем работу.
Это далеко не все, что можно сделать для защиты LAMP. Также следует учесть, что данные советы не могут гарантировать абсолютной безопасности, такого просто не бывает в природе, хотя несколько уменьшить риск они позволяют. Кроме того, в некоторых средах часть параметров могут вызывать проблемы или влиять на производительность. Поэтому к их использованию следует подходить осторожно, вводя изменения постепенно и тщательно тестируя результат. Универсальный совет по-прежнему один: изучать документацию и включать только то, что нужно.
Статья опубликована в октябрьском номере журнала «Xakep» за 2007 год.





