Модуль nginx HTTP rDNS

Модуль ngx_http_rdns_module реализует в веб-сервере nginx следующие возможности:

  • преобразование IP-адреса клиента в доменное имя;
  • создание простых списков контроля доступа (разрешить / запретить) на основе полученного доменного имени.

При этом ngx_http_rdns_module поддерживает модуль rewrite для динамического включения / выключения внутри директив if.

English description

For English documentation on this module, please refer to the README.md file or project's GitHub page.

Общие сведения

  • Язык программирования: Си.
  • Лицензия: BSD.
  • Авторы оригинальной версии: Дмитрий Столяров и Тимофей Кириллов.
  • Исходный код: GitHub.

Пример использования

location / {
    resolver 127.0.0.1;

    rdns_deny badone\.example\.com;

    if ($http_user_agent ~* FooAgent) {
        rdns on;
    }

    if ($rdns_hostname ~* (foo\.example\.com)) {
        set $myvar foo;
    }

    #...
}

При такой конфигурации nginx для каждого HTTP-запроса от клиента с User Agent, установленным в FooAgent, будет осуществляться обратный DNS-запрос (rDNS) для определения хоста по IP-адресу клиента. В качестве DNS-сервера для rDNS-запросов будет использоваться 127.0.0.1 (для этого используется стандартная директива nginx — resolver). Если хост клиента определится как badone.example.com, то запрос будет отклонён.

Для каждого запроса от FooAgent в переменной $rdns_hostname будет храниться результат rDNS-запроса (имя хоста) или строка «not found» (если хост не определён или произошла ошибка). Для запросов от всех остальных клиентов $rdns_hostname будет определена как «-».

Директивы

rdns

  • Синтаксис: rdns on | off | double
  • Умолчание: —
  • Контекст: http, server, location, if-in-server, if-in-location
  • Фаза: rewrite
  • Переменные: rdns_hostname

Включает / выключает rDNS-запросы:

  • on — включить rDNS-запросы в текущем контексте.
  • double — включить двойные DNS-запросы в текущем контексте. Если обратный DNS-запрос завершился успешно и вернул хост, модуль выполнит прямой DNS-запрос (для полуения исходного IP-адреса по хосту). Если прямой DNS-запрос выполнился с ошибкой или ни один из полученных IP-адресов не соответствует исходному, $rdns_hostname примет значение «not found».
  • off — отключить rDNS-запросы в текущем контексте.

Переменная $rdns_hostname может принимать следующие значения:

  • результат rDNS-запроса (имя хоста клиента);
  • строку «not found», если имя хоста не было получено или произошла ошибка во время его получения;
  • строку «-», если rDNS-запрос для этого HTTP-запроса не выполнялся.

После выполнения rDNS-запроса модуль сбрасывает фазу обработки внешнего запроса на NGX_HTTP_FIND_CONFIG_PHASE, чтобы сделать новую переменную $rdns_hostname видимой другим директивам.

Примечание по использованию директивы внутри «if» в блоках server и location: при выполнении директивы включения модуля (т.е. указании rdns on или rdns double) активируется rDNS-запрос и вызывается break (прекращает выполнение последующих директив внутри «if»). После того, как получен результат rDNS-запроса и фаза обработки внешнего запроса сброшена, все директивы внутри «if» выполняются снова, уже без вызова break. Отключение модуля (директива rdns off) никак не влияет на процесс выполнения последующих директив внутри «if».

Для работы этой директивы должна быть определена директива resolver из стандартной поставки nginx (она задаёт используемые DNS-серверы).

rdns_allow

  • Синтаксис: rdns_allow regex
  • Умолчание: —
  • Контекст: http, server, location
  • Фаза: access
  • Переменные: —

Разрешает доступ для домена, попадающего под регулярное выражение regex.

rdns_deny

  • Синтаксис: rdns_deny regex
  • Умолчание: —
  • Контекст: http, server, location
  • Фаза: access
  • Переменные: —

Запрещает доступ для домена, попадающего под регулярное выражение regex.

Примечания

Списки контроля доступа

Директивы rdns_allow и rdns_deny определяют новые списки контроля доступа для того контекста, в котором они используются.

Наследование списков контроля доступа в контекстах работает только в том случае, если у дочернего контекста не определены свои правила.

Именованные locations

Выполнение rDNS-запроса под именованным location не поддерживается и может привести к зацикливанию. Например:

server {
    rdns on;

    location / {
        echo_exec @foo;
    }

    location @foo {
        #...
    }
}

Дело в том, что nginx, «находясь» в именованном location, при сбросе фазы обработки запроса продолжает обработку не в именованном location, а в обычном. Поэтому, если в данном примере не выключить rdns в именованном location, возникнет цикл. Правильная конфигурация для приведённого примера должна выглядить следующим образом:

server {
    rdns on;

    location / {
        echo_exec @foo;
    }

    location @foo {
        rdns off;
        #...
    }
}

Документация на английском

Описание директив модуля и принципов его работы на английском языке доступно в файле README.md, входящем в состав модуля, и на странице проекта на GitHub.