Apache: каждому virtual host’y по пользователю.

1) Введение.

Представим, что вы небольшой (или начинающий) хостинг провайдер. У вас наверное используется apache+virtualhosts. И возникает вопрос: как ограничить права пользователей, что бы каждый virtualhost не мог безпредельничать и выполнять действия только от своего пользователя. Обычно, apache работает из-под пользователя www. Предположим, что кто-то из пользователей залил на сайт дырявый скрипт, который в случае чего, может получить (теоретически) доступ к остальным virtualhost’ам ну и сделать с ними всё, что хочеться. Со стороны безопасности это очень плохо. Вот если бы можно было сделать так, что бы все файлы каждого virtualhost’a выполнялись только под своим пользователем. Тогда, даже в случае ошибки в скрипте, он сможет навредить только самому себе. Или например, на хостинг заливают разные пользователи и нужно, что бы каждый мог удалить только свои файлы. О том, как это настроить и пойдёт речь с нашей статье.

На данный момент мне известны следущие методы:

— модуль SuExec + t-бит на папки
— модуль mod_become (http://nixbit.com/cat/internet/nttp-(www)/mod-become/)
— использовать mpm (itk, peruser)
— модуль mod_ruid2 (http://sourceforge.net/projects/mod-ruid/)

Первый предназначен только для запуска скриптов и не совсем универсален, но залитые файлы будут иметь владельца www:www, что не до конца решает проблему. Во-втором случае проект остановился и не развивается. Поэтому, рассмотрю 3-ий случай в 2-х реализациях: itk и peruser.

Стенд: FreeBSD 8.0 Release, apache 2.2.14_5

2)ITK (домашняя страница http://mpm-itk.sesse.net/)

Обновляем порты и переходим в папку с apache’ем:

$cd /usr/ports/www/apache22/files

Проверим, добавлена ли возможность использования itk:

# ls | grep itk
mpm-itk-20090414-00

Видим, что патч присутствует. Если вдруг отсутствует, тогда качаем вручную:

#fetch http://mpm-itk.sesse.net/apache2.2-mpm-itk-20090414-00.patch

Замечу, что на сайте патч будет работать с версиями apache 2.2.6 и выше.
Теперь переходим в /usr/ports/www/apache22, открываем Makefile, ищем строчку «WITH_MPM?=prefork» и меняем prefork на itk. В итоге получится такое:

WITH_MPM?=      itk

После этого ставим apache:

#make install clean

Если всё правильно и без ошибок, то в конце увидим такую строчку

===>  Cleaning for apache-itk-2.2.14_5

что означает, что у нас всё-таки не обычный apache, а именно, с поддержкой itk. Для проверки можно так же использовать один из способов, приведённых ниже:

а) $apachectl -l | grep itk
itk.c

б) $httpd -V | grep -i mpm
Server MPM:     ITK
-D APACHE_MPM_DIR="server/mpm/experimental/itk"

Если вывод не пустой — значит, всё впорядке. Теперь переходим непосредственно к настройке. Открываем файл httpd.conf и расскоментируем следующие строчки (если они у вас ранее не добавлены или расскоментированы): первая включает возможность использования mpm, вторая — описывает файл с virtualhost’ами:

Include etc/apache22/extra/httpd-mpm.conf
Include etc/apache22/extra/httpd-vhosts.conf

Для указания пользователя и группы используем параметр AssignUserID. Вот как это выглядит на примере:

NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@srv.com
DocumentRoot "/usr/local/www/apache22/data"
ServerName mainsite.com
ErrorLog "/var/log/httpd-error.log"
CustomLog "/var/log/httpd-access.log" common
AssignUserID www www
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@srv1.com
DocumentRoot "/usr/local/www/srv1"
ServerName srv1.com
ErrorLog "/var/log/srv1.com.err"
CustomLog "/var/log/srv1.com.log" common
AssignUserID srv1 www
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@srv2.com
DocumentRoot "/usr/local/www/srv2"
ServerName srv2.com
ErrorLog "/var/log/srv2.com.err"
CustomLog "/var/log/srv2.com.log" common
AssignUserID srv2 www
</VirtualHost>

Примечание.

Что бы добавить эту возможность в ISPmanager, в конфигурационном файле добавьие опцию для работы с Apache MPM:

Option ApacheMPM

В DirectAdmin в Templates необходимо подправить скрипты создания файла httpd.conf. Также, необходимо добавить загрузку дополнительных модулей с родного конфиг-файла

3)Peruser (официальный сайт http://www.peruser.org/trac/peruser)

Идём в каталог порта с apach’ем (/usr/ports/www/apache22), открываем Makefile, ищем строчку WITH_MPM? и ставим параметр peruser:

WITH_MPM?=peruser

Здесь нас ждёт сюрприз: в портах уже есть порт с названием apache22-peruser-mpm, который как раз и предназначен для этого. Ну что ж, переходи в каталог и ставим:

# cd /usr/ports/www/apache22-peruser-mpm/
# make install clean

Если вдруг у вас вылезла такая ошибка:

===>  apache-peruser-2.2.14_5 Sorry,  and apache versions are out of sync.
*** Error code 1
Stop in /usr/ports/www/apache22-peruser-mpm.

то открываем файл Makefile и подправляем релиз apache’а на тот, который содержится в портах. У меня, например, версия apach’a была 2.2.14_5, а в Makefile порта apache22-peruser-mpm была указана версия 2.2.13. Собственно изменил

SLAVE_DESIGNED_FOR=     2.2.13

на

SLAVE_DESIGNED_FOR=     2.2.14

После этого пробуем запустить установку ещё раз. После установки проверяем поддержку (одним из способов, можно и обеими):

$apachectl -l | grep peruser
peruser.c
$httpd -V | grep -i mpm
Server MPM:     Peruser
-D APACHE_MPM_DIR="server/mpm/experimental/peruser"

Теперь переходим непосредственно к настройке. Открываем файл httpd.conf и добавляем следующее:

<IfModule peruser.c>
# Multiplexer pool
MinMultiplexers 3
MaxMultiplexers 20
Multiplexer www www
ProcessorWaitTimeout 2 10
# Fork limits
ServerLimit 20
MaxClients 20
MaxRequestsPerChild 1000
# Processor defaults
MinProcessors       0
MinSpareProcessors  3
MaxProcessors       10
# Timeouts
IdleTimeout 60
ExpireTimeout 300
<Processor srv1>
User srv1
Group www
</Processor>
<Processor srv2>
User srv2
Group www
</Processor>
</IfModule>
Include etc/apache22/extra/httpd-vhosts.conf

Вот пример моего httpd-vhosts.conf:

<VirtualHost *:80>
ServerAdmin webmaster@srv1.com
DocumentRoot "/usr/local/www/srv1"
ServerName srv1.com
ErrorLog "/var/log/srv1.com.err"
CustomLog "/var/log/srv1.com.log" common
<IfModule peruser.c>
ServerEnvironment srv1
</IfModule>
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@srv2.com
DocumentRoot "/usr/local/www/srv2"
ServerName srv2.com
ErrorLog "/var/log/srv2.com.err"
CustomLog "/var/log/srv2.com.log" common
<IfModule peruser.c>
ServerEnvironment srv2
</IfModule>
</VirtualHost>

Насколько понятно из пример, за работу модуля отвечает директива <IfModule peruser.c>

Примечание.

Как пишут в сети, могут наблюдаться  проблемы при работе этого модуля на FreeBSD.

Опубликовано с разрешения журнала root.ua

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *