Динамические модули Nginx: полное руководство по сборке, подключению и управлению | AdminWiki

Динамические модули Nginx: полное руководство по сборке, подключению и управлению

26 июля 2026 9 мин. чтения

Динамический модуль Nginx - это разделяемая библиотека (.so), которую веб-сервер загружает во время запуска или перезагрузки конфигурации. Вы получаете возможность добавлять функциональность - авторизацию, сжатие, балансировку, защиту - без полной перекомпиляции основного бинарного файла. Директива load_module подключает готовый модуль, а флаг --add-dynamic-module при сборке из исходников создаёт такой модуль.

Этот подход решает главную проблему: раньше для подключения стороннего расширения требовалось пересобрать Nginx целиком. Теперь достаточно заменить один .so-файл и перезагрузить конфигурацию. Материал построен на практических сценариях - вы пройдёте путь от подготовки окружения до диагностики ошибок совместимости.

Что такое динамические модули Nginx и зачем они нужны

Nginx с момента версии 1.9.11 поддерживает динамическую загрузку модулей. До этого все расширения вкомпилировались статически на этапе сборки. Статическая компоновка даёт минимальный выигрыш в производительности за счёт отсутствия накладных расходов на загрузку разделяемых библиотек, но жёстко привязывает функциональность к конкретному бинарному файлу.

Динамический модуль - это файл с расширением .so, который Nginx загружает в память при старте. Вы можете подключить модуль, предоставленный разработчиком дистрибутива, или собрать собственный из исходников. После добавления директивы load_module в конфигурацию и перезагрузки сервера новая функциональность активируется. Для отключения достаточно закомментировать строку и перезагрузить Nginx.

Типовые задачи, решаемые динамическими модулями:

  • Делегированная аутентификация через ngx_http_auth_request_module
  • Отдача предварительно сжатых файлов через ngx_http_gzip_static_module
  • Балансировка нагрузки с альтернативными алгоритмами, например ngx_http_upstream_fair_module
  • Защита от DDoS-атак и фильтрация трафика
  • Интеграция с языками программирования через модули вроде ngx_http_lua_module

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

Сборка динамического модуля из исходников

Самостоятельная компиляция требуется, когда нужный модуль отсутствует в пакетном менеджере вашего дистрибутива или когда необходима специфичная версия. Процесс состоит из трёх этапов: подготовка окружения, конфигурирование с флагом --add-dynamic-module и компиляция.

Подготовка сборочного окружения

Для компиляции модулей Nginx необходимы те же зависимости, что и для сборки самого веб-сервера. Установите пакеты:

# Debian/Ubuntu
apt-get install build-essential libpcre3-dev zlib1g-dev libssl-dev

# CentOS/RHEL
yum groupinstall "Development Tools"
yum install pcre-devel zlib-devel openssl-devel

Загрузите исходники Nginx той же версии, которая работает на вашем сервере. Проверьте текущую версию командой nginx -v. Скачайте соответствующий архив с официального сайта:

wget http://nginx.org/download/nginx-1.26.0.tar.gz
tar -xzf nginx-1.26.0.tar.gz

Исходники модуля получите из репозитория разработчика. Для примера возьмём ngx_http_auth_request_module - он уже включён в стандартную поставку Nginx как опциональный, но демонстрирует общий принцип. Сторонние модули клонируются через git:

git clone https://github.com/gnosek/nginx-upstream-fair.git

Критически важно: версия исходников Nginx должна совпадать с версией установленного экземпляра. Несовпадение приведёт к ошибке «module is not binary compatible» при загрузке.

Конфигурирование и компиляция с --add-dynamic-module

Перейдите в директорию с исходниками Nginx и запустите ./configure с флагом --add-dynamic-module. Флаг принимает путь к директории с исходным кодом модуля:

cd nginx-1.26.0
./configure --add-dynamic-module=../nginx-upstream-fair

Вы можете указать несколько модулей одновременно, перечислив флаги последовательно:

./configure \
  --add-dynamic-module=../module-one \
  --add-dynamic-module=../module-two

После конфигурирования запустите компиляцию только модулей. Команда make modules собирает исключительно динамические расширения, не затрагивая основной бинарный файл. Это быстрее и безопаснее, чем полная сборка:

make modules

Собранные .so-файлы находятся в поддиректории objs/. Скопируйте их в каталог модулей Nginx:

cp objs/*.so /etc/nginx/modules/

Путь /etc/nginx/modules/ - общепринятый, но вы можете выбрать любое расположение. Главное - указать корректный путь в директиве load_module.

Подключение динамического модуля в работающий Nginx

Активация модуля выполняется добавлением одной строки в конфигурацию и последующей перезагрузкой сервера. Процедура безопасна: Nginx проверяет синтаксис и совместимость модуля до применения изменений.

Синтаксис директивы load_module

Директива load_module размещается на верхнем уровне конфигурационного файла nginx.conf, до блока events. Она принимает абсолютный или относительный путь к .so-файлу:

load_module /etc/nginx/modules/ngx_http_auth_request_module.so;

events {
    worker_connections 1024;
}

http {
    # основная конфигурация
}

Относительный путь отсчитывается от префикса сборки Nginx, обычно /etc/nginx/ или /usr/local/nginx/. Рекомендуем использовать абсолютные пути - это исключает неоднозначность.

Порядок загрузки модулей соответствует порядку директив в конфигурации. Если модуль B зависит от модуля A, директива для A должна располагаться выше. Дважды загрузить один модуль нельзя - Nginx выдаст ошибку при старте. Выгрузить модуль без перезапуска невозможно, поэтому для отключения требуется закомментировать директиву и перезагрузить сервер.

Проверка и активация модуля

Перед применением изменений проверьте синтаксис конфигурации:

nginx -t

Вывод syntax is ok и test is successful подтверждает корректность. При наличии ошибок вы получите точное указание на проблемную строку.

Для плавной перезагрузки без разрыва активных соединений используйте:

nginx -s reload

Убедиться, что модуль загружен, можно несколькими способами. Команда nginx -V 2>&1 показывает полную строку конфигурации сборки, включая статические модули. Для просмотра динамических модулей проверьте вывод на наличие load_module в работающей конфигурации или используйте специализированные страницы статуса. Детальный разбор методов диагностики мы приводили в статье о ключевых метриках мониторинга Nginx - там описаны инструменты для отслеживания состояния сервера.

Управление динамическими модулями: добавление, отключение, обновление

Жизненный цикл модуля включает три операции: первичное добавление, временное отключение и обновление до новой версии. Каждая операция выполняется без остановки сервера.

Добавление нового модуля: скопируйте .so-файл в директорию /etc/nginx/modules/, пропишите load_module в конфигурации, выполните nginx -t && nginx -s reload. Модуль активирован.

Отключение: закомментируйте строку load_module, проверьте конфигурацию и перезагрузите сервер. Функциональность модуля перестаёт работать, сам .so-файл остаётся на диске - его можно удалить позже.

Обновление модуля: замените .so-файл новым, сохранив прежнее имя и путь. Проверьте конфигурацию и выполните перезагрузку. Если модуль обрабатывает критичные запросы, рассмотрите staggered reload на кластере из нескольких экземпляров Nginx.

Обеспечение совместимости версий

Модуль должен быть собран для той же версии Nginx, в которую он загружается. Проверьте версию сервера:

nginx -v
# nginx version: nginx/1.26.0

При несовпадении версий вы получите ошибку:

nginx: [emerg] module "/etc/nginx/modules/ngx_http_example_module.so" is not binary compatible

Решение - пересборка модуля из исходников той же версии, что и установленный Nginx. Если вы обновили веб-сервер через пакетный менеджер, пересоберите все динамические модули заново.

Обновление модуля без простоя

Процедура безопасного обновления:

  1. Соберите новую версию модуля
  2. Скопируйте .so-файл во временное расположение
  3. Подмените старый файл новым атомарной операцией mv
  4. Выполните nginx -t
  5. Выполните nginx -s reload

Для кластерных конфигураций с балансировщиком нагрузки применяйте последовательную перезагрузку узлов. Выведите один сервер из балансировки, обновите модуль, перезагрузите, верните в кластер. Повторите для остальных узлов. Этот подход исключает деградацию сервиса при обновлении.

Практические примеры: авторизация, сжатие, балансировка

Разберём три рабочих кейса, которые покрывают наиболее частые запросы администраторов. Каждый пример содержит минимальную конфигурацию, готовую к адаптации под вашу среду.

Настройка делегированной аутентификации

Модуль ngx_http_auth_request_module перенаправляет проверку прав доступа на внутренний endpoint. Это позволяет реализовать централизованную аутентификацию без дублирования логики в каждом приложении.

Сборка модуля (включён в стандартные исходники Nginx как опциональный):

./configure --add-dynamic-module=src/http/modules/auth_request
make modules
cp objs/ngx_http_auth_request_module.so /etc/nginx/modules/

Конфигурация:

load_module /etc/nginx/modules/ngx_http_auth_request_module.so;

http {
    server {
        location /private/ {
            auth_request /auth;
            auth_request_set $auth_user $upstream_http_x_user;
            proxy_pass http://backend;
        }

        location = /auth {
            internal;
            proxy_pass http://auth-service/verify;
            proxy_pass_request_body off;
            proxy_set_header Content-Length "";
        }
    }
}

При запросе к /private/ Nginx отправляет подзапрос на /auth. Если сервис аутентификации возвращает 2xx, основной запрос проксируется на бэкенд. Код 401 или 403 от /auth немедленно возвращается клиенту.

Эффективное сжатие статических файлов

Модуль ngx_http_gzip_static_module отдаёт предварительно сжатые .gz-версии файлов, экономя процессорное время на динамическом сжатии. Подходит для статики, которая редко меняется: CSS, JavaScript, шрифты.

Сборка:

./configure --add-dynamic-module=src/http/modules/gzip_static
make modules
cp objs/ngx_http_gzip_static_module.so /etc/nginx/modules/

Конфигурация:

load_module /etc/nginx/modules/ngx_http_gzip_static_module.so;

http {
    server {
        location /static/ {
            gzip_static on;
            expires 30d;
            add_header Cache-Control "public, immutable";
        }
    }
}

Предварительно сожмите файлы утилитой gzip:

gzip -k -9 /var/www/static/style.css
# создаст /var/www/static/style.css.gz

Nginx отдаст .gz-файл клиентам, поддерживающим сжатие, без дополнительной нагрузки на CPU. Для клиентов без поддержки gzip отдаётся оригинальный файл.

Улучшенная балансировка нагрузки

Сторонний модуль ngx_http_upstream_fair_module реализует алгоритм балансировки, который распределяет запросы пропорционально загрузке бэкендов. В отличие от round-robin, он не отправляет новый запрос на занятый сервер.

Сборка:

git clone https://github.com/gnosek/nginx-upstream-fair.git
cd nginx-1.26.0
./configure --add-dynamic-module=../nginx-upstream-fair
make modules
cp objs/ngx_http_upstream_fair_module.so /etc/nginx/modules/

Конфигурация:

load_module /etc/nginx/modules/ngx_http_upstream_fair_module.so;

http {
    upstream backend_cluster {
        fair;
        server 10.0.1.10:8080;
        server 10.0.1.11:8080;
        server 10.0.1.12:8080;
        keepalive 32;
    }

    server {
        location / {
            proxy_pass http://backend_cluster;
        }
    }
}

Алгоритм fair полезен в сценариях с неоднородными запросами: когда одни запросы выполняются быстро, а другие требуют длительной обработки. Round-robin в таких условиях может перегрузить один из серверов, fair - нет. Для углублённого изучения балансировки ознакомьтесь с материалом Nginx как балансировщик нагрузки - там разобраны health checks и отказоустойчивость.

Диагностика и устранение ошибок при загрузке модулей

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

Ошибка «cannot open shared object file»

Полный текст ошибки:

nginx: [emerg] cannot open shared object file "/etc/nginx/modules/ngx_http_example_module.so": No such file or directory

Причины и решения:

  • Файл отсутствует по указанному пути - проверьте командой ls -la /etc/nginx/modules/
  • Опечатка в пути - скопируйте путь из ошибки и сверьте с реальным расположением
  • Недостаточно прав - установите chmod 644 на .so-файл и chown root:root
  • SELinux блокирует доступ - проверьте контекст безопасности: ls -Z /etc/nginx/modules/

Инструмент strace показывает системные вызовы и точно указывает, на каком этапе происходит сбой:

strace -e openat nginx -t 2>&1 | grep module_name

Ошибка «module is not binary compatible»

Эта ошибка означает, что модуль собран для другой версии Nginx. Сравните версии:

nginx -v
strings /etc/nginx/modules/ngx_http_example_module.so | grep "nginx version"

Решение - пересборка модуля из исходников той же версии, что и установленный Nginx. Если сервер обновлялся через пакетный менеджер, загрузите исходники соответствующей версии с официального сайта и повторите компиляцию.

Проверить зависимости модуля можно утилитой ldd:

ldd /etc/nginx/modules/ngx_http_example_module.so

Отсутствующие библиотеки помечаются как «not found». Установите недостающие пакеты и повторите загрузку модуля.

Рекомендация: все изменения с динамическими модулями сначала тестируйте в staging-среде, идентичной production по версиям ОС и Nginx. Это предотвратит падение боевого сервера из-за несовместимости.

Статические vs динамические модули: что выбрать

Выбор между статической и динамической загрузкой модуля определяется тремя факторами: производительностью, удобством сопровождения и политикой безопасности.

Статическая компиляция встраивает код модуля непосредственно в бинарный файл Nginx. Вызовы функций происходят напрямую, без накладных расходов на динамическое связывание. Разница в производительности составляет доли процента и заметна только на предельных нагрузках - от 50 000 одновременных соединений и выше. Статические модули нельзя отключить без перекомпиляции, что усложняет аудит безопасности и обновление.

Динамические модули загружаются во время выполнения. Накладные расходы - однократная операция связывания при старте, которая занимает миллисекунды. Вы получаете возможность добавлять и удалять функциональность правкой конфигурации, распространять модули отдельно от ядра и использовать сторонние расширения без модификации системных пакетов.

Рекомендации по выбору:

  • Стандартные модули из официальной поставки (http, stream, mail) - статическая компиляция, если вы собираете Nginx самостоятельно
  • Сторонние модули с активной разработкой - динамическая загрузка для упрощения обновлений
  • Редко используемые модули - динамическая загрузка, чтобы не увеличивать размер бинарного файла
  • Высоконагруженные системы с жёсткими требованиями к latency - статическая компиляция критичных модулей

Практическое правило: начинайте с динамических модулей. Если бенчмарки покажут, что накладные расходы на загрузку значимы для вашего сценария, переходите на статическую компоновку. Для 95% инсталляций разница незаметна. Дополнительные приёмы оптимизации конфигурации описаны в руководстве по настройке Nginx для высоконагруженных приложений.

Поделиться:
Сохранить гайд? В закладки браузера