Настройка Apache2 с mod_fcgid и PHP5 на CentOS 6.2
Введение
Версия 1.0
Автор: Falko Timme
Следите за автором в Twitter
В этом руководстве показано, как установить Apache2 с модулем mod_fcgid и PHP5 на CentOS 6.2. mod_fcgid — современная совместимая альтернатива старому mod_fastcgi. Он позволяет выполнять PHP-скрипты с правами владельца файлов, а не системного пользователя Apache.
Я не даю гарантий, что всё сработает в вашей среде — проверяйте конфигурации и резервные копии перед применением на продакшене.
Кому это подходит
- Системным администраторам, которые хотят запускать PHP-скрипты под пользователями сайтов (из соображений безопасности и учёта прав).
- Проектам, которые по каким-то причинам не могут использовать PHP-FPM и предпочитают модуль mod_fcgid.
Важно: CentOS 6.2 — устаревшая платформа, рассмотрите миграцию на более свежие релизы или использование контейнеров.
1 Предварительная заметка
В примерах используется сервер CentOS 6.2 с именем host server1.example.com и IP 192.168.0.100. Для демонстрации будут созданы два vhost: www.example1.com и www.example2.com.
Перед началом убедитесь, что SELinux отключён. Отредактируйте файл /etc/selinux/config и установите SELINUX=disabled:
vi /etc/selinux/config| # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted |
После изменения нужно перезагрузить систему:
reboot2 Установка Apache2, mod_fcgid и PHP5
mod_fcgid недоступен в официальных репозиториях CentOS, но есть в репозитории EPEL. Подключите EPEL следующим образом:
rpm --import https://fedoraproject.org/static/0608B895.txt
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-7.noarch.rpm
rpm -ivh epel-release-6-7.noarch.rpmЗатем установите утилиту приоритетов yum:
yum install yum-prioritiesОтредактируйте /etc/yum.repos.d/epel.repo и добавьте строку priority=10 в секцию [epel]:
vi /etc/yum.repos.d/epel.repo| [epel] name=Extra Packages for Enterprise Linux 6 - $basearch #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 priority=10 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 [...] |
После этого устанавливаем Apache, mod_fcgid и php-cli:
yum install httpd mod_fcgid php-cliЕсли Apache уже был установлен с PHP в виде модуля, отключите модуль PHP5 — отредактируйте /etc/httpd/conf.d/php.conf:
vi /etc/httpd/conf.d/php.conf… и закомментируйте всё содержимое файла (пример ниже иллюстрирует содержимое, закомментируйте строки с LoadModule и директивами обработки .php):
| # # PHP is an HTML-embedded scripting language which attempts to make it # easy for developers to write dynamically generated webpages. # # |
Создайте системные ссылки для старта Apache и запустите сервис:
chkconfig --levels 235 httpd on
/etc/init.d/httpd restartОтредактируйте /etc/php.ini и раскомментируйте строку cgi.fix_pathinfo=1 (требуется для корректной работы PATH_INFO при запуске через CGI):
vi /etc/php.ini| [...] ; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's ; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok ; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting ; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting ; of zero causes PHP to behave as before. Default is 1. You should fix your scripts ; to use SCRIPT_FILENAME rather than PATH_TRANSLATED. ; http://www.php.net/manual/en/ini.core.php#ini.cgi.fix-pathinfo cgi.fix_pathinfo=1 [...] |
Откройте /etc/httpd/conf.d/fcgid.conf и добавьте в конец строку PHP_Fix_Pathinfo_Enable 1:
vi /etc/httpd/conf.d/fcgid.conf| [...] PHP_Fix_Pathinfo_Enable 1 |
Перезагрузите конфигурацию Apache:
/etc/init.d/httpd reload3 Создание виртуальных хостов для www.example1.com и www.example2.com
В примере будут два виртуальных хоста: www.example1.com с DocumentRoot /var/www/web1/web и www.example2.com с DocumentRoot /var/www/web2/web. Владелец первого сайта — пользователь и группа web1, второго — web2.
Создаём группы и пользователей:
groupadd web1
groupadd web2
useradd -s /bin/false -d /var/www/web1 -m -g web1 web1
useradd -s /bin/false -d /var/www/web2 -m -g web2 web2
chmod 755 /var/www/web1
chmod 755 /var/www/web2Создаём корни сайтов и назначаем владельцев:
mkdir -p /var/www/web1/web
chown web1:web1 /var/www/web1/web
mkdir -p /var/www/web2/web
chown web2:web2 /var/www/web2/webМы будем запускать PHP через suExec; документный корень suExec — /var/www, что видно из вывода:
/usr/sbin/suexec -V[root@server1 ~]# /usr/sbin/suexec -V
-D AP_DOC_ROOT=”/var/www”
-D AP_GID_MIN=100
-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=500
-D AP_USERDIR_SUFFIX=”public_html”
[root@server1 ~]#
Поскольку бинарник PHP (/usr/bin/php-cgi) находится за пределами AP_DOC_ROOT, suExec не позволит его запускать напрямую и не разрешает символические ссылки. Решение — создать wrapper-скрипт в субдиректории внутри /var/www, который будет вызывать /usr/bin/php-cgi. Этот wrapper должен принадлежать пользователю сайта. Для каждого сайта нужен свой wrapper.
Создаём директории-оболочки:
mkdir -p /var/www/php-fcgi-scripts/web1
mkdir -p /var/www/php-fcgi-scripts/web2Создаём скрипт-стартер для web1:
vi /var/www/php-fcgi-scripts/web1/php-fcgi-starter| #!/bin/sh PHPRC=/etc/ export PHPRC export PHP_FCGI_MAX_REQUESTS=5000 export PHP_FCGI_CHILDREN=8 exec /usr/bin/php-cgi |
Создаём такой же скрипт-стартер для web2:
vi /var/www/php-fcgi-scripts/web2/php-fcgi-starter| #!/bin/sh PHPRC=/etc/ export PHPRC export PHP_FCGI_MAX_REQUESTS=5000 export PHP_FCGI_CHILDREN=8 exec /usr/bin/php-cgi |
Коротко о параметрах:
- PHPRC — папка, где лежит php.ini (здесь /etc/ => /etc/php.ini).
- PHP_FCGI_MAX_REQUESTS — максимальное число запросов, после которого fcgid-процесс будет перезапущен.
- PHP_FCGI_CHILDREN — число дочерних процессов PHP для обработки запросов.
Делаем скрипты исполняемыми и назначаем владельцев:
chmod 755 /var/www/php-fcgi-scripts/web1/php-fcgi-starter
chmod 755 /var/www/php-fcgi-scripts/web2/php-fcgi-starter
chown -R web1:web1 /var/www/php-fcgi-scripts/web1
chown -R web2:web2 /var/www/php-fcgi-scripts/web2Теперь добавим виртуальные хосты в конец /etc/httpd/conf/httpd.conf:
vi /etc/httpd/conf/httpd.conf| [...] NameVirtualHost *:80 |
Убедитесь, что пути и значения в SuexecUserGroup совпадают с владельцами директорий.
Перезагрузите Apache:
/etc/init.d/httpd reloadПрактические замечания и рекомендации
Контроль за процессами и настройка производительности
- Начните с небольшого числа PHP_FCGI_CHILDREN (например, 2–4) и увеличивайте по мере необходимости. Не ставьте слишком много детей на сервер с ограниченной памятью.
- PHP_FCGI_MAX_REQUESTS стоит выставлять так, чтобы избежать утечек памяти в долгоживущих процессах — 5000 в примере подходит для большинства случаев, но корректируйте в зависимости от наблюдений.
Логи и отладка
- Просматривайте /var/log/httpd/error_log и /var/log/httpd/access_log при проблемах.
- suExec логирует попытки запуска в /var/log/httpd/suexec.log согласно выводу /usr/sbin/suexec -V.
Безопасность
- Не давайте директории вне /var/www права на запись без надобности.
- Проверяйте права и владельцев wrapper-скриптов — они должны принадлежать соответствующим пользователям сайтов.
- Отключайте ненужные модули Apache и минимизируйте набор прав (минимум разрешений для выполнения).
- Регулярно обновляйте пакеты (учитывая поддержку CentOS 6.x). Рассмотрите миграцию на более новые системы или контейнеры для длительной безопасности.
Альтернативные подходы (когда применять и почему)
- PHP-FPM + mod_proxy_fcgi: более современный и предпочтительный вариант для новых установок. Обеспечивает лучшую производительность, управление процессами и более гибкую конфигурацию.
- Использовать FastCGI через mod_fastcgi: устаревший вариант, не рекомендуется.
- Запускать PHP как модуль Apache (libphp): проще, но все php-скрипты будут выполняться от пользователя Apache (меньше изоляции и возможные проблемы с правами).
Когда этот метод не годится
- Если нужно масштабирование на множество ядер и высокий трафик — лучше PHP-FPM.
- Если ваша политика безопасности запрещает запускать любые исполняемые файлы в /var/www — suExec может быть неподходящим.
Критерии приёмки
- Apache запускается без ошибок после перезагрузки:
service httpd statusили/etc/init.d/httpd status. - При переходе на http://www.example1.com и http://www.example2.com выполняются .php файлы и возвращают корректный HTML.
- Проверка прав: wrapper-скрипты и каталоги принадлежат соответствующим пользователям (web1/web2).
- suExec не записывает ошибок при запуске /var/log/httpd/suexec.log.
Резервный план и откат
- Перед изменением /etc/httpd/conf/httpd.conf и /etc/php.ini сделайте резервные копии:
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak cp /etc/php.ini /etc/php.ini.bak - Если сайт перестаёт работать после изменения, откатитесь к резервной копии и перезагрузите Apache:
cp /etc/httpd/conf/httpd.conf.bak /etc/httpd/conf/httpd.conf /etc/init.d/httpd restart
Проверочные тесты и приёмка
- Создайте простой файл /var/www/web1/web/info.php с содержимым:
Откройте http://www.example1.com/info.php — должна отобразиться страница phpinfo(). Если вместо этого вы видите исходный код или ошибка 500, проверьте логи и права на wrapper и директории.
Рольные чек-листы
Администратор:
- Проверить SELinux и перезагрузку.
- Установить EPEL и пакеты.
- Создать пользователей, права и wrapper-скрипты.
- Настроить виртуальные хосты и перезагрузить Apache.
Разработчик:
- Проверить, что phpinfo() показывает ожидаемую конфигурацию.
- Убедиться, что файловые операции работают под нужным пользователем.
- Провести нагрузочное тестирование в контролируемой среде.
Оператор/DevOps:
- Наблюдать за метриками памяти/CPU после включения PHP_FCGI_CHILDREN.
- Настроить ротацию логов и мониторинг ошибок.
Миграция и совместимость
- При переносе на CentOS 7/8 или RHEL 7/8 рекомендую перейти на PHP-FPM и systemd-сервисы.
- Многие современные дистрибутивы больше не поставляют php5; планируйте обновление кодовой базы для поддержки PHP7+.
Краткий словарь (1 строка)
- suExec — механизм Apache для запуска CGI/скриптов от имени конкретного пользователя.
- mod_fcgid — модуль Apache для поддержки FastCGI-демонов и запуска CGI-процессов.
- wrapper-скрипт — оболочка внутри AP_DOC_ROOT, вызывающая системный php-cgi.
Типичные ошибки и способы устранения
- Ошибка 500 при обращении к .php: проверьте права на файлы, исполнение wrapper-скрипта и лог /var/log/httpd/error_log.
- PHP исполняется под пользователем apache: убедитесь, что вы отключили модуль libphp (php.conf) и настроили FCGIWrapper и SuexecUserGroup.
- suExec отказывает в запуске: проверьте, что файл находится в пределах AP_DOC_ROOT и принадлежит нужному пользователю.
Пример сценария отката инцидента
- Определить изменение, приведшее к сбою (конфигурация Apache, php.ini, wrapper).
- Восстановить файл из бэкапа (см. раздел «Резервный план и откат»).
- Перезапустить Apache:
/etc/init.d/httpd restart. - Проверить логи:
/var/log/httpd/error_logи/var/log/httpd/suexec.log.
Вывод
Настройка Apache2 с mod_fcgid и PHP5 на CentOS 6.2 позволяет запускать PHP-скрипты с правами владельца сайта, что повышает изоляцию и безопасность по сравнению с запуском от пользователя Apache. Подход требует дополнительной настройки wrapper-скриптов и внимательного управления правами. Для новых систем рекомендуется рассмотреть PHP-FPM как более современную и масштабируемую альтернативу.
Важно: тестируйте изменения в тестовой среде и готовьте план миграции на поддерживаемые версии ОС и PHP.
Ключевые файлы и команды, упомянутые в статье, остаются в исходных путях (/etc, /var/www и т.д.).
Примечание: если вы планируете держать систему в рабочем состоянии длительное время, рассмотрите обновление платформы и переход на поддерживаемые версии PHP и CentOS.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента