Apache + SuExec + PHP (ServerAPI as CGI/FastCGI) | Выделенный сервер своими руками

Apache + SuExec + PHP (ServerAPI as CGI/FastCGI)

Сегодня в этой заметке хочу рассказать Вам о том, что же все-таки такое SuExec, зачем он нужен и как его установить на web-сервер в Linux системе.

Не смотря на то, что интернет кишит множеством материалов по SuExec, о том как его ставить и какими способами, все же возникает множество вопросов начиная от корректности способов установки и его настройки до, почему же все в итоге не работает? Или работает но не так как надо?

Прежде чем я начну говорить о SuExec, позвольте мне некоторое уточняющее отступление, которое поможет Вам в дальнейшем сориентировать именно Вас (как это ни странно) в какой же вы все-таки ОС собираетесь устанавливать и настраивать SuExec, другими словами, подходит ли вам тот или иной способ, найденный вами в интернете, для вашей операционной системы? Вот тут-то самое интересное.
Найдя интересующий вас способ вы начинаете пробовать делать все как описано в нем и у вас что-то начинает идти не так практически сразу по причине простейшего отсутствия в вашей ОС тех команд которые описаны в способе... Все просто. Дело в том, что найденный Вами пример применим только для одного, максимум 3 видам ОС Linux. Какому именно? Далее, для этой статьи это будет уже не суть важно, потому что в данной статье я хочу предложить универсальный пример/способ, который подойдет к подавляющему большинству ОС Linux. Панацея? Возможно, да... В любом случае для начинающего интересоваться ОС Linux человека, мне кажется, эта статья будет крайне полезной.

Итак приступим: Что же такое SuExec и для чего он НЕ нужен?
Прежде чем принять решение об установке и приступить к настройке SuExec задайте себе вопрос: "А для чего я это делаю?". Есть несколько вариантов ответа:
1. Нужно повысить безопасность web-сервера Apache, потому что у меня присутствуют в системе виртуальные веб-серверы с несколькими доменами, ссылающимися на них. (ок - эта статья для вас)
2. Просто говорят, что это полезная штука и ее надо иметь в установленном/активизированном виде на web-сервере Apache, вот и хочу установить чтобы повысить безопасность одной странички на моем веб-сервере. (Думаю, в данном случае, модуль suExec Вам просто НЕ нужен и нет смысла его ставить).
3. Для самообразования, чтобы понять какие плюсы можно получить и какие минусы нужно учесть после установки этого модуля на многодоменный web-сервер. (Добро пожаловать в статью, думаю материал изложенный тут будет вам наиболее полезен).

Если вы все-таки решили устанавливать этот модуль, то продолжаем.

Далее. Какие версии Apache и PHP я использую в этой статье?
Apache/2.2.19 (Unix)
PHP Version 5.3.6
Итого имею: SERVER_SOFTWARE Apache/2.2.19 (Unix) DAV/2 PHP/5.3.6

Какую версию OC Linux я использую?:
Для данной статьи это не суть важно, но если вам все-же интересно то пожалуйста:
System - Linux AtomLinux 2.6.39.3 x86_64
Мне кажется это вам мало что сказало - потому что в своей работе я использую свой "респин" с данным ему мной названием "Atom" от версий linux Slackware и Mops/Agilia (http://agilialinux.ru/) - я просто привык от линукса брать только то что мне нужно под конкретные, нужные только мне, задачи и более ничего лишнего.

Но продолжим. Далее я буду рассматривать два варианта развития событий:
1. Web-сервер Apache и PHP у Вас еще НЕ установлены в системе и Вы планируете настройку с нуля.
2. Web-сервер Apache и PHP у Вас уже установлен и они обслуживают 2 или более доменов.

Итак, самое главное! Что же такое SuExec?

SuExec - это модуль web-сервера Apache, который позволяет запускать CGI и аналогичные собственные или сторонних разработчиков скрипты/программы внутри веб-папки домена от имени вполне конкретного пользователя (которому данная папка/домен принадлежат) а не от пользователя/группы от имени которого работает непосредственно сам Apache web-сервер.

Пример-пояснение (частный случай):

Допустим мы имеем.
1. Web-сервер Apache, сервис которого запускается от пользователь:группа apache:apache
2. PHP - языковой пакет
3. домен www.domain1.ru - папка на сервере для него /vhost/domain1
4. домен www.domain2.ru - папка на сервере для него /vhost/domain2
5. содержимое папок domain1 и domain2 имеет следующий вид:

для domain1.ru
root@AtomLinux:/vhost/domain1# ls -l
итого 16
dr-xr-x--- 2 domain1 domain1 4096 Июл 31 07:09 cgi-bin/
drwxr-x--- 2 domain1 domain1 4096 Июл 31 07:07 ftp/
drwxr-x--- 2 domain1 domain1 4096 Авг 4 01:43 logs/
drwxr-x--- 2 domain1 domain1 4096 Июл 31 07:12 www/
root@AtomLinux:/vhost/domain1#

для domain2.ru
root@AtomLinux:/vhost/domain2# ls -l
итого 16
dr-xr-x--- 2 domain2 domain2 4096 Июл 31 07:09 cgi-bin/
drwxr-x--- 2 domain2 domain2 4096 Июл 31 07:07 ftp/
drwxr-x--- 2 domain2 domain2 4096 Авг 4 01:43 logs/
drwxr-x--- 2 domain2 domain2 4096 Июл 31 07:12 www/
root@AtomLinux:/vhost/domain2#

Мы видим что на сравнении эти две папки практически идентичны, НО пользователь и его группа отличаются.
Теперь перейдем в папку ./www каждого домена и сравним еще раз:

для domain1.ru
root@AtomLinux:/vhost/domain1/www# ls -l
итого 4
-rwxr-x--- 1 domain1 domain1 19 Июл 27 16:41 php.php*
root@AtomLinux:/vhost/domain1/www#

для domain2.ru
root@AtomLinux:/vhost/domain2/www# ls -l
итого 4
-rwxr-x--- 1 domain2 domain2 19 Июл 27 16:41 php.php*
root@AtomLinux:/vhost/domain2/www#

И там и там присутствует файл php.php - он имеет внутри простой код вызова полного описания настроек php для домена к которому он относится.
-rwxr-x--- 1 domain1 domain1 19 Июл 27 16:41 php.php*
-rwxr-x--- 1 domain2 domain2 19 Июл 27 16:41 php.php*

Внимание стоит обратить на то, что что им присвоены разные пользователь и группа.
Так вот, если мы скопируем файл php.php из директории /vhost/domain1/www в директорию /vhost/domain2/www и дадим ему название php1.php (-rwxr-x--- 1 domain1 domain1 19 Июл 27 16:41 php1.php*) и попробуем его запустить через браузер, то получим ответ от сервера Apache "Access Denied" - попросту получим ошибку #403 - отказ в доступе. Одновременно с этим, файл с названием php.php (-rwxr-x--- 1 domain2 domain2 19 Июл 27 16:41 php.php*) будет также продолжать благополучно выполнять возложенную на него задачу. Файл php1.php не запустился потому что этот файл не принадлежит пользователю "domain2" группы "domain2" и файл является чужеродным для данного домена и обрабатываться не будет.
Если мы проделаем все наоборот, то получим такую же картину.
Также хочу обратить Ваше внимание на то, что если мы попытаемся из созданного скрипта в папке /vhost/domain1/www произвести какие либо изменения в папке /vhost/domain2/www - то мы так же получим сообщение от системы о том, что в доступе отказано.

Вы уже обратили внимание на то что имена пользователей и их группы отличаются у папок разных доменов (и их содержимого) и как-бы не имеют ничего общего с сервисом Apache? Однако это не совсем так. Давайте заглянем в

файлик group (/etc/group):

domain1:x:2006:apache
domain2:x:2007:apache

и файлик (/etc/passwd):

domain1:x:2006:2006::/vhost/domain1:/bin/bash
domain2:x:2007:2007::/vhost/domain2:/bin/bash

И тут становится понятно, что пользователь apache включен в группу этих доменов "domain1" и "domain2". Если мы уберем пользователя apache из любой из этих групп, то тот домен который входит в эту группу просто перестанет обрабатываться сервисом Apache. Таким образом можно "отключить" домен от сервиса выполнив простую команду (gpasswd -d apache domain1 или gpasswd -d apache domain2) удалив пользователя apache из соответствующих групп. Но это не всегда правильно, потому не стоит увлекаться этим приемом, я привел его для наглядности.

Как мы видим из всего вышеперечисленного, SuExec это модуль который позволяет Web-серверу Apache существенно повысить безопасность как виртуальных хостов системы так и коренного домена. Это далеко не весь его функционал, но чаще всего его ставят именно из этих соображений.
ВНИМАНИЕ! Неверная настройка модуля SuEXEC может не только решить ваши текущие проблемы но и СУЩЕСТВЕННО навредить безопасности наделав еще больше дыр. Так что будьте в достаточной степени внимательными при его установке.

Теперь, собственно, приступим к самой установке модуля SuExec для web-сервера Apache.
Что нам потребуется:
1. Сам компьютер с установленной ОС Linux
2. Пакет Apache. Взять его можно тут: http://mirror.metrocast.net/apache//httpd/. Поскольку я использую версию 2.2.19, то мне понадобится пакет httpd-2.2.19.tar.gz. Устанавливать мы будем, естественно, из исходников, потому и выбран этот вид пакета.
3. Пакет PHP. Взять его можно тут: http://www.php.net/get/php-5.3.6.tar.gz/from/a/mirror. Как вы возможно вы правильно обратили внимание, PHP мы тоже будем собирать из исходников.

Ну что же, приступим:

Для того чтобы во время установки включить опцию SuExec нам надо кое что добавить в строку конфигуратора. Взглянем более детально.
В документации по установке Apache сказано, что для того чтобы установить web-сервер Apache проделайте следующую последовательность команд:

gzip -d httpd-NN.tar.gz - достаем из архива #1
tar xvf httpd-NN.tar - достаем из архива #2
cd httpd-NN - переходим в директорию после разархивирования
./configure --prefix=PREFIX - конфигурируем
make - готовим сконфигурированный вариант установки
make install - устанавливаем подготовленную конфигурацию
vi PREFIX/conf/httpd.conf - редактируем конфигурационные файлы Apache
PREFIX/bin/apachectl -k start - запускаем сам Apachе, ничего сложного! Все просто и понятно.

Теперь обратим внимание на "./configure --prefix=PREFIX" - что же такое префикс? А это ни что иное как место на диске сервера куда сам Apache будет установлен. Как видите, для того чтобы установить Apache, минимум что ему нужно, так это указать папку куда ему себя надо будет "прописать", установить и "привязать".
НО.. есть одно "НО"... нам нужен SuExec!! Если мы установим Apache таким образом, то мы не получим вместе с ним установленный модуль SuExec. Почему? А потому что SuExec идет как "опция". Помните я говорил, что если у вас всего один домен или несколько доменов, которые вы используете для себя и только для себя (в своих личных целях, да мало-ли чего), когда не требуется обезопасить один домен от другого, то не стоит устанавливать модуль SuExec. Именно по этой причине разработчики Apache не включили поддержку SuExec в конфигурацию по-умолчанию.

Итак, для того что бы установился модуль "suexec", нам необходимо понимать ТО, что мы будем делать дальше. У модуля первоначальной настройки Apache перед непосредственной установкой, есть вспомогательные ключи.. да-да и они нам очень помогут сейчас. Полный перечень ключей вы можете лицезреть тут: http://httpd.apache.org/docs/2.2/programs/configure.html. Смотрим внимательно... еще внимательнее... и "та-да-м!!" видим заветное "--enable-suexec". Но, увы - этого будет недостаточно.. потому рассмотрим этот этап более детально.

Итак, поскольку эта статья относится к решению вопроса по установке модуля SuExec для web-сервера Apache, то я приведу все ключи конфигурации тут и объясню их подробно, нормальным человеческим языком. Итак:

suEXEC configuration options

--enable-suexec
Как мы уже понимаем, эта опция включает поддержку suEXEC которая не включена в конфигурацию Apache по-умолчанию. Для того чтобы suexec заработал, должна быть указана по меньше мере одна опция вида "--with-suexec-xxxxx" вместе с "--enable-suexec".
--with-suexec-bin=PATH
Поскольку сам SuExec состоит из двух частей, то этой опцией мы указываем путь к создаваемому бинарному файлу suexec, туда где он должен быть расположен. Эту опцию использовать не обязательно, потому что в случае, если вы ее не укажете то конфигуратор Apache подставит значение по-умолчанию "--with-suexec-bin=/usr/sbin/suexec". Рекомендуется использовать это значение, но абсолютно не произойдет ничего страшного, если вы укажете свой путь, если вы захотите его изменить в целях безопасности.
--with-suexec-caller=UID
В этой опции надо будет указать конфигуратору, под каким пользователем запускается сам сервис Apache. Это должен быть только и именно этот пользователь (которого вы укажете), потому что, в том случае, если вы его потом смените в конфигурационном фале после установки, возможно, при последующем перезапуске сервиса Apache, сервис просто не поднимется, а функции SuExec перестанут работать совершенно точно.
--with-suexec-userdir=DIR
Тут надо указать где находится директория в которой suexec будет иметь право выполнять скрипты/программы пользователя домена. Значением по-умолчанию является "public_html". Но если у вас в качестве этой папки планируется какая-то другая с другим именем, ее необходимо тут указать. В том случае, если вы используете в Apache структуру виртуальных доменов/хостов с указанием различных папок пользователей для каждого пользователя, вам нужно определить/поместить эти папки в одну общую и указать имя общей папки в этой опции. Если, в этом случае, вы этого не сделаете, то опция Apache при вызове папки пользователя вида "~userdir" и cgi запросов, работать не будет!
--with-suexec-docroot=DIR
В этой опции надо определить корневую папку для устанавливаемого Apache. Эта папка используется для определения окружения в котором может работать SuExec. По-умолчанию эта директория принимает значение от опции --datadir и добавляет значение "/htdocs", например, если Apache сконфигурирован со значением опции "--datadir=/home/apache", то "/home/apache/htdocs" будет использоваться как корневая папка для окружения SuExec.
--with-suexec-uidmin=UID
Ну тут самое интересное. В SuExec есть очень хороший механизм, отсекания нежелательных пользователей для использования их в работе web-сервера Apache. В данной опции нужно указать минимальное значение UID (в цифрах) пользователей, ниже которым SuExec будет запрещать работать с папками/файлами пользователей посредством web-сервиса Apache. Очень удобно в том случае если вы хотите отделить/оградить/скомпоновать служебных пользователей отдельно от пользователей сервиса Apache. Если эта опция не указывается то данному элементу присваивается значение по-умолчанию равное 100.
--with-suexec-gidmin=GID
Тут все тоже самое что и с пользователями, только относится к группам пользователей. Если эта опция не указывается то данному элементу присваивается значение по-умолчанию равное 100.
--with-suexec-logfile=FILE
В этой опции, все, думаю, и так понятно. Тут мы указываем имя файла, куда будет записываться отчет о работе SuExec (операции, ошибки и пр.). По-умолчанию файлу назначается имя "suexec_log", а путь к нему указывается в опции конфигуратора Apache "--logfiledir".
--with-suexec-safepath=PATH
Тут мы указываем путь к безопасному окружению для выполнения CGI. Значение по-умолчанию "/usr/local/bin:/usr/bin:/bin". Практика показала, его лучше не трогать.

Вот и все ключи по Suexec :)

Теперь давайте сконфигурируем Apache:

./configure --prefix=/usr --with-apxs2=/usr/sbin/apxs --enable-suexec --with-suexec-bin=/usr/sbin/suexec --with-suexec-caller=apache --with-suexec-userdir=/www --with-suexec-docroot=/vhost --with-suexec-uidmin=2000 --with-suexec-gidmin=2000

Как видно из примера, мы указали "--prefix=/usr" и опции для suexec (--enable-suexec --with-suexec-bin=/usr/sbin/suexec --with-suexec-caller=apache --with-suexec-userdir=/www --with-suexec-docroot=/vhost --with-suexec-uidmin=2000 --with-suexec-gidmin=2000). Но я так же добавил "--with-apxs2=/usr/sbin/apxs", для чего, вы спросите? Как я говорил ранее, suexec состоит из 2 частей.. первую мы указали в опциях "--enable-suexec" - тут создается бинарный файл "suexec" который кладется в папку "/usr/sbin/" указанную в ключе "--with-suexec-bin=/usr/sbin/suexec", а вторая часть, это как раз и есть тот модуль который будет подключаться в сервис Apache. Для того чтобы этот модуль потом скомпилировался нам необходима система компиляции модулей Apache, она называется "APXS". Вот я ее и включил чтобы на выходе мы имели готовый скомпилированный модуль вида "mod_suexec.so".
Важно! Примечание: возможно вам понадобится добавить ключ "--enable-so" для того чтобы компиляция этого модуля прошла успешно и она прописалась в конфиг Apache.

Чтож, думаю этот этап у нас прошел успешно. Продолжим:
Далее нам надо подготовить сконфигурированный вариант установки; Вперед! Готовим!

make

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

make install

- и тоже ждем пока пройдет много текста по экрану (это может зависить от количества дополнительных опций указанных вами и от мощности компьютера). Если все прошло нормально, то поздравляю с установленным сервисом Apache с поддержкой функции SuExec!

Далее надо отредактировать файл httpd.conf. Я не буду тут описывать каждое значение переменных в этом файле, поскольку подразумеваю то, что если вы решились ставить suexec, то вы понимаете синтаксис и значения содержащиеся в этом файле. Я лишь для наглядности приведу пример того что получилось у меня:

вот файлик "/etc/httpd/httpd.conf" (убрал для краткости все закомментированные строки):

#
ServerRoot "/usr"
Listen 192.168.1.3:80
Listen 192.168.1.4:80

LoadModule authn_file_module lib64/httpd/modules/mod_authn_file.so
LoadModule authn_dbm_module lib64/httpd/modules/mod_authn_dbm.so
LoadModule authn_anon_module lib64/httpd/modules/mod_authn_anon.so
LoadModule authn_dbd_module lib64/httpd/modules/mod_authn_dbd.so
LoadModule authn_default_module lib64/httpd/modules/mod_authn_default.so
LoadModule authn_alias_module lib64/httpd/modules/mod_authn_alias.so
LoadModule authz_host_module lib64/httpd/modules/mod_authz_host.so
LoadModule authz_groupfile_module lib64/httpd/modules/mod_authz_groupfile.so
LoadModule authz_user_module lib64/httpd/modules/mod_authz_user.so
LoadModule authz_dbm_module lib64/httpd/modules/mod_authz_dbm.so
LoadModule authz_owner_module lib64/httpd/modules/mod_authz_owner.so
LoadModule authnz_ldap_module lib64/httpd/modules/mod_authnz_ldap.so
LoadModule authz_default_module lib64/httpd/modules/mod_authz_default.so
LoadModule auth_basic_module lib64/httpd/modules/mod_auth_basic.so
LoadModule auth_digest_module lib64/httpd/modules/mod_auth_digest.so
LoadModule file_cache_module lib64/httpd/modules/mod_file_cache.so
LoadModule cache_module lib64/httpd/modules/mod_cache.so
LoadModule disk_cache_module lib64/httpd/modules/mod_disk_cache.so
LoadModule mem_cache_module lib64/httpd/modules/mod_mem_cache.so
LoadModule dbd_module lib64/httpd/modules/mod_dbd.so
LoadModule dumpio_module lib64/httpd/modules/mod_dumpio.so
LoadModule reqtimeout_module lib64/httpd/modules/mod_reqtimeout.so
LoadModule ext_filter_module lib64/httpd/modules/mod_ext_filter.so
LoadModule include_module lib64/httpd/modules/mod_include.so
LoadModule filter_module lib64/httpd/modules/mod_filter.so
LoadModule substitute_module lib64/httpd/modules/mod_substitute.so
LoadModule deflate_module lib64/httpd/modules/mod_deflate.so
LoadModule ldap_module lib64/httpd/modules/mod_ldap.so
LoadModule log_config_module lib64/httpd/modules/mod_log_config.so
LoadModule log_forensic_module lib64/httpd/modules/mod_log_forensic.so
LoadModule logio_module lib64/httpd/modules/mod_logio.so
LoadModule env_module lib64/httpd/modules/mod_env.so
LoadModule mime_magic_module lib64/httpd/modules/mod_mime_magic.so
LoadModule cern_meta_module lib64/httpd/modules/mod_cern_meta.so
LoadModule expires_module lib64/httpd/modules/mod_expires.so
LoadModule headers_module lib64/httpd/modules/mod_headers.so
LoadModule ident_module lib64/httpd/modules/mod_ident.so
LoadModule usertrack_module lib64/httpd/modules/mod_usertrack.so
LoadModule unique_id_module lib64/httpd/modules/mod_unique_id.so
LoadModule setenvif_module lib64/httpd/modules/mod_setenvif.so
LoadModule version_module lib64/httpd/modules/mod_version.so
LoadModule proxy_module lib64/httpd/modules/mod_proxy.so
LoadModule proxy_connect_module lib64/httpd/modules/mod_proxy_connect.so
LoadModule proxy_ftp_module lib64/httpd/modules/mod_proxy_ftp.so
LoadModule proxy_http_module lib64/httpd/modules/mod_proxy_http.so
LoadModule proxy_scgi_module lib64/httpd/modules/mod_proxy_scgi.so
LoadModule proxy_ajp_module lib64/httpd/modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module lib64/httpd/modules/mod_proxy_balancer.so
#LoadModule ssl_module lib64/httpd/modules/mod_ssl.so
LoadModule mime_module lib64/httpd/modules/mod_mime.so
LoadModule dav_module lib64/httpd/modules/mod_dav.so
LoadModule status_module lib64/httpd/modules/mod_status.so
LoadModule autoindex_module lib64/httpd/modules/mod_autoindex.so
LoadModule asis_module lib64/httpd/modules/mod_asis.so
LoadModule info_module lib64/httpd/modules/mod_info.so
LoadModule suexec_module lib64/httpd/modules/mod_suexec.so
LoadModule cgi_module lib64/httpd/modules/mod_cgi.so
LoadModule dav_fs_module lib64/httpd/modules/mod_dav_fs.so
LoadModule vhost_alias_module lib64/httpd/modules/mod_vhost_alias.so
LoadModule negotiation_module lib64/httpd/modules/mod_negotiation.so
LoadModule dir_module lib64/httpd/modules/mod_dir.so
LoadModule imagemap_module lib64/httpd/modules/mod_imagemap.so
LoadModule actions_module lib64/httpd/modules/mod_actions.so
LoadModule userdir_module lib64/httpd/modules/mod_userdir.so
LoadModule alias_module lib64/httpd/modules/mod_alias.so
LoadModule rewrite_module lib64/httpd/modules/mod_rewrite.so

