mod_aclr
Модуль предназначен для работы на бек-енд сервере apache v.1.3.x совместно с nginx в качестве фронт-енда.
Версия для apache 2.x https://github.com/defanator/mod_aclr2 от Андрея Белова.
Преамбула
Основная проблема использования маленьких серверов в качестве фронт-енд в виртуальном хостинге - это полное непонимание синтаксиса .htaccess, а значит игнорирование настроек пользователя. Решения обычно два - или использование в качестве фронт-енд apache (с mod_proxy или mod_accel) или использование маленьких серверов в режиме "проксировать все". В случае последнего варианта большие файлы проходят стадию передачи бек-енд->фронт-енд, да еще и кешируются фронт-ендом, что вносит дополнительную нагрузку как на сервисы, так и на дисковую систему.
Задача модуля
Для решения этой проблемы был написан mod_aclr. Его задача - определить тип файла. Фронт-енд (nginx) проксирует каждый запрос на бек-енд (apache). Если это динамический контент - работа продолжается в обычном режиме - бек-енд выдает его фронт-енду, а тот уже отдает клиенту. Если же запрошенный файл - статика, то тут вступает в работу mod_aclr, который выдает фронт-енду в качестве ответа специальный внутренний редирект. Фронт-енд следует этому редиректу и начинает выдачу файла. Редирект выдается после отработки всей логики apache включая htaccess.
Идея реализации
Модуль встает в apache как default handler. Этот обработчик API сервера вызывает в последнюю очередь - если запрос не был перехвачен другими хендлерами. Поставив модуль первым в списке (обрабатывается последним по внутренней логике), mod_aclr получит управление лишь если ни один другой модуль не захотел обработать этот запрос.
Получив управление модуль делает необходимые проверки - включен ли он для этого сервера, есть ли в запросе от клиента заголовок X-Accel-Internal, существует ли запрошенный файл и некоторые другие проверки. Если происходит ошибка - модуль завершается с передачей управления следующему (обычно это mod_core).
Принцип работы
Специальной обработке подвергаются запросы содержащие заголовок X-Accel-Internal - это позволяет серверу нормально работать и с обычными клиентами. Если результатом запроса является файл и логика модуля включена для этого виртуального сервера (директории), mod_aclr выдает в качестве ответа OK с длиной тела 0 (Content-Length: 0) и специальным заголовком X-Accel-Redirect, который состоит из двух частей - строки, переданной посредством X-Accel-Internal и переданного URI.
Для X-Accel-Internal поддерживается макрос %host%, который при выдаче в X-Accel-Redirect заменяется на имя сервера (виртуального) бек-енда.
Директивы
AccelRedirectSet {On|Off}
Default: Off
Context: server config, virtual host, directory
Включает (выключает) работу модуля. В выключенном состоянии модуль "прозрачен".
AccelRedirectSize size[k|M]
Default: -1
Context: server config, virtual host, directory
Устанавливает минимальный размер запрошенного файла, начиная с которого модуль выдает редирект. Файлы с меньшим размером обрабатываются apache как обычно и выдаются клиенту.
AccelRedirectDebug level
Default: 0
Context: server config
Устанавливает уровень отладочных сообщений. 0 - отключает их.
Конфигурация nginx
Ниже приведен пример конфигурации nginx в качестве фронт-енд.
server {
listen x.x.x.x;
server_name server.name.ru;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Accel-Internal /internal_xxx;
proxy_set_header Host $http_host;
}
location /internal_xxx/ {
root /home/server.name.ru/htdocs;
rewrite ^/internal_xxx/(.*)$ /$1 break;
internal;
}
}
Для всех запросов сервера осуществляется проксирование на бек-енд (127.0.0.1) c установкой заголовка X-Accel-Internal (без него mod_aclr будет обрабатывать запрос как обычный). Если контент - динамика, бек-енд выдает его в ответ фронт-енду, а тот уже - клиенту. Если контент - статика, модуль mod_aclr выдает фронт-енду пустой ответ с заголовком X-Accel-Redirect: /internal_xxx/uri/to/file.mp3. Nginx обрабатывает этот запрос через второй location, где установлен уже корень сайта, и выдает запрошенный файл своими силами.
Вариант 2 - без использования блоков server на каждый хост.
map $int_host $root {
default /path/to/server/no_server_found/;
server1.ru /path/to/server/1/;
server2.ru /path/to/server/2/;
}
server {
listen x.x.x.x;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Accel-Internal /internal;
proxy_set_header Host $http_host;
}
location /internal/ {
internal;
set $int_host $http_host;
root /$root;
rewrite ^/internal/(.*)$ /$1 break;
}
}
Данный вариант стал возможен начиная с одной из версий nginx, благодаря обработке переменных в директиве root. Тут все виртуальные хосты описаны в виде map блока, что занимает значительно меньше памяти в сравнении с 1-м вариантом.
Безопасность
Схема редиректов вносит потенциальную дыру в безопасности масс-хостинга, о которой следует упомянуть. Речь идет о случаях, когда клиент, используя свои скрипты, может сам выдать заголовок X-Accel-Redirect. Теоретически там может быть редирект на чужой файл (т.е. файл другого клиента). Хотя X-Accel-Redirect не может содержать имя хоста и отсчитывается от текущего root, об этой проблеме следует помнить при создании собственной конфигурации.
Скачать
Текущая версия: 0.04
По ссылке http://miksir.maker.ru/mod_aclr/mod_aclr.c - всегда последняя версия
Номер версии http://miksir.maker.ru/mod_aclr/VERSION
Установка
Модуль устанавливается стандартно. Предпочтительнее использование apxs. Пример:
/usr/local/apache/bin/apxs -c mod_aclr.c - компиляция модуля
/usr/local/apache/bin/apxs -i mod_aclr.so - инсталяция модуля
После этого следует прописать загрузку модуля директивами
LoadModule aclr_module libexec/mod_aclr.so
AddModule mod_aclr.c
в начало списка модулей (самым верхним)
Известные проблемы
Решения для апача 2.x нет
Изменения
0.04
Исправлена коллизия с именем функции parse_bytes из libroken (спасибо Alex Vorona)
0.03
Теперь собирается и на FreeBSD 4.11 (патч прислал Yevgeniy Kruglov)
0.02
Добавлены отладочные директивы и директива управления ими
Поправлена работа с SSI (модуль пытался обрабатывать внутренние подзапросы apache)
Добавлена обработка макроса %host% в заголовке X-Accel-Internal
0.01
Начало