Защищенный Apache: шаг за шагом во FreeBSD


- Автор: Artur Maj , 14.05.2003.
Перевод и редактирование: kAMIkaDze

Эта статья в пошаговом режиме покажет, как установить и сконфигурировать Apache 1.3.x Web server так, чтобы уменьшить риск удачного проникновения в систему, при обнаружении новых дыр в этом по праву считающимся одним из лучших Web серверов.

Функциональные возможности
--------------------------

Прежде чем мы начнем "защищать" Apache, мы должны определить, какие функции должен выполнять наш сервер. На данный момент Apache
используют для решения совершенно разных задач, поэтому очень сложно написать универсальное руководство по установки защищенного web
сервера. Именно по этому в этой статье мы будем опираться на следующие функциональные возможности:
* Web сервер будет доступен через Интернет;
* Будут использоваться только статические HTML страницы
* Сервер будет поддерживать name-based virtual hosting механизм
* Некоторые Web страницы будут доступны только пользователям с определенным IP адресом
* Сервер будет записывать все Web запросы (включая информацию о Web браузерах)

Стоит подчеркнуть, что приведенная выше модель не поддерживает PHP, JSP, CGI или любые другие технологии, которые дают возможность
взаимодействовать с Web службами. Использование таких технологий может серьезно повлиять на безопасность сервера. Даже маленький неприметный сценарий может очень сильно уменьшить уровень защиты Web сервера.
Почему? Прежде всего, приложения ASP/CGI могут содержать уязвимость защиты (например SQL injection или cross-site-scripting). Во вторых,
сама технология может быть опасной (уязвимости в PHP и Perl модулях и т.д.). Именно поэтому я настоятельно рекомендую использовать такие
технологии только, когда обойтись без них просто невозможно.


Проектирование защиты
---------------------

Одним из наиболее важных элементов любого компьютерного проекта является проектирование защиты. Эта операция должна быть выполнена еще до того, как проект будет закончен. Вот как мы спроектируем защиту нашего Web сервера:
* Операционная система должна быть максимально защищена как от локальных, так и от удаленных атак;
* Сервер не должен предоставлять какие-либо сетевые сервисы, кроме HTTP: (80/TCP);
* Удаленный доступ к серверу должен быть под контролем файерволла, который должен блокировать подключения к любым другим портам,
кроме 80/TCP (порт Web сервера);
* Apache Web server должен быть единственной службой, запущенной в системе;
* Только самые необходимые модули Apache должны быть включены;
* Всякие Web-страницы диагностики должны быть отключены;
* Сервер должен выдавать как можно меньше информации о себе;
* Apache Web сервер должен быть запущен под уникальными UID/GID, которые не используются другими процессами;
* Процесс Apache должен иметь ограниченный доступ к файловой системе (chrooting); и
* Никакие оболочки командного интерпритатора не должны находиться в chroot окружении (/bin/sh, /bin/csh и т. д.).


Установка операционной системы
------------------------------

Перед установкой Apache мы должны выбрать операционную систему, на которой будет работать наш Web сервер. Здесь мы имеем широкий выбор, потому что Apache может быть скомпилирован и установлен практически на любой операционной системе. Оставшаяся часть статьи покажет, как обеспечить высокий уровень безопасности Apache Web сервера на ОС FreeBSD (4.7), однако описанные методы можно применить и на других UNIX/Linux системах. Единственная операционная система, которую я не рекомендую использовать - MS Windows - главным образом из-за ограничений в настройке безопасности Apache.

Первым шагом в обеспечении хорошей защиты Web сервера является улучшение/укрепление безопасности операционной системы. К сожалению, эта тема выходит за рамки данной статьи. Однако, существует множество статей/документов/заметок в сети по этому чрезвычайно важному вопросу.

После того как система установлена и защищена должным образом, мы должны добавить новую группу и обычного пользователя "apache" (пример на FreeBSD):

pw groupadd apache
pw useradd apache -c "Apache Server" -d /dev/null -g apache -s /sbin/nologin

По умолчанию, процесс Apache запущен с привилегиями пользователя nobody (за исключением главного процесса, который запущен с привилегиями root) и GID'ом группы nogroup. Это может привести к серьезной угрозе защиты. При удачном проникновении, взломщик может
получить доступ ко всем другим процессам, которые запущены под теми же UID/GID.

Следовательно, оптимальным решением будет запуск Apache под UID/GID уникального пользователя/группы, которые будут работать только с нашим Web сервером и ни с каким другим софтом.


Подготовка Программного обеспечения
-----------------------------------

Следующий шаг - вы должны загрузить самую последнюю версию [78]Apache Web server. Некоторые опции Apache могут быть включены только при компиляции, таким образом очень важно скачать исходный код, а не так называемую "binary-версию".

После успешной загрузки Apache, мы должны его распаковать. Затем нам предстоит решить, какие модули нам пригодятся, а какие нет. Короткие
описания всех модулей можно найти на http://httpd.apache.org/docs/mod/

Модули Apache

Выбор модулей - один из наиболее важных шагов в обеспечении хорошей защиты Apache Web server. Мы должны руководствоваться одним хорошим правилом: чем меньше, тем лучше. Чтобы задействовать нужные нам функциональные возможности и обеспечить хорошую защиту, должны быть включены следующие модули:

httpd_core - Ядро Apache, требуется при каждой установке Apache.
mod_access - Контроль доступа к каталогам сервера в зависимости от IP-адреса или имени узла клиента.
mod_auth - Требуется, чтобы осуществлять авторизацию пользователей, используя текстовые файлы.
mod_dir - Требуется, чтобы искать индексные файлы: "index.html", "default.html", и т. д.
mod_log_config - Обеспечивает регистрацию запросов, направляемых серверу.
mod_mime - Содержит директивы, способствующие организации на сервере различных типов MIME.

Все остальные модули Apache должны быть выключены. Мы можем спокойно их отключить, потому что они нам не понадобятся. Отключая ненужные модули, мы предотвращаем возможность взломщика эксплуатировать уязвимость, которая была найдена в одном из этих модулей.

Также стоит обратить внимание, что два модуля Apache (mod_autoindex и mod_info) являются наиболее опасными. Первый модуль позволяет
автоматически проиндексировать каталог и он включен по умолчанию.
Чтобы посмотреть, как он работает, введите, например,
http://server_name/icons/ и если в этом каталоге нет индексных файлов, то будет выведено содержание всего каталога. Второй модуль,
mod_info, никогда не должен быть доступен через Интернет, потому что он показывает всю конфигурацию Web сервера Apache.

Следующий вопрос - как компилировать модули. Мне кажется, что статический метод - самый лучший (коды встраиваются в исполняемые
файлы), нежели динамическая (коды собираются в момент запуска программы). Выбирая статический метод, мы также устраняем потребность
в еще одном модуле - mod_so.

Компилирование программного обеспечения
---------------------------------------

Прежде всего, если существуют патчи, то их нужно немедленно установить. Затем вы должны скомпилировать и установить сервер так:

./configure --prefix=/usr/local/apache --disable-module=all
--server-uid=apache --server-gid=apache --enable-module=access
--enable- module=log_config --enable-module=dir
--enable-module=mime --enable-module=auth
make
su
umask 022
make install
chown -R root:sys /usr/local/apache


Chroot'им сервер
----------------

Делая следующий шаг, мы ограничим доступ процессу Apache к файловой системе. Достигнуть этой цели мы можем, путем chroot'a главного демона Apache (httpd). Вообще, chroot - это создание новой структуры каталога root, перемещение всех демонов в новый каталог и запуск надлежащих демонов в этой новой среде. Благодаря этому, daemon (и все порожденные им процессы) будет иметь доступ только к этой новой структуре каталога.

Теперь создадим новую структуру каталога root (/chroot/httpd):

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/apache/bin
mkdir -p /chroot/httpd/usr/local/apache/logs
mkdir -p /chroot/httpd/usr/local/apache/conf
mkdir -p /chroot/httpd/www

Владельцем вышеперечисленных каталогов должен быть root, и права доступа должны быть 0755. Затем мы создадим специальный файл:
/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, в файл /etc/rc.conf нужно добавить следующую строчку:

syslogd_flags="-l /chroot/httpd/dev/log"

Мы должны перезапустить систему или демон syslogd, чтобы сделанные нами изменения вступили в силу.

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

ldd - Показывает динамическую зависимость исполняемых файлов или общедоступных библиотек.

ktrace/ktruss/kdump (*BSD) - Включает отслеживание вызовов ядра

sotruss (Solaris) - Трассирует вызовы функций из разделяемых библиотек.

strace/ltrace (Linux) - Отслеживает системные вызовы, которые делает программа в процессе своей работы

strings - Позволяет просмотреть в любом (в том числе выполнимом) файле все строки (в коде ASCII)

trace (AIX) - Записывает выбранные системные вызовы

truss (FreeBSD, Solaris, AIX 5L, SCO Unixware) - Трассирует системные вызовы и сигналы

trusc (HP-UX>11) - Трассирует системные вызовы в HP-UX 11


Ниже приведен пример использования команд ldd, strings и truss:

localhost# ldd /usr/local/apache/bin/httpd
/usr/local/apache/bin/httpd:
libcrypt.so.2 => /usr/lib/libcrypt.so.2 (0x280bd000)
libc.so.4 => /usr/lib/libc.so.4 (0x280d6000)

localhost# strings /usr/local/apache/bin/httpd | grep lib
/usr/libexec/ld-elf.so.1
libcrypt.so.2
libc.so.4

localhost# truss /usr/local/apache/bin/httpd | grep open
(...)
open("/var/run/ld-elf.so.hints",0,00) = 3 (0x3)
open("/usr/lib/libcrypt.so.2",0,027757775370) = 3 (0x3)
open("/usr/lib/libc.so.4",0,027757775370) = 3 (0x3)
open("/etc/spwd.db",0,00) = 3 (0x3)
open("/etc/group",0,0666) = 3 (0x3)
open("/usr/local/apache/conf/httpd.conf",0,0666) = 3 (0x3)
(...)

Вышеупомянутые команды должны применяться не только по отношению к httpd, но и ко всем требуемым библиотекам и бинарным файлам. В случае с FreeBSD, следующие файлы должны быть скопированы в новую root директорию:

cp /usr/local/apache/bin/httpd /chroot/httpd/usr/local/apache/bin/
cp /var/run/ld-elf.so.hints /chroot/httpd/var/run/
cp /usr/lib/libcrypt.so.2 /chroot/httpd/usr/lib/
cp /usr/lib/libc.so.4 /chroot/httpd/usr/lib/
cp /usr/libexec/ld-elf.so.1 /chroot/httpd/usr/libexec/

Используя команду truss мы обнаружим, что следующие конфигурационные файлы также должны присутствовать в новой среде:

cp /etc/hosts /chroot/httpd/etc/
cp /etc/host.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
cp /usr/local/apache/conf/mime.types /chroot/httpd/usr/local/apache/conf/

Обратите внимание, что в файле /chroot/httpd/etc/passwords мы должны удалить все строчки кроме "nobody" и "apache". Таким же образом мы
должны удалить все строчки, кроме "apache" и "nogroup" в /chroot/httpd/etc/group. Затем нам нужно создать базу данных паролей:

cd /chroot/httpd/etc
pwd_mkdb -d /chroot/httpd/etc passwords
rm -rf /chroot/httpd/etc/master.passwd

Теперь нам предстоит проверить, правильно ли работает httpd сервер в новой среде. Для этого нам нужно скопировать файл конфигурации Apache и файл index.html, как показано в примере:

cp /usr/local/apache/conf/httpd.conf /chroot/httpd/usr/local/apache/conf/
cp /usr/local/apache/htdocs/index.html.en /chroot/httpd/www/index.html

После окончания копирования вышеупомянутых файлов, мы должны заменить директиву DocumentRoot (в /chroot/httpd/usr/local/apache/conf/httpd.conf):

DocumentRoot "/www"

Теперь мы можем попробовать запустить сервер:

chroot /chroot/httpd /usr/local/apache/bin/httpd

Если появились проблемы, я рекомендую проанализировать log файлы Apache (/chroot/httpd/usr/local/apache/logs). Как альтернативу, вы можете использовать следующую команду:

truss chroot /chroot/httpd /usr/local/apache/bin/httpd

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

Конфигурирование Apache
-----------------------

Для начала, удалите старый /chroot/httpd/usr/local/apache/conf/httpd.conf файл и создайте на его месте новый, примерно со следующим содержанием:

# =================================================
# Basic settings
# =================================================
ServerType standalone
ServerRoot "/usr/local/apache"
PidFile /usr/local/apache/logs/httpd.pid
ScoreBoardFile /usr/local/apache/logs/httpd.scoreboard
ResourceConfig /dev/null
AccessConfig /dev/null

# =================================================
# Performance settings
# =================================================
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
MinSpareServers 5
MaxSpareServers 10
StartServers 5
MaxClients 150
MaxRequestsPerChild 0

# =================================================
# Apache's modules
# =================================================
ClearModuleList
AddModule mod_log_config.c
AddModule mod_mime.c
AddModule mod_dir.c
AddModule mod_access.c
AddModule mod_auth.c

# =================================================
# General settings
# =================================================
Port 80
User apache
Group apache
ServerAdmin Webmaster@www.ebank.lab
UseCanonicalName Off
ServerSignature Off
HostnameLookups Off
ServerTokens Prod

DirectoryIndex index.html

DocumentRoot "/www/vhosts"

# =================================================
# Access control
# =================================================

Options None
AllowOverride None
Order deny,allow
Deny from all


Order allow,deny
Allow from all


Order allow,deny
Allow from all


# =================================================
# MIME encoding
# =================================================

TypesConfig /usr/local/apache/conf/mime.types

DefaultType text/plain

AddEncoding x-compress Z
AddEncoding x-gzip gz tgz
AddType application/x-tar .tgz


# =================================================
# 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/apache/logs/error_log
CustomLog /usr/local/apache/logs/access_log combined

# =================================================
# Virtual hosts
# =================================================
NameVirtualHost *

DocumentRoot "/www/vhosts/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


DocumentRoot "/www/vhosts/www.test.lab"
ServerName "www.test.lab"
ErrorLog logs/www.test.lab/error_log
CustomLog logs/www.test.lab/access_log combined

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

- www.ebank.lab (www.e-bank.lab)
- www.test.lab

Контент вышеупомянутых сайтов находится в следующих каталогах:

- /chroot/httpd/www/vhosts/www.ebank.lab
- /chroot/httpd/www/vhosts/www.test.lab

Каждый сайт имеет собственные log файлы, которые находятся в следующих каталогах:

- /chroot/httpd/usr/local/apache/logs/www.ebank.lab
- /chroot/httpd/usr/local/apache/logs/www.test.lab

Эти каталоги должны быть созданы еще до того, как вы в первый раз запустите Apache - иначе Apache не будет работать корректно.
Владельцем вышеупомянутых каталогов должен быть root:sys, а права доступа должны быть 0755.

По сравнению с настройками по умолчанию, в файле конфигурации Apache были сделаны следующие изменения:

- Число доступных/включенных модулей значительно уменьшен
- Apache не выдает информацию о номере версии (директивы:
ServerTokens, ServerSignature)
- Процессы Apache (за исключением процесса root) выполняются с привилегиями уникального пользователя/группы (директивы: User, Group)

- Apache предоставит доступ только к тем каталогам, подкаталогам и файлам, которые явно прописаны в файле конфигурации
(директивы: Directory, Allow); по умолчанию, все остальные запросы будут отклонены

- Apache записывает гораздо больше информации о HTTP запросах

Последние штрихи
----------------

Теперь мы сделаем скрипт запуска "apache.sh", содержание которого должно выглядеть примерно так:

--------------------------------
#!/bin/sh

CHROOT=/chroot/httpd/
HTTPD=/usr/local/apache/bin/httpd
PIDFILE=/usr/local/apache/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
--------------------------------

Данный скрипт вы должны скопировать в надлежащий каталог (зависит от конкретной UNIX системы), где находятся все скрипты запуска. В случае с FreeBSD это - /usr/local/etc/rc.d каталог.

Резюме
------

Продемонстрированный вам метод позволяет значительно повысить уровень безопасности, по сравнению с теми настройками, которые установлены по умолчанию.

Благодаря отключению ненужных модулей Apache, мы значительно снижаем риск успешного проведения атаки. Скрыв номер версии Apache, выключив службу индексации каталогов, проведя операцию chroot, мы насколько это возможно затруднили проникновение взломщику.

Обновлено: 12.03.2015