Гид по технологиям

Настройка массового виртуального хостинга Apache2 с mod_rewrite, mod_userdir и mod_suexec на CentOS 5.3

6 min read Apache Обновлено 28 Nov 2025
Массовый виртуальный хостинг Apache2 на CentOS 5.3
Массовый виртуальный хостинг Apache2 на CentOS 5.3

Версия: 1.2
Последнее редактирование: 7 июля 2009

Кратко: этот материал показывает метод массового виртуального хостинга на Apache2 с динамическим сопоставлением директорий через mod_rewrite и запуском CGI под владельцем скрипта с помощью suEXEC и mod_userdir. Подходит для распределённого хостинга, где каждому сайту соответствует системный пользователь. Тестируйте в контролируемой среде — конфигурация не проверялась на production.

Перед началом

Платформа: CentOS 5.3. Для примера предполагается, что домен www.example.com указывает на веб‑сервер с IP 192.168.1.1, а веб‑корень example.com расположен в /home/vhosts/example.com/public_html.

Важно: CentOS 5.3 — устаревшая версия; при перенесении на современные системы проверьте совместимость модулей и пути к бинарникам.

Установка Apache

Установите пакет httpd (в пакете CentOS включены модули mod_rewrite, mod_userdir и mod_suexec):

yum install httpd

Конфигурация массового виртуального хостинга

Откройте конфигурацию Apache:

vim /etc/httpd/conf/httpd.conf

Добавьте загрузку модуля mod_rewrite в верхней части (если ещё не загружен):

LoadModule rewrite_module modules/mod_rewrite.so

Внизу файла вставьте следующие правила (не меняйте пути, если используете ту же структуру):

## get the server name from the Host: header
UseCanonicalName Off


## splittable logs
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon


RewriteEngine On


## Create a handle to convert upper or mixed-case to lower-case
RewriteMap lowercase int:tolower


##-----------------------------------
## where hostname has www prefix
##-----------------------------------
## Firstly create custom variable that contains the host without the www prefix
RewriteCond %{HTTP_HOST} ^www\.(.*)$ 
RewriteRule .? - [E=noWWWHost:%1]


## Map the virtualhost to the documentroot
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{HTTP_HOST} ^www\. 
RewriteRule ^/(.*)$ /home/vhosts/${lowercase:%{ENV:noWWWHost}}/public_html/$1


##-----------------------------------
## where hostname *does not* have www prefix
##-----------------------------------
## Map the virtualhost to the documentroot
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{HTTP_HOST} !^www\. 
RewriteRule ^/(.*)$ /home/vhosts/${lowercase:%{HTTP_HOST}}/public_html/$1

Пояснения к конфигурации:

  • Сайты размещаются в /home/vhosts. Каждая подпапка — это доменное имя сайта (без www), например /home/vhosts/example.com.
  • Запрос к www.example.com будет динамически переписан на example.com.
  • Документная корневая папка называется public_html — это требование suEXEC для работы через mod_userdir. Если вы не планируете использовать suEXEC, можно использовать другое имя и скорректировать правила.

Создайте тестовый index.html в public_html виртуального хоста:

echo "index.html Hello World" > /home/vhosts/example.com/public_html/index.html

Запустите Apache:

/etc/init.d/httpd start

Затем при обращении к http://www.example.com/ должен отобразиться текст ‘index.html Hello World’. Если нет — смотрите лог ошибок:

tail /var/log/httpd/error_log

Запуск CGI под владельцем скрипта (suEXEC + mod_userdir)

Цель: в окружении шаред‑хостинга CGI/скрипты должны запускаться от имени владельца сайта, а не от процесса веб‑сервера.

Требование: системный пользователь с именем, равным имени сайта. Пример для example.com:

useradd -d /home/vhosts/example.com example.com

Это создаст пользователя example.com с домашней директорией /home/vhosts/example.com. Веб‑файлы для www.example.com помещайте в /home/vhosts/example.com/public_html.

Можно завести пользователей вручную в /etc/passwd или интегрировать LDAP/AD для автоматической авторизации.

Включите модуль mod_userdir и настройте UserDir:

vim /etc/httpd/conf/httpd.conf

Убедитесь, что в конфиге присутствуют строки:

LoadModule userdir_module modules/mod_userdir.so



    UserDir public_html

Теперь при запросе вида http://192.168.1.1/~example.com Apache по умолчанию будет искать /home/vhosts/example.com/public_html. Но мы хотим, чтобы URL оставался в форме http://www.example.com — для этого добавим скрытую переписку для CGI.

Добавьте после ранее вставленных правил следующее:

## Rewrite script to userdir so we can use suEXEC
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{SCRIPT_FILENAME} /home/vhosts/(.*)/public_html/(.*\.(pl|cgi))
RewriteRule .* /~%1/%2 [PT,L]



    AddHandler cgi-script .pl .cgi
    Options +ExecCGI

Перезагрузите конфигурацию Apache:

/etc/init.d/httpd reload

Создайте тестовый Perl‑скрипт test.pl в public_html:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "

test.pl Hello World

\n";

Сделайте скрипт исполняемым и установите правильного владельца:

chmod +x test.pl
chown example.com:example.com test.pl

Теперь при обращении к http://www.example.com/test.pl вы должны увидеть ‘test.pl Hello World’. Если нет — проверьте логи:

tail /var/log/httpd/error_log
tail /var/log/httpd/suexec.log

PHP и Python через suEXEC

Добавить поддержку PHP и Python просто: установите необходимые пакеты и настройте обработку как CGI.

Установите интерпретаторы:

yum install php-cli
yum install python

Примеры скриптов в public_html:

test.py

#!/usr/bin/python

print "Content-type: text/html\n\n"
print "test.py Hello world!"

test.php

#!/usr/bin/php-cgi


Поменяйте владельца и дайте бит исполнения. Каждому скрипту нужно указывать интерпретатор в первой строке (shebang). Чтобы не править каждый файл, можно зарегистрировать binfmt_misc (требуются разрешения и поддержка ядра):

echo ":PHP:E::php::/usr/bin/php-cgi:" > /proc/sys/fs/binfmt_misc/register  
echo ":Python:E::py::/usr/bin/python:" > /proc/sys/fs/binfmt_misc/register

Расширьте правило переписывания и обработчик cgi‑script:

## Rewrite script to userdir so we can use suEXEC
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{SCRIPT_FILENAME} /home/vhosts/(.*)/public_html/(.*\.(pl|cgi|php|py))
RewriteRule .* /~%1/%2 [PT,L]



    AddHandler cgi-script .pl .cgi .php .py
    Options +ExecCGI

PHP‑примечание: установите cgi.force_redirect = 0 в /etc/php.ini, чтобы избежать ошибок REDIRECT_STATUS при запуске php-cgi.

Перезагрузите Apache:

/etc/init.d/httpd reload

Проверяйте логи при ошибках:

tail /var/log/httpd/error_log
tail /var/log/httpd/suexec.log

Catchall — обработка несуществующих виртуальных хостов

Если нужно перенаправлять запросы к несуществующим vhost на «пойманный» сайт, добавьте последним правилом в /etc/httpd/conf/httpd.conf:

## Redirect non-existent virtualhosts
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{SCRIPT_FILENAME} (/home/vhosts/.*)/public_html/.*
RewriteCond %1 !-d
RewriteRule .? http://www.google.com [R,NS,L]

Замените http://www.google.com на адрес вашего catchall‑сайта. Это правило должно быть последним, чтобы не перехватывать реальные хосты.

Безопасность, ограничения и рекомендации

Important: suEXEC выполняет дополнительные проверки безопасности и ограничивает запуск CGI только в определённых условиях (пути, владельцы, права). Проверьте:

  • Владелец и группа файлов совпадают с ожидаемыми (chown user:user).
  • Права на директории и скрипты не должны быть открыты для группы/остальных (обычно 0755 для директорий и 0755/0750 для скриптов, уточняйте по требованиям suEXEC).
  • suEXEC логирует сообщения в /var/log/httpd/suexec.log — используйте его для отладки.

Ограничения suEXEC и mod_userdir:

  • suEXEC не поддерживает запуск из произвольных путей — путь и владельцы должны соответствовать ожиданиям.
  • suEXEC не выполняет файлы с небезопасными правами.
  • Если нужны ресурсоёмкие приложения (persistent PHP-FPM, long‑running Python), лучше использовать отдельные процессы/сокеты вместо suEXEC CGI.

Рекомендации по безопасности:

  • Минимизируйте набор исполняемых расширений (.pl, .cgi, .php, .py).
  • Используйте SELinux (если включён) и настройте политики для каталога /home/vhosts.
  • Отключите ненужные модули Apache и ограничьте число разрешённых директив в .htaccess.

Чек‑лист перед запуском (роль: системный администратор)

  • Установлен пакет httpd.
  • Загружены модули mod_rewrite, mod_userdir, mod_suexec.
  • В каталоге /home/vhosts созданы директории для доменов.
  • Пользователи созданы и владеют своими директориями (useradd -d …).
  • public_html присутствует и содержит index.html для теста.
  • Конфигурация RewriteMap и правил проверена локально.
  • Тестовые CGI‑скрипты имеют правильные shebang, права и владельца.
  • Логи доступны и индексируются для отладки (/var/log/httpd/*).

Критерии приёмки

  • При обращении к существующему домену отображается его index.html.
  • CGI/Perl/Python/PHP скрипт запускается и возвращает корректный HTTP‑ответ от имени владельца сайта.
  • Логи Apache и suexec не содержат ошибок при штатных запросах.
  • Правило catchall срабатывает только для несуществующих сайтов.

Runbook: быстрый порядок действий при сбое

  1. Проверить статус httpd: systemctl (или /etc/init.d/httpd) start|status.
  2. Просмотреть последние записи в /var/log/httpd/error_log и /var/log/httpd/suexec.log.
  3. Проверить, что каталог и файл существуют и имеют правильные права: ls -l /home/vhosts/example.com/public_html/test.pl.
  4. Убедиться, что shebang у скрипта корректен и интерпретатор установлен.
  5. Откат: восстановить предыдущую конфигурацию httpd.conf из резервной копии и выполнить reload.

Тестовые случаи и приёмочные проверки

  • Тест 1: GET / -> index.html, код 200.
  • Тест 2: GET /test.pl -> выполняется тест.pl, отображает H1, владелец процесса соответствует владельцу файла.
  • Тест 3: GET /test.php и /test.py -> корректный вывод от php-cgi и python.
  • Тест 4: Запрос к несуществующему домену -> редирект на catchall (если включено).

Модель принятия решений (Mermaid)

flowchart TD
    A[Запрос на www.example.com] --> B{Существует ли /home/vhosts/domain/public_html}
    B -- Да --> C{Запрошен файл с расширением CGI?}
    C -- Да --> D[Переписать на /~user/file и запустить suEXEC]
    C -- Нет --> E[Отдать файл из /home/vhosts/domain/public_html]
    B -- Нет --> F[Сработает правило catchall или 404]

Совместимость и миграция

  • На новых дистрибутивах пути к php-cgi и python могут отличаться (/usr/bin/php-cgi, /usr/bin/python3). Проверьте shebang.
  • CentOS 5.3 — устаревший релиз. При переносе на более новые системы рассмотрите использование PHP‑FPM, systemd и современных механизмов изоляции (containers, cgroups) вместо suEXEC для лучшей масштабируемости.

Частые ошибки и способы устранения

  • Ошибка suEXEC: проверьте владельца и права файла.
  • Ошибка CGI REDIRECT_STATUS: установите cgi.force_redirect = 0 в /etc/php.ini.
  • Переписывание не срабатывает: включён ли мод_rewrite и правильны ли условия RewriteCond.
  • Нечитаемые логи: проверьте права на /var/log/httpd и r/o монтирование.

Роль‑ориентированные чек‑листы

Администратор:

  • Провести аудит прав и владельцев.
  • Настроить ротацию логов.
  • Настроить мониторинг доступности.

Разработчик:

  • Проверить shebang и зависимости скрипта.
  • Убедиться, что скрипт не требует persistent‑процесса.

Короткое резюме

  • Массовый виртуальный хостинг реализуется через динамическую переписку путей в mod_rewrite и размещение сайтов в /home/vhosts.
  • suEXEC + mod_userdir позволяют запускать CGI от владельца сайта.
  • Проверяйте права, shebang и логи; на современных платформах рассмотрите альтернативы suEXEC для лучшей производительности.

Важно: эта инструкция описывает один из подходов. Для production рекомендуется тестирование на staging, контроль прав доступа, бекапы конфигурации и, при необходимости, миграция на современные механизмы обработки скриптов.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как улучшить графику в Elden Ring
Игры

Как улучшить графику в Elden Ring

Удаление пароля Windows 10 для локальной учётной записи
Windows

Удаление пароля Windows 10 для локальной учётной записи

HANDLE_ERROR_ON_CRITICAL_THREAD — как исправить BSOD
Windows

HANDLE_ERROR_ON_CRITICAL_THREAD — как исправить BSOD

Устранение утечки памяти LockAppHost.exe в Windows 10
Windows 10

Устранение утечки памяти LockAppHost.exe в Windows 10

Ошибка AppHangB1: способы исправления
Windows

Ошибка AppHangB1: способы исправления

Жесты головы на AirPods в iOS 18
Гаджеты

Жесты головы на AirPods в iOS 18