Защищаем Apache 2. Шаг за шагом


Артур Май
При выборе Web сервера, Apache очень часто побеждает своих конкурентов из-за стабильности, высокой производительности, открытого исходного кода и множеством других преимуществ. Сейчас Apache существует в виде двух версий - устойчивая версия 1.3, используемая миллионами пользователей и, с другой стороны, усовершенствованная и перепроектированная версия 2.0.
Хотя новая версия имеет ряд существенных дополнений и особенностей, многие администраторы все еще используют более старую версию 1.3, считая ее более устойчивой и безопасной. Множество фактов потверждают это. Так как версия 1.3 использовалась миллионами пользователей в течение долгого времени, большинство брешей в защите в этой версии, по всей, было уже обнаружены. В то же самое время версия 2.0 может быть имеет множество пока еще не обнаруженных уязвимостей.
Продолжая серию предыдущих статей (Apache, PHP, MySQL), в этой статье мы расскажем о пошаговой установке и конфигурировании Apache 2.0, чтобы снизить риск неавторизованного доступа или успешного взлома в случае применения новой уязвимости, обнаруженной в Apache Web сервере. В результате, можно будет пользоваться новыми особенностями Apache Web сервера 2.0, не слишком волнуясь о новых ошибках защиты, которые могут представлять серьезную угрозу
Функциональные требования
В мире безопасности, существует несколько золотых принципов, которые обязаны всегда соблюдаться. Один из таких принципов - правило, которое говорит, что должны использоваться только необходимые части программного обеспечения. Все другие компоненты должны быть заблокированы, сделаны недоступными или даже не должны вообще быть установлены.
Логика этого правила очень проста - если есть программное обеспечение с множеством компонентов, которые включены по умолчанию, то обнаруженная уязвимость защиты только в одном из этих компонентов, может поставить под угрозу целую систему под опасность успешного взлома. С другой стороны, если используются только несколько крайне необходимых компонентов, обнаруженная новая уязвимость защита не обязательно делает программное обеспечение уязвимым - потому что обнаруженная уязвимость может затрагивать компоненты, которые отключены или не установлены. Вероятность успешного взлома в этом случае очевидно намного ниже, чем в случае заданной по умолчанию инсталляции.
Поэтому, перед установкой Apache 2, очень важно знать, какие функциональные возможности мы действительно ожидаем от Web сервера. Это позволит нам подготовить список модулей, которые мы оставим включенными, а остальные будут отключены в процессе установки.
Согласно этому правилу, мы предполагаем, что будут использоваться только следующие основные особенности Apache 2:
1. Обрабатываться будут только статические HMTL страницы.
2. Сервер должен поддерживать механизм виртуального хостинга.
3. Доступ к некоторым Web страницам может быть ограничен по IP адресам или пользователям (basic authentication).
4. Сервер должен регистрировать все Web запросы (включая информацию о web браузере).
Обратите внимание, что вышеупомянутые функциональные возможности не поддерживают CGI сценарии, SSL протокол или другие полезные особенности Apache сервера. Это сделано так, потому что главная цель статьи состоит в том, чтобы представить общий метод защиты Apache 2.0, не сосредотачиваясь на специфическом выполнении. Если есть потребность в дополнительных функциональных возможностях, читатели
" могут использовать представленное решение как отправную точку, и расширить его, включая дополнительные модули, например mod_ssl, mod_cgi и тд.
Предположения защиты
Чтобы обеспечить наиболее возможный уровень защиты, и в то же самое время сделать это решение переносимым среди различных Linux/BSD систем, мы будем использовать следующие уровни защиты:
Операционная система
" операционная система должна быть укреплена в максимально возможной степени; все ненужные компоненты должны быть удалены из системы.
" Операционная система не должна позволять выполнять программы на стеке (если поддерживается).
" Все ненужные сетевые службы должны быть заблокированы.
" Число SUID/SGID файлов должно быть минимизировано.
Apache web server
" Включены быть только абсолютно необходимые модули Apache; остальное должно быть заблокировано в процессе компиляции
" Должны быть выключены все диагностические web-страницы и автоматическая служба индексации каталога.
" Cервер должен раскрыть наименьшее количество количества информации о себе насколько возможно - политика запутывания. Хотя это - не реальный уровень защиты, его применение делает возможные проникновения трудно осуществимыми.
" Web сервер должен выполнятся под выделенным UID/GID, который не используется другими системными процессами.
" Apache процесс должен иметь ограниченный доступ к файловой системе (chrooting).
" В Apache chrooted среде не должно присутствовать никаких программных оболочек (/bin/sh, /bin/csh и т.п.) - это позволяет намного усложнить процесс выполнения вредоносного кода.
Установка операционной системы
Прежде всего, мы должны выбрать операционную систему, на которой будет выполняться Web сервер. Основная часть этой статьи описывает защиту Apache на FreeBSD (5.1), однако читатели могут свободно использовать их любимую Unix, BSD, Linux или Linux-подобную операционную систему.
Относительно наших предположений защиты, после установки операционной системы она должна быть защищена против удаленных и локальных нападений. Независимо от выбора UNIX/Linux/BSD дистрибутива, очень важно установить только основную операционную систему и удалить любые избыточные пакеты и применять на современном уровне исправления к ядру и всему установленному программному обеспечению.
Также рекомендуют периодически синхронизировать локальное время с доверенным сервером времен, используя часы с сервера времени, которому доверяют, используя Network Time Protocol (NTP), и посылать журналы регистрации удаленному, выделенному регистрационному серверу.
После того, как система подготовлена, мы можем начать устанавливать Apache 2.0. Первым шагом мы должены добавить новую группу и правильного пользовател,я названного Apache. Пример для FreeBSD показан ниже:
pw groupadd apache
pw useradd apache -c "Apache Server" -d /dev/null -g apache -s /sbin/nologin
Дочерние Apache процессы должны выполнятся с привилегиями группы и пользователя apache. вышеупомянутая учетная запись будет выделена Apache Web серверу, это поможет обеспечить разделение привилегий и избежать потенциальных проблем защиты, когда несколько различных процессов выполняются под той же самой учетной записью, например под пользователем nobody.
Загрузка программного обеспечения
Далее, нам необходимо загрузить последнюю версию Apache Web сервера из Web сайта Apache. Так как мы хотим отключить ненужные модули в процессе компиляции, очень важно загрузить исходный код Apache. Также важно проверить загруженное программное обеспечение против PGP сигнатуры, чтобы удостовериться, что загруженная версия немодифицирована.
lynx http://httpd.apache.org/download.cgi
<download: httpd-2.0.xx.tar.gz, httpd-2.0.xx.tar.gz.asc, KEYS>
gpg --import KEYS
gpg httpd-2.0.49.tar.gz.asc
gpg: Good signature from "Sander Striker <striker@apache.org>"
tar zxvf httpd-2.0.49.tar.gz
cd ./httpd-2.0.49/
Выбор Apache модулей
После того, как распакован исходный код Apache, мы должны выбрать, какие модули останутся, и какие должны быть удалены. Краткое описание всех модулей, доступных в Apache 2.0, могут быть найдены в http://httpd.apache.org/docs-2.0/mod/. Выполняя функциональные возможности и требования защиты, принятые в начале этой статьи, мы компилируем только следующие модули:
Имя модуля Описания
core Основное ядро Apache, необходимое для инсталляции.
http_core Основное HTTP ядро, необходимое для Apache 2.0 инсталляции.
prefork Модуль мультизадачного режима (MPM), для обеспечения многозадачной работы.
mod_access Обеспечивает управление доступом, основанным на имени хоста клиента, IP-адресе и других характеристиках запроса клиента. Поскольку этот модуль необходим, чтобы использовать директивы "order", "allow" и "deny", он должен оставаться доступным.
mod_auth Требуется для осуществления пользовательской идентификации (базовая HTTP идентификация).
mod_dir Требуется, для поиска и обслуживания каталога с индексными файлами: "index.html", "default.htm", и т.д.
mod_log_config Требуется для регистрации запросов, сделанных на сервер.
mod_mime Требуется для установки набора символов, content encoding, обработчика, content-language, и документов MIME типа.
Так как мы хотим использовать только минимальное число модулей, мы компилируем все модули статически. Благодаря этому, мы устраним возможность применения уязвимости еще в одном модуле - mod_so.
Компилирование и установка программного обеспечения
В этом шаге мы конфигурируем, компилируем, и устанавливаем Apache Web сервер следующим образом:
./configure
--prefix=/usr/local/apache2
--with-mpm=prefork
--disable-charset-lite
--disable-include
--disable-env
--disable-setenvif
--disable-status
--disable-autoindex
--disable-asis
--disable-cgi
--disable-negotiation
--disable-imap
--disable-actions
--disable-userdir
--disable-alias
--disable-so
make
su
umask 022
make install
chown -R root:sys /usr/local/apache2

После того, как Apache установлен, мы должны удостовериться, что используются только следующие модули:
/usr/local/apache2/bin/httpd -l
Compiled in modules:
core.c
mod_access.c
mod_auth.c
mod_log_config.c
prefork.c
http_core.c
mod_mime.c
mod_dir.c

Конфигурирование Apache
Перед первым запуском Apache, мы должны изменить файл конфигурации Apache. Мы должны сделать это, потому что заданный по умолчанию файл конфигурации использует модули, которые мы отключили, и без модификаций Apache не будет выполнятся.
Таким образом, мы должны удалить/usr/local/apache2/conf/httpd.conf файл и создать новый httpd.conf в его месте, со следующим содержанием:
# =================================================
# Basic settings
# =================================================
Listen 0.0.0.0:80
User apache
Group apache
ServerAdmin webmaster@www.ebank.lab
UseCanonicalName Off
ServerSignature Off
HostnameLookups Off
ServerTokens Prod
ServerRoot "/usr/local/apache2"
DocumentRoot "/www"
PidFile /usr/local/apache2/logs/httpd.pid
ScoreBoardFile /usr/local/apache2/logs/httpd.scoreboard
<IfModule mod_dir.c>
DirectoryIndex index.html
</IfModule>

# =================================================
# HTTP and performance settings
# =================================================
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

<IfModule prefork.c>
MinSpareServers 5
MaxSpareServers 10
StartServers 5
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

# =================================================
# Access control
# =================================================
<Directory />
Options None
AllowOverride None
Order deny,allow
Deny from all
</Directory>
<Directory "/www/www.ebank.lab">
Order allow,deny
Allow from all

</Directory>
<Directory "/www/www.test.lab">
Order allow,deny
Allow from all
</Directory>

# =================================================
# MIME encoding
# =================================================
<IfModule mod_mime.c>
TypesConfig /usr/local/apache2/conf/mime.types
</IfModule>
DefaultType text/plain

<IfModule mod_mime.c>
AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType application/x-tar .tgz
</IfModule>

# =================================================
# Logs
# =================================================
LogLevel warn
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
ErrorLog /usr/local/apache2/logs/error_log
CustomLog /usr/local/apache2/logs/access_log combined

# =================================================
# Virtual hosts
# =================================================
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/www/www.ebank.lab"
ServerName "www.ebank.lab"
ServerAlias "www.e-bank.lab"
ErrorLog logs/www.ebank.lab/error_log
CustomLog logs/www.ebank.lab/access_log combined
</VirtualHost>

<VirtualHost *>
DocumentRoot "/www/www.test.lab"
ServerName "www.test.lab"
ErrorLog logs/www.test.lab/error_log
CustomLog logs/www.test.lab/access_log combined
</VirtualHost>
По сравнению с заданным по умолчанию файлом конфигурации, были сделаны следующие важные изменения:
" Уменьшено до минимума число допускаемых модулей
" процесса) установлены, чтобы выполнятся с root Процессы Apache (кроме уникальными привилегиями пользователя/группы.
" Apache раскрывает наименьшее количество информации о себе насколько это возможно.
" Установлены более ограниченные права доступа к содержанию сайта.
Согласно нашим требованиям, вышеупомянутая конфигурация предполагает, что есть два виртуальных хоста, поддержавшие Apache:
" www.e-bank.lab) (псевдоним: www.ebank.lab
" www.test.lab
Содержание вышеупомянутых виртуальных хостов физически хранятся под /www каталогом, поэтому перед запуском Apache, мы также должны создать соответствующие каталоги с типовыми web-страницами:
mkdir -p /www/www.ebank.lab
mkdir -p /www/www.test.lab
echo "<html><head><title>eBank.lab</title></head><body>eBank.lab
works!</body></html>" > /www/www.ebank.lab/index.html
echo "<html><head><title>test.lab</title></head><body>Test.lab
works!</body></html>" > /www/www.test.lab/index.html
chmod -R 755 /www
chown -R root:sys /www

