Настройка Response Policy Zone (RPZ) в BIND9

BIND9 имеет очень интересный функционал DNS, который не описан в каких-либо официальных спецификациях RFC. Называется он – Response Policy Zone. Если говорить подробнее, RPZ позволяет переопределять ответы DNS для доменных имен так, как вам хочется. Клиенту может быть возвращено сообщение, что домен не существует или можно вернуть совсем другой адрес – например адрес локального сервера, на котором размещена дефолтная страничка с информацией о политиках, запрещающих посещение данного ресурса (как на счет блокировки vk.com в корпоративной сети?).

В этой статье поговорим как настроить этот замечательный (для админа, но не всегда для юзера) функционал.


Если вам интересно подробнее изучить задачи администрирования BIND9, рекомендую обратиться к соответствующему тегу на моем блоге.


Настройка Response Policy Zone в BIND9

Помимо настройки сервиса также расскажу об основных нюансах работы RPZ и ситуациях, которые могут вам встретиться.

Окружение

Предполагаю, что сервер BIND9 у вас уже установлен и возможно даже настроен. Если нет, вы можете это сделать на основе моих предыдущих статей (Сервер пересылки на BIND9 и Настройка представлений (View) в BIND9). Настоятельно рекомендую настроить утилиту rndc. Это крайне желательно, но на самом деле не обязательно.

Примечание: если не настроили rndc, то просто вместо команды rndc reload выполняйте обычный перезапуск демона – systemctl restart bind9.

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

Настройка

Для настройки функционала RPZ основная секция конфигурации options {} обязательно должна содержать директиву response-policy:

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

  • given – политика по умолчанию, не требуется прописывать в явном виде (выше в конфиге указана для наглядности). Для каждой записи выполняет действия, определенные внутри файла зоны;
  • disabled – отключает все действия, определенные в файле зоны, но логирует “попадание” запросов;
  • passthru – отвечать на запросы так, как будто нет никаких политик RPZ;
  • drop – не возвращает клиенту никакого ответа, в итоге он получит ответ connection timed out;
  • nxdomain – будет возвращен ответ о не существующем домене – NXDOMAIN;
  • nodata – будет возвращен ответ об отсутствии данных – NODATA;
  • tcp-only – отправляет урезанное сообщение, что вынуждает клиента выполнить повторный запрос, но уже по TCP;
  • cname domain – будет возвращать запись CNAME с указанным доменом в ответ на запрос любой записи внутри файла зоны.

Следующим шагом нужно задать зону точно также, как это делается в обычных случаях. Например зона может быть внутри представления:

Имя зоны должно совпадать с именем внутри директивы response-policy. Также указанная зона “rpz” должна содержаться в каждом представлении, если у вас их несколько. Иначе получите ошибку наподобие этой:

Ну а теперь рассмотрим возможное содержимое файла зоны /etc/bind/rpz/local.zone:

Хоть в файле и присутствуют записи SOA и NS, они служат лишь для формальной совместимости, ведь зоны RPZ по сути имеют вид и свойства самых обычных зон и поддерживают передачи.

Тестирование

Самое время протестировать как работает функционал RPZ, который мы только что настроили. Итак, по очереди запросим каждое имя, заданное в зоне local.zone.

1. Начнем с CNAME-записи:

192.168.1.1 – адрес нашего днс-сервера. Результат запроса (status: NXDOMAIN):

2. Следующий запрос:

Результат:

3. Запрос:

Результат (status: NOERROR – возвращен реальный публичный адрес доменного имени blog.bissquit.com):

4. Запрос:

Ответ (connection timed out):

5. Запрос:

С ответом в этом случае все несколько сложнее, ведь мы должны убедиться в том, что сервер вынуждает клиента обратиться именно по tcp, хотя по умолчанию используется udp. Проверить это можно с помощью tcpdump, перехватив трафик с сервера. Команда будет иметь вид (запускать с сервера bind):

Если вывод от tcpdump пришел, значит обращение идет именно по tcp. В противном случае используется udp и вывод tcpdump будет пустой (убедитесь в этом на запросах других записей):

6. Ну а теперь самый любопытный момент – посмотрим какой ответ возвращает BIND9 на запрос MX-записи:

Ответ:

Если вы заметили, то MX-запись ссылается имя mail.bissquit.com.rpz.. Почему так происходит и что с этим делать, разберемся в главе ниже.

Особенности работы

Ниже расскажу о некоторых нюансах работы, некоторые из них прямо или косвенно связаны с RPZ.

$ORIGIN в RPZ

Перед тем как рассматривать особенности работы, лишний раз стоит напомнить о важности указания переменной $ORIGIN, особенно внутри файлов зон RPZ. Вот что пишут об этом в документации 1:

While it is always good practice to use an $ORIGIN name in every zone file it is practically essential for RPZ domains. BIND9 will synthesize missing $ORIGIN names from the name used in the zone file but this can have unintended side effects and reduce flexibility in zone naming…

$ORIGIN содержит суффикс, который используется для получения fqdn из не полностью квалифицированных записей зоны (записи, у которых в конце нет точки 2), если вы вдруг забыли.

В ответе сервера на запрос MX содержатся следующие строчки:

