Сажаем индейца в вигвам

Сажаем индейца в вигвам

В данной статье речь пойдет о веб-серверах apache, работающих под управлением UNIX-подобных операционных систем. Я расскажу о истории внедрения технологии, позволяющей ограничивать каждый веб-сайт внутри его собственного “chroot”-окружения.

Честно говоря это моя первая статья, поэтому прошу не судить строго за стилистические ляпы и прочие “детcкие болезни”.

В данной статье речь пойдет о веб-серверах apache, работающих под управлением UNIX-подобных операционных систем. Я расскажу о истории внедрения технологии, позволяющей ограничивать каждый веб-сайт внутри его собственного “chroot”-окружения.

Я думаю каждый веб-администратор хоть раз в жизни сталкивался с тем, что удаленный взломщик находил дыру в каком-либо веб-приложении и начинал “хозяйничать” на сервере. Последствия при этом могут быть достаточно разные: от перезаписи индексного файла веб-сайта, до попытки повышения привелегий в операционной системе путем загрузки и запуска локального эксплоита.

Для того чтобы понять в какую сторону нам двигаться попробуем рассмотреть более подробно как работает apache и для большей наглядности возьмем простейший пример конфигурации виртуального хоста.

<VirtualHost a.b.c.d>
ServerName superserver
DocumentRoot /var/www/vhosts/superserver/htdocs
ScriptAlias /cgi-bin /var/www/vhosts/superverver/cgi-bin
</VirtualHost>


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

пока (ждем запросов от пользователей) {
…..
какой-то код
…..
если (получили запрос к веб-сайту) {
переходим в директорию соответствующую DocumentRoot
}
……
дальнейшая обработка запроса
……
}

Конечно настоящий код намного сложнее но общую идею он передает.

Все работает хорошо до тех пор пока контент веб-сайта является статическим. Проблемы начинаются сразу как только сервер начинает обслуживать “скриптовый” контент. Если вспомнить историю создания apache то становится понятным почему apache не содержит достаточных средств для обеспечения безопасности веб-сайта. В те времена самым распространенным скриптовым языком для веба был perl для которого был создан индивидуальный костыль под названием “suexec”.


Мы начали работать над проблемой путем анализа возможных действий взломщика после того как он произвел проникновение через “дырявое” веб-приложение. Обычно взломщик пытается осмотреться на скомпроментированной системе. Невозможность выполнения задуманного обычно дает свои плоды – взломщик уходит “не солоно хлебавши”. Чем-же можно ограничить “радиус” действия рук потенциального хакера? Первое что напрашивается в голову это создание “chroot”-окружения всего веб-сервера с необходимым набором библиотек и собственно веб-сайтом.

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

Попробуем описать работу веб-сервера с учетом описанной технологии.

пока (ждем запросов от пользователей) {
…..
какой-то код
…..
если (получили запрос к веб-сайту) {
переходим в директорию соответствующую DocumentRoot
делаем chroot в новый корень веб-сайта
меняем uid и gid нашего процесса на uid/gid хозяина обрабатываемого файла
}
……
дальнейшая обработка запроса
……
}


Тут необходимо некоторое пояснение. В качестве дополнительной меры безопасности мы также меняем идентификатор процесса-обработчика т.е. фактически эмулируем работу suexec. Это также позволяет более точно определять нагрузку создаваемую тем или иным веб-сайтом на сервера, т.к. процесс-обработчик работает не от единого пользователя, а от пользователя-хозяина конкретного файла.

Таким образом файл конфигурации виртуального веб-сайта приобретает следующий вид:

<VirtualHost a.b.c.d>
ServerName superserver
DocumentChroot /var/www/vhosts/superserver
DocumentRoot /htdocs
ScriptAlias /cgi-bin /cgi-bin
</VirtualHost>


Как вы заметили мы добавили новую apache-дериктиву – DocumentChroot, которая являеься указателем на диреткорию, в которую должен выполняться системный вызов chroot. Так-как мы создаем новый корень веб-сайта, то необходимо не забыть создать в директории /var/www/vhosts/superserver поддиректории etc, dev, tmp, usr.
На каталог tmp необходимо установить “sticky-bit” командой chmod +t tmp.
В dev необходимо скопировать специальный файл null из /dev/.
В etc необходимо положить resolv.conf, hosts, passwd и group.

На данном этапе разработки мы столкнулись с проблем невозможности отрабатывания системных вызовов chroot, setuid и setgid от имени пользователя веб-сервера. Данные вызовы могут выполняться только пользоватлеме, с установленными системными флагами CAP_CHROOT, CAP_SETUID, CAP_SETGID, которые в стандартной UNIX-подобной операционной системе может иметь только суперпользователь root. То есть необходимо чтобы веб-сервер выполнялся от root’а, что нас несколько не устраивало по вполне понятным причнам. После долгих поисков был найден модуль erup (http://www.wijata.com/software/index.php?mus=7). Этот модуль позволяет устанавливать системные флаги таким образом, чтобы пользователь мог выполнять некоторые привелигированные операции, доступные только суперпользователю. После установки модуля, был создан следующий скрипт инициализации.

erupmgr add user www-data 10000 65534
erupmgr add group www-data 10000 65534
erupmgr add groups www-data 0 1
erupmgr add chr www-data /var/www


после выполнения этого скрипта пользователь www-data имеет возможность менять свой uid/gid в пределах 10000-65534 которые соответственно выдаются пользовательским сайтам, менять свои дополнительные группы, а также делать системный вызов chroot везде в пределах /var/www.

У пытливого читателя наверняка к этому месту уже возник вопрос – А как-же быть с PEAR/Perl –модулями для PHP/CGI (или вставьте свое в зависимости от ваших сексуальных предпочтений в области написания веб-скриптов J). Все верно. В своем собственном виртуальном окружении веб-сайт не имеет никаких дополнительных библиотек. Делать для каждого веб-сайта отдельную копию Pear/Perl -модулей является достаточно расточительным с точки зрения дисковых ресурсов, да и в случае обновления какого-либо из модулей администратор рискует долгими зимними вечерами накатывать обновления для каждого веб-сайта. И здесь было найдено достаточно простое решение.
Был создан файл в котором создана полноценная файловая система при помощи следующего набора команд:

dd if=/dev/zero of=fs.ext2 bs=1048576 count=64
mkfs -t ext2 -m 0 ./fs.ext2
tune2fs -c -1 -r 0 -O dir_index,sparse_super -L ext2 ./fs.ext2
e2fsck -f ./fs.ext2


после этого файл был смонтирован во временную папку /mnt/tmp и туда были скопированы все необходимые библиотеки и модули. Создавать папки и файлы при этом нужно таким образом, чтобы этот файл в дальнейшем можно было монтировать в usr каждого из виртуальных веб-сайтов. После того как все файлы собраны, fs.ext2 монтируется следующей командой:

mount –o loop,ro,noatime,nosuid –t ext2 fs.ext2 /var/www/mount_usr

и после этого для каждого из виртуальных веб-сайтов выполняем команду:

mount –bind /var/www/mount_usr /var/www/vhosts/superserver/usr

эта команда выполняет не настоящий mount а просто делает связку одной директории с другой и в итоге в директории /var/www/vhosts/SITE/usr содержатся данные находящиеся в /var/www/mount_usr. Тут возникает вопрос – а почему-бы не монтировать сразу наш файл для каждого веб-сайта в usr. Нам кажется такой вариант более удобным, с точки зрения более централизованного управления изменениями в файле fs.ext2. Еще хотелось-бы обратить ваше внимание на одну особенность - мы монтируем fs.ext2 в /var/www/mount_usr с флагом ro (ReadOnly) – т.е. в режиме только для чтения. Это является защитой от случайного удаления так тщательно собранных модулей при удалении всего виртуального веб-сайта.

После некоторого тестового периода был создан патч позволяющий выполнять chroot, setuid и setgid для каждого отдельного веб-сайта для apache 1.3. Для apache 2.0 был создан полноценный модуль. Моку сказать что данная технология используется нашей компанией в течении двух лет и пока показала себя только с лучшей стороны. Буквально несколько месяцев назад мы завершили полную интеграцию вышеописанной технологии
с одной достаточно известной панелью управления хостингом. Таким образом наш подход позволяет не только сэкономить существеггые средства, которые могли быть потрачены на покупку ПО, реализовывающего VPS-решение, но и создать более защищенный веб-сервер.

Компания SoftKey – это уникальный сервис для покупателей, разработчиков, дилеров и аффилиат–партнеров. Кроме того, это один из лучших Интернет-магазинов ПО в России, Украине, Казахстане, который предлагает покупателям широкий ассортимент, множество способов оплаты, оперативную (часто мгновенную) обработку заказа, отслеживание процесса выполнения заказа в персональном разделе.


Roman Hlynovskiy 
 

 

Если вам нравится играть в опасную игру, присоединитесь к нам - мы научим вас правилам!

Подписаться