Мы должны также подготовить каталоги для хранения журналов регистраций:
mkdir -p /usr/local/apache2/logs/www.ebank.lab
mkdir -p /usr/local/apache2/logs/www.test.lab
chmod -R 755 /usr/local/apache2/logs
chown -R root:sys /usr/local/apache2/logs
Наконец, мы можем попробовать выполнить Apache, и проверить, что все работает должным образом:
/usr/local/apache2/bin/apachectl start
Если доступен сайт www.ebank.lab через web-браузер, мы можем завершение Apache:
/usr/local/apache2/bin/apachectl stop
И затем перейдем к chroot сервера. Если возникли проблемы, должны быть проанализированы журналы регистрации или команда truss (для BSD и Solaris пользователей) следующим образом:
truss /usr/local/apache2/bin/httpd
Обратите внимание, что для Linux пользователей, эквивалентная команда - strace. Анализ данных, представленных командами truss (или strace), могут помочь в решении возникших проблем.
Chrooting сервера
Далее, ограничим доступ Apache процесса к файловой системе. Техника chrooting подробно описана в предыдущей статье, поэтому в этом пункте мы просто создадим структуру директорий для нашего нового Apache:

mkdir -p /chroot/httpd/dev
mkdir -p /chroot/httpd/etc
mkdir -p /chroot/httpd/var/run
mkdir -p /chroot/httpd/usr/lib
mkdir -p /chroot/httpd/usr/libexec
mkdir -p /chroot/httpd/usr/local/apache2/bin
mkdir -p /chroot/httpd/usr/local/apache2/lib
mkdir -p /chroot/httpd/usr/local/apache2/logs/www.ebank.lab
mkdir -p /chroot/httpd/usr/local/apache2/logs/www.test.lab
mkdir -p /chroot/httpd/usr/local/apache2/conf
mkdir -p /chroot/httpd/usr/local/lib
mkdir -p /chroot/httpd/www
Владелец весь выше каталогов должен быть root, и права доступа не должны позволить обычным пользователям выполнять любые изменения в этих каталогах:
chown -R root:sys /chroot/httpd
chmod -R 0755 /chroot/httpd
Затем, мы создадим специальный файл устройства,/dev/null:
ls -al /dev/null
crw-rw-rw- 1 root wheel 2, 2 Mar 14 12:53 /dev/null
mknod /chroot/httpd/dev/null c 2 2
chown root:sys /chroot/httpd/dev/null
chmod 666 /chroot/httpd/dev/null

Мы также должны создать /chroot/httpd/dev/log устройство, которое необходимо для нормальной работы сервера. В случае нашей FreeBSD системы, нужно добавить следующую строкe к /etc/rc.conf: syslogd_flags="-l /chroot/httpd/dev/log"
Для того, чтобы вступили в силу наши изменения, мы также должны перезапустить syslogd демон с новым параметром:
kill `cat /var/run/syslog.pid`
/usr/sbin/syslogd -ss -l /chroot/httpd/dev/log
Далее скопируем все необходимые программы, библиотеки и файлы конфигурации в новое дерево каталогов. В случае FreeBSD 5.1 список требуемых файлов следующий:
cp /usr/local/apache2/bin/httpd /chroot/httpd/usr/local/apache2/bin/
cp /usr/local/apache2/lib/libaprutil-0.so.9 /chroot/httpd/usr/local/apache2/lib/
cp /usr/local/apache2/lib/libapr-0.so.9 /chroot/httpd/usr/local/apache2/lib/
cp /usr/local/apache2/conf/mime.types /chroot/httpd/usr/local/apache2/conf/
cp /usr/local/apache2/conf/httpd.conf /chroot/httpd/usr/local/apache2/conf/
cp /usr/local/lib/libexpat.so.4 /chroot/httpd/usr/local/lib/
cp /usr/lib/libc.so.5 /chroot/httpd/usr/lib/
cp /usr/lib/libcrypt.so.2 /chroot/httpd/usr/lib/
cp /usr/lib/libm.so.2 /chroot/httpd/usr/lib/
cp /usr/libexec/ld-elf.so.1 /chroot/httpd/usr/libexec/
cp /var/run/ld-elf.so.hints /chroot/httpd/var/run/
cp /etc/hosts /chroot/httpd/etc/
cp /etc/nsswitch.conf /chroot/httpd/etc/
cp /etc/resolv.conf /chroot/httpd/etc/
cp /etc/group /chroot/httpd/etc/
cp /etc/master.passwd /chroot/httpd/etc/passwords
В случае других Unix, BSD, Linux и Linux-подобных систем, список требуемых файлов может быть определен, используя команды типа ldd, strace, , truss или strings, как было описанр в предыдущей статье. После того, как сделаны вышеупомянутые шаги, мы должны подготовить базу данных пароля, которая должна присутствовать в chrooted файловой системе. Таким образом, от /chroot/httpd/etc/passwords и/chroot/httpd/etc/group мы должны удалить все строки кроме apache. Затем, мы должны формировать базу данных пароля следующим образом:
cd /chroot/httpd/etc
pwd_mkdb -d /chroot/httpd/etc passwords
rm -rf /chroot/httpd/etc/master.passwd
Вышеупомянутые команды должны быть выполнены при использовании FreeBSD. В других системах может быть достаточно редактировать /chroot/httpd/etc/passwd и /chroot/httpd/etc/shadow файлы. Наконец, мы можем копировать типовое содержание сайта к chrooted среде:
cp -R /www/* /chroot/httpd/www/
И проверить корректную работу Apache Web сервера:
chroot /chroot/httpd /usr/local/apache2/bin/httpd
Заключительные шаги
Если теперь ваш Apache работает должным образом, нам осталось создать сценарий, который запустит Apache во время начальной загрузки системы. Для этого может использоваться следующий сценарий:

#!/bin/sh CHROOT=/chroot/httpd HTTPD=/usr/local/apache2/bin/httpd PIDFILE=/usr/local/apache2/logs/httpd.pid echo -n " apache" case "$1" in start) /usr/sbin/chroot $CHROOT $HTTPD ;; stop) kill `cat ${CHROOT}/${PIDFILE}` ;; *) echo "" echo "Usage: `basename $0` {start|stop}" >&2 exit 64 ;; esac exit 0
Вышеупомянутый сценарий должен быть скопирован в каталог, где находятся по умолчанию сценарии запуска. В случае с FreeBSD это - /usr/local/etc/rc.d каталог. Права доступа к тому файлу должны быть установлены следующим образом:
chown root:sys/usr/local/etc/rc.d/apache.sh
chmod 711/usr/local/etc/rc.d/apache.sh

Выводы
Главная цель этой статьи состояла в том, чтобы представить метод защиты Apache 2.0, который позволяет читателям смягчать риск успешного взлома, даже если используется новая уязвимость. Было показано, как установить Apache с минимальным номером модулей, как установить более ограничительную конфигурацию, и как осуществить защиту против большого количества эксплоитов, выполняя Web сервер в chrooted среде, без использования любых программ оболочки. И хотя никакой метод не может предоставить 100% защиты, применяя вышеупомянутые рекомендации, будет намного труднее выполнить нападение против Apache 2.0 по сравнению с заданной по умолчанию инсталляцией.

Обновлено: 13.03.2015