Информационная безопасность


Практический пример: Apache


Наверное, один из наиболее часто помещаемых в CE сервисов - веб-сервер Apache. Про это много написано и под разными углами, но я все же рискну повториться. Рассмотрим пошагово перенос в CE программной связки Apache 1.3.x + PHP 5 с учетом взаимодействия с СУБД MySQL (классический комплекс, именуемый в народе "LAMP" - Linux + Apache + MySQL + PHP). В примере предполагается, что мы имеем дело с дистрибутивной сборкой Apache в Slackware (для вашей системы файлы могут быть расположены немного по-другому, но принцип должен быть понятен).

Вот скрипт для автоматизированного создания CE: #!/bin/sh # create chrooted environment for Apache 1.3 + PHP 5 # Den aka Diesel <diesel@sherdart.net>

PREFIX=/chroot/httpd APACHE_PREFIX=/usr PHP_PREFIX=/usr APACHE_DATADIR=/var/www

# создаем структуру каталогов:

mkdir -p $PREFIX mkdir -p $PREFIX/dev mkdir -p $PREFIX/etc mkdir -p $PREFIX/lib mkdir -p $PREFIX/tmp mkdir -p $PREFIX/var/cache/proxy mkdir -p $PREFIX/var/run mkdir -p $PREFIX/$APACHE_PREFIX/bin mkdir -p $PREFIX/$APACHE_PREFIX/lib mkdir -p $PREFIX/$APACHE_PREFIX/sbin mkdir -p $PREFIX/$APACHE_PREFIX/libexec mkdir -p $PREFIX/var/log/apache mkdir -p $PREFIX/var/run/mysql mkdir -p $PREFIX/$PHP_PREFIX/lib/php mkdir -p $PREFIX/home

# выставляем 'sticky bit' на /tmp:

chmod 1777 $PREFIX/tmp

# создаем файл устройства /dev/null:

mknod $PREFIX/dev/null c 1 3 chmod 666 $PREFIX/dev/null chown root:sys $PREFIX/dev/null

# копируем конфигурационные файлы:

cat /etc/group|egrep "apache:|nobody:|nogroup:" > $PREFIX/etc/group cat /etc/passwd|egrep "apache:|nobody:" > $PREFIX/etc/passwd cat /etc/shadow|egrep "apache:|nobody:" > $PREFIX/etc/shadow chmod 640 $PREFIX/etc/shadow cp /etc/HOSTNAME $PREFIX/etc cp /etc/host.conf $PREFIX/etc cp /etc/hosts $PREFIX/etc cp /etc/nsswitch.conf $PREFIX/etc cp /etc/resolv.conf $PREFIX/etc cp /etc/localtime $PREFIX/etc cp -R /etc/apache $PREFIX/etc

# копируем данные и лог-файлы:

cp -R $APACHE_DATADIR $PREFIX`dirname $APACHE_DATADIR` cp -R /var/log/apache $PREFIX/var/log


# копируем бинарные файлы:

cp $APACHE_PREFIX/bin/htdigest $PREFIX/$APACHE_PREFIX/bin cp $APACHE_PREFIX/bin/mm-config $PREFIX/$APACHE_PREFIX/bin cp $APACHE_PREFIX/bin/htpasswd $PREFIX/$APACHE_PREFIX/bin cp $APACHE_PREFIX/bin/checkgid $PREFIX/$APACHE_PREFIX/bin cp $APACHE_PREFIX/bin/dbmmanage $PREFIX/$APACHE_PREFIX/bin cp $APACHE_PREFIX/sbin/ab $PREFIX/$APACHE_PREFIX/sbin cp $APACHE_PREFIX/sbin/apxs $PREFIX/$APACHE_PREFIX/sbin cp $APACHE_PREFIX/sbin/httpd $PREFIX/$APACHE_PREFIX/sbin cp $APACHE_PREFIX/sbin/logresolve $PREFIX/$APACHE_PREFIX/sbin cp $APACHE_PREFIX/sbin/rotatelogs $PREFIX/$APACHE_PREFIX/sbin cp $APACHE_PREFIX/sbin/apachectl-standard $PREFIX/$APACHE_PREFIX/sbin cp $APACHE_PREFIX/sbin/apacheconfig $PREFIX/$APACHE_PREFIX/sbin cp -R $APACHE_PREFIX/libexec/apache $PREFIX/$APACHE_PREFIX/libexec

# копируем библиотеки:

for BINARY in "$APACHE_PREFIX/sbin/httpd $APACHE_PREFIX/libexec/apache/libphp5.so $APACHE_PREFIX/lib/php/extensions/mysql.so"; do for i in `ldd $BINARY|awk '{print $3}'`; do d=$(dirname $i) if [[ $d != .* ]]; then mkdir -p $PREFIX$d; fi if [[ $d != .* ]]; then cp $i $PREFIX$d; fi done done cp -d /lib/libnss_compat* $PREFIX/lib cp -d /lib/libnss_dns* $PREFIX/lib cp -d /lib/ld-* $PREFIX/lib cp -d /lib/libnsl* $PREFIX/lib cp -R -d /usr/lib/gconv $PREFIX/usr/lib cp -R $PHP_PREFIX/lib/php $PREFIX/$PHP_PREFIX/lib cp -d -R /usr/lib/locale/en_GB $PREFIX/usr/lib/locale cp -d -R /usr/lib/locale/en_GB.utf8 $PREFIX/usr/lib/locale cp -d -R /usr/lib/locale/ru_RU $PREFIX/usr/lib/locale cp -d -R /usr/lib/locale/ru_RU.koi8r $PREFIX/usr/lib/locale cp -d -R /usr/lib/locale/ru_RU.utf8 $PREFIX/usr/lib/locale

Обратите внимание на несколько моментов:


  • из /etc/passwd мы взяли только записи про apache, nobody, nogroup (не стоит подвергать информацию о других учетных записях опасности быть украденой при взломе этого конкретного сервиса, исключение составляет только ситуация с использованием ~/public_html/)
  • не забывайте про /etc/localtime, если хотите, чтобы сервис жил с вами в одной временной зоне
  • по-минимуму можно было не копировать все бинарные файлы Apache, а обойтись только httpd





  • обвязка ldd в этом скрипте сделана на скорую руку (однако работает в подавляющем большинстве случаев) - имя какой-нибудь библиотеки, нестандартно выведенной, может не захватиться в переменную
  • не забывайте про /etc/nsswitch.conf и resolv.conf при помещении в CE сетевых сервисов
  • также не забывайте про библиотеки libnss, libnss_dns и libnsl
  • при желании уменьшить объем, занимаемый библиотеками и исполняемыми бинарными файлами - после копирования и тестирования работоспособности CE сделайте им strip

  • файлы из /usr/lib/gconv и /usr/lib/locale нужны для корректной работы с локалями, отличными от английской (C) - без этих файлов, например, русские буквы не будут восприниматься как корректные символы алфавита, что может сказаться на работе регулярных выражений в PHP
  • некоторым сервисам может требоваться не только файл устройства /dev/null, но и /dev/random вместе с /dev/urandom (например, для того же BIND - иначе у него не работают корректно функции шифрования)
  • если вам для работы каких-нибудь CGI-скриптов необходим PERL, его так же необходимо поместить в CE, не забыв про /usr/lib/perl5

  • учтите, что если вы не предпримете никаких дополнительных мер, PHP функция mail() не будет работать в CE, т.к. она пытается вызвать бинарный файл SMTP-клиента, который отсутствует в CE (в интернете описаны методы обхода этого с использованием модулей из репозитария PEAR)
  • не пренебрегайте возможностью установить (с помощью утилиты chattr) флаг иммунитета к изменениям (immutable) для важных файлов, которые не должны меняться в ходе работы - например, для конфигурационных файлов


  • Возможно, есть еще какие-то тонкости, однако я в своей практике с ними не сталкивался, и поэтому написать ничего про них не могу. Помещение MySQL в CE производится аналогично, никаких особых подводных камней там нет, помимо уже описанных.


    Содержание раздела