bissquit.com ссылается на странную запись mail.bissquit.com.rpz. На самом деле ничего странного в ней нет, поскольку в файле зоны все записи определены неявно (без точки в конце). Это значит, что в самый конец каждой записи будет дописано значение из переменной $ORIGIN (так и должно быть), либо имя файла зоны, если $ORIGIN пустая (а так лучше не делать).

Примечание:  у вас может возникнуть желание дописать точку в конце каждого имени и это действительно можно сделать, но работать как нужно не будет.

Ничего страшного в таком поведении нет, ведь для клиента важно получить конечный адрес, на который ссылается запись mail.bissquit.com.rpz.. Он его получает чуть ниже (см. полный ответ бинда выше):

Хотя так может получаться не всегда. Почему, читайте ниже.

Additional section

Когда клиент запрашивает разрешение днс-записи у сервера, помимо основной секции ответа – ANSWER SECTION – он может получить также и дополнительную секцию – ADDITIONAL SECTION. Её цель – предоставить клиенту ответ по тем днс-записям, которые клиент может запросить сразу после получения основного ответа. Это особенно актуально для таких записей как MX, NS.

Примечание:  стоит напомнить, что MX ссылается на одну или несколько А-записей. Эти А-записи также необходимо разрешить, чтобы получить ip-адрес, на который уже можно будет отправить почту.

Днс-сервер “предугадывает” следующее действие клиента и просто сразу засовывает в ADDITIONAL SECTION разрешенные А-записи. Так проще всем.

Тем не менее бывают ситуации, когда ADDITIONAL SECTION может не содержаться в ответе сервера. Это нормальная ситуация, поскольку, строго говоря, наличие ADDITIONAL SECTION необязательно. Это заставит клиента разрешить А-записи, но уже в следующем запросе. Если бинд получит запрос на разрешение записи из зоны RPZ, он не растеряется и возвратит что надо:

Ответ:

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

В большинстве случаев промежуточный сервер пересылки просто передаст ответ от бинда клиенту в том виде, в котором его отдаст бинд. Однако иногда может случиться так, что по каким-то причинам промежуточный сервер удалит ADDITIONAL SECTION из ответа бинда. Соответственно клиент должен будет запросить А-запись(и) у промежуточного сервера. В обычной ситуации запрос какой-либо несуществующей зоны (в моем случае .rpz) заставит промежуточный сервер сильно загрустить, правильного ответа клиенту он не вернет.

Примечание:  если вдруг используете одноуровневый домен совсем как у меня (.rpz), то позаботьтесь о том, чтобы такого домена в реальности не существовало. Это можно проверить вот на этой странице.

Существует три решение данной проблемы:

  1. Заставить клиента напрямую обращаться к бинду (самый простой и правильный вариант);
  2. Создать на промежуточном сервере зону-форвардер .rpz (это в моем случае, у вас будет другое имя).
  3. Прописать бинд в качестве форвардера на промежуточном сервере (этот вариант вообще не всегда возможен, да и гипотетически может создавать некоторое подобие “петель”)

Будьте аккуратны с ADDITIONAL SECTION.

Связанность записей внутри зоны RPZ

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

… то непременно получите ошибку:

Также будьте внимательны например при создании сложных записей, таких как MX. Сначала вы задаете собственно саму запись MX, а потом А-записи как в примере ниже:

Записи должны быть не полностью квалифицированными (без точек в конце), иначе днс-сервер будет возвращать некорректный ответ.

Порядок опроса серверов

Может показаться, что как только вы запрашиваете какую-либо запись из зоны RPZ у бинда, он сразу возвращает вам ответ. На самом деле на стороне сервера все выглядит сложнее. Перед возвращением ответа он сначала лезет к публичным серверам (указаны в форвардерах), чтобы узнать а нет ли у них той записи, которую запрашивает клиент. Это поведение хорошо иллюстрирует дамп трафика на 53 порту:

*1.14 – сервер BIND9, *1.28 – клиент, запрашивающий MX-запись bissquit.com. Обратите внимание, запрашивается в т.ч. и запись PTR. Не удивляйтесь, если обращения к записям внутри RPZ генерируют доп. днс-трафик наружу.

Алгоритмы поведения клиентов DNS

Разные клиенты ведут себя по-разному. Особенно заметно различие между Windows- и Linux- клиентами. Например если вы попытаетесь с Windows-машины обратиться к бинду с командой:

То резолвер предпримет странную (на мой взгляд) попытку состряпать fqdn из запрашиваемого имени и всех дополнительных суффиксов по очереди.

Например у вас в системе заданы следующие сетевые настройки:

Перед запросом имени ns1.bissquit.com резолвер захочет узнать а нет ли у сервера имен ns1.bissquit.com.tratata.local, ns1.bissquit.com.localhost.localdomain и ns1.bissquit.com.bq.local.. В этом легко убедиться, заглянув в логи (либо перехватить сессию с помощью tcpdump, как удобно):

Linux-клиенты такое не вытворяют. Так что не паникуйте, если среди статистики запросов на вашем бинде начнет проскакивать аномально большое количество NXDOMAIN (как мониторить бинды я расскажу в следующих статьях).

Итоговые конфиги

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

1. /etc/bind/named.conf:

2. /etc/bind/named.conf.options:

3. /etc/bind/

4. /etc/bind/

5. /etc/bind/

6. Файлы db.* идут в дефолтной конфигурации бинда и я их не менял.

Яндекс.Метрика