<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>

User apache
Group apache

</IfModule>
</IfModule>

ServerAdmin you@example.com

ServerName atomlinux:80

DocumentRoot "/vhost"

<Directory /vhost>
    Options FollowSymLinks
    AllowOverride All
    Order deny,allow
    Deny from all
</Directory>

<Directory "/vhost">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

<FilesMatch "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

ErrorLog "/var/log/httpd/error_log"
LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    CustomLog "/var/log/httpd/access_log" common
</IfModule>

<IfModule alias_module>
</IfModule>

<IfModule cgid_module>
</IfModule>

<Directory "/vhost/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>

DefaultType text/plain

<IfModule mime_module>
    TypesConfig /etc/httpd/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
</IfModule>

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

<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
Include /etc/httpd/mod_php.conf

а вот файлик "/etc/httpd/extra/httpd-vhosts.conf" (убрал для краткости все закомментированные строки):
примерно вот так он должен выглядеть. Вы его должны компоновать уже сами.

#
Listen 192.168.1.3:80
NameVirtualHost 192.168.1.3:80

##### VHOST ДЛЯ ДОМЕНА domain1 #####
Listen 192.168.1.4:80
NameVirtualHost 192.168.1.4:80
<VirtualHost 192.168.1.4:80>
<Directory /vhost/domain1>
    Options +ExecCGI
</Directory>
    ScriptAlias /cgi-bin/ "/vhost/domain1/cgi-bin/"
<FilesMatch \.php$>
    SetHandler php-cgi
</FilesMatch>
    Action php-cgi /cgi-bin/php-cgi
    SuexecUserGroup domain1 domain1
    ServerAdmin domain1@domain1.ru
    DocumentRoot "/vhost/domain1/www"
    ServerName domain1.ru
    ServerAlias www.domain1.ru
    ErrorLog "/vhost/domain1/logs/domain1_ru-error_log"
    CustomLog "/vhost/domain1/logs/domain1_ru-access_log" common
</VirtualHost>

##### VHOST ДЛЯ ДОМЕНА domain2 #####
Listen 192.168.1.5:80
NameVirtualHost 192.168.1.5:80
<VirtualHost 192.168.1.5:80>
<Directory /vhost/domain2>
    Options +ExecCGI
</Directory>
    ScriptAlias /cgi-bin/ "/vhost/domain2/cgi-bin/"
<FilesMatch \.php$>
    SetHandler php-cgi
</FilesMatch>
    Action php-cgi /cgi-bin/php-cgi
    SuexecUserGroup domain2 domain2
    ServerAdmin domain2@domain2.ru
    DocumentRoot "/vhost/domain2/www"
    ServerName domain2.ru
    ServerAlias www.domain2.ru
    ErrorLog "/vhost/domain2/logs/domain2_ru-error_log"
    CustomLog "/vhost/domain2/logs/domain2_ru-access_log" common
</VirtualHost>

Как вы уже сами поняли, перед тем как заводить домены для этих пользователей, надо этих пользователей создать и задать им соответствующие UID и GID (2001, 2002, 2003, 2004 и т.д.)
порядок примерно такой:

useradd domain1 -m -d /vhost/domain1 -s /bin/bash -u 2001 (или /bin/false, если не хотите пускать пользователя по SSH, FTP и пр.) - данная команда создаст пользователя, его домашнюю папку, и группу с таким же названием как и имя пользователя, но если этого не произошло, просто добавьте ключ "-U" в команду.

далее добавляем пользователя "apache" в группу вновь созданного пользователя:

usermod -a -G domain1 apache

Ключ "-a" говорит нам, как раз, о том, что необходимо указанного пользователя добавить в группу указанную рядом с ключом "-G" и, при этом не удалять его из ранее назначенных групп (ну правда, зачем нам это надо?).

Собственно, после создания одного или нескольких пользователей можно уже и компоновать файл httpd-vhosts.conf.

Немного слов о содержимом домашней директории пользователя... Как я показывал выше, список:

root@AtomLinux:/vhost/domain1# ls -l
итого 16
dr-xr-x--- 2 domain1 domain1 4096 Июл 31 07:09 cgi-bin/
drwxr-x--- 2 domain1 domain1 4096 Июл 31 07:07 ftp/
drwxr-x--- 2 domain1 domain1 4096 Авг 4 01:43 logs/
drwxr-x--- 2 domain1 domain1 4096 Июл 31 07:12 www/
root@AtomLinux:/vhost/domain1#

Эти папки в данном случае вам придется создавать вручную для каждого создаваемого пользователя. Но есть удобная никточка, за которую если потянуть, то можно узнать, что существует в системе такой каталог как "/etc/skel/" - так вот, в нем содержится шаблон содержимого домашних папок пользователей и, если в нем один раз создать все требуемые по-умолчанию папки и файлы для пользователя, то на основании этого шаблона все последующие домашние папки вновь создаваемых пользователей будут наполняться содержимым "/etc/skel/" с соответствующими правами для нового пользователя. Единственное чему стоит уделить особое внимание, так эта папке "/cgi-bin/" - почему? Все просто... смотрим ее содержимое:

root@AtomLinux:/vhost/domain1# ls -l /vhost/domain1/cgi-bin/
итого 12096
-r-xr-x--- 1 root root 6132248 Апр 3 21:26 php*
-r-xr-x--- 1 domain1 domain1 6151928 Апр 3 21:26 php-cgi*
-r-xr-x--- 1 root root 68313 Апр 3 21:26 php.ini*
root@AtomLinux:/vhost/domain1#

Заметили? Два файла имеют пользователя и группу root:root - это нужно для того чтобы нельзя было модифицировать эти файлы самостоятельно.. их повреждение будет означать отказ работы домена этого пользователя... права же на файл php-cgi нужны для данного пользователя чтобы обрабатывать php скрипты. Так что права выставьте вручную или напишите комплексный bash-скрипт который делает это все разом, чтоб каждый раз руками не переписывать.

Примечание: Может возникнуть такая ситуация, что файл php.ini при включенном режиме работы suexec будет подгружаться из общей системной папки PHP (например /etc/php - смотрите каждый у себя сам где он лежит. В этом поможет команда php -i либо php-cgi -i . Там в самом начале будет секция показывающая расположение файла php.ini ). Чтобы активировать процесс подгрузки файла php.ini из веб-папки пользователя, подпапки /cgi-bin/ просто поменяйте права на файл php.ini добавив туда возможность читать его "для всех остальных", или смените группу на группу текущего пользователя. Второй вариант предпочтительнее.

С Apache вроде разобрались.

Теперь приступим к PHP.

Но тут радостная новость!! На этом статью можно в принципе и закончить, потому что начиная с версии 5.2.хх у PHP идет уже встроенная модель работы с поддержкой suexec. PHP пакет надо просто скопмилировать, найти файлы php, php-cgi, php.ini и поместить их в соответствующую папку "/cgi-bin/" или как я рекомендовал выше в папку шаблона "/etc/skel/".

Вот собственно и все, что касается настройки SuExec с нуля! Написано много, да. Я старался более менее полностью раскрыть эту тему. На самом деле это делается все в течение 5-10 минут. Так что, дерзайте.

А пока мы перейдем к самому неоднозначному варианту развития событий... А что если Apache уже настроен, сконфигурирован и установлен в системе без поддержки SuExec?

Что... придется все перекомпилировать и устанавливать заного? Мой ответ будет, увы, ДА! И это печально...

Но я не стал бы затевать вторую часть этой статьи если бы такой возможности все-таки не было. Так что выход из положения, все-таки, есть!

Итак, откатывается немного назад, до того момента когда мы начинали готовить пакет Apache к подготовке к установке "./configure".
Делаем все как там написано, и, затем, проводим процедуру make. (make install делать НЕ нужно!) Делаем следующим образом:

make suexec
strip support/suexec
cp support/suexec /usr/sbn
chown root:root /usr/sbin/suexec

Ищем файлы "suexec" и "mod_suexec.so" и кладем их в соответствующие директории. Куда класть "suexec" мы уже знаем, а вот "mod_suexec.so" мы должны положить в "путь_к_папке_куда_установлен_Apache/httpd/modules/". Вот и все.
Если модуль mod_suexec.so не собрался по каким-то причинам, то попробуйте проделать команду:

apxs2 -c mod_suexec.c

Файл mod_suexec.c должен лежать в директории предподготовки для установки Apache..

Теперь надо дать права на на файл suexec. Если права буду не верны, то мы начнем получать ошибку из серии "SuExec wrapper error..." У меня права стоят вот так:

root@AtomLinux:~# ls -l /usr/sbin/suexec
-rwsr-xr-x 1 root root 14136 Июл 31 15:13 /usr/sbin/suexec*
root@AtomLinux:~#

Но можно ужесточить права путем передачи управления только на Apache:

chgrp apache /usr/sbin/suexec
chmod 4750 /usr/sbin/suexec

проверяем конфигурацию suexec:

suexec -V

должны получить нечто похожее:

root@AtomLinux:/# suexec -V
-D AP_DOC_ROOT="/vhost"
-D AP_GID_MIN=2000
-D AP_HTTPD_USER="apache"
-D AP_LOG_EXEC="/var/log/httpd/suexec_log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=2000
-D AP_USERDIR_SUFFIX="/www"
root@AtomLinux:/#

если все верно, то рестартуем апач, именно делаем полный рестарт!! Режим "graceful" не даст результата! Делаем stop и затем start.
Если что-то пошло не так.. читаем логи (/var/log/httpd/....)

Вот, в принципе, и все!

Если у вас есть дополнения по этому материалу, с радостью выслушаю и внесу соответствующие корректировки.
Так же если есть вопросы, я готов на них ответить.

С Уважением,
Savaog

Спасибо за статью. Но вот

Спасибо за статью. Но вот вопрос -
есть примитивная панель управления с файл менеджером на php в /var/www/panel/
есть те же 2 пользователя со своими папками и виртуальными серверами
/usr/home/user1/
/usr/home/user2/
все настроенно для работы с suexec

как сделать так что бы залогиневшись в панель(простая mysql и php авторизация), файл менеджер работал из под правильного пользователя? т.е. с правильными правами.
или получается что файл менеджер надо каждому пользователю скопировать и редиректить из панели?! но тогда возникает целая серия вопросов о безопасности...

Т.е. как организовать централизованный доступ?

Столкнулся я с этой заразой!

Столкнулся я с этой заразой! Именно заразой, иначе и не скажешь. И как, позвольте спросить перегосить сайт на хостинг где включён этот модуль. Я как раз пытаюсь перенести пару сайтов на хостинг с этим модулем. Правда в связке с Confixx. Так он, гад, даже элементарное изменение отображения ссылок в Wordpress не даёт сделать. Ругается, что я хочу сего-то там в wp-admin сделать. При этом ещё и валит сайт с ошибкой из разряда "недостаточно прав" После этого и откат невозможен малой кровью. И сайт практически недоступен. ЧПУ ссылки сделать тоже не даёт. И с тем же эффектом. Причём перезаливка файлов уже не даёт ничего. Он ещё и фиксирует где-то все эти казусы. и блокирует доступ напрочь. Так и пишет,, что у вас недостаточно прав. Это уже не безопасность. Это - параноя! Хорошо если поддержка разбирается во всех этих конфигурационных нюансах. И ей это будет не в лом. А то прийдётся в попыхах менее параноидальный хостинг искать. :)

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

Добрый вечер! На самом деле,

Добрый вечер!

На самом деле, переносить свои сайты на хостинги, где используется технология SuExec не так уж и сложно...
Важно понимать, что после копирования, если оно ведется напрямую, файлы вашего сайта могут сохранить маркеры доступа от прежнего размещения... для этого необходимо всего-лишь принудительно, на новом хостинге, комплексно провести процедуры переназначения хозяина Ваших файлов и папок (user:group) и прав на них (их кстати можно попробовать оставить без изменений), согласно авторизационным данным, предоставленным Вам на новом хостинге. Для этого используются команды "chmod" и "chown" (при наличии возможности доступа к управлению сайтом посредством SSH).

С Уважением,
Savaog