Делегирование обратной зоны подсети менее /24 в BIND. Как это работает

Встала однажды передо мной задача, отдать одному из клиентов право на редактирование PTR-записей отданной ему подсети /28. Автоматизации для редактирования настроек BIND извне у меня нет. Поэтому я решил пойти другим путем — делегировать клиенту кусок PTR-зоны подсети /24.

Казалось бы — что может быть проще? Просто нужным образом прописываем подсеть и направляем на нужный NS как это делается с поддоменом. Но нет. Не так все просто (хотя на деле вообще примитивно, но интуиция не поможет ), поэтому я и пишу эту статью.

Кто захочет сам разобраться, тот может почитать RFC
Кто хочет готового решения, добро пожаловать под кат.

Чтобы не задерживать тех, кто любит метод копипасты, сначала я размещу практическую часть, а после нее теоретическую.

1. Практика. Делегируем зону /28

Допустим у нас есть подсеть 7.8.9.0/24. Нам надо делегировать подсеть 7.8.9.240/28 на днс-клиента 7.8.7.8 (ns1.client.domain).

На провайдерском днс надо найти файл, описывающий обратную зону этой подсети. Пусть будет 9.8.7.in-addr.arpa.
Записи от 240 до 255 комментируем, если есть. И в конец файла пишем следующее:

255-240  IN  NS      7.8.7.8
$GENERATE 240-255 $ CNAME $.255-240

не забываем увеличить serial зоны и делаем

rndc reload

На этом провайдерская часть закончена. Переходим к клиентскому днс.

Для начала создадим файл /etc/bind/master/255-240.9.8.7.in-addr.arpa следующего содержания:

$ORIGIN 255-240.9.8.7.in-addr.arpa.
$TTL 1W
@                       1D IN SOA       ns1.client.domain. root.client.domain. (
                        2008152607      ; serial
                        3H              ; refresh
                        15M             ; retry
                        1W              ; expiry
                        1D )            ; minimum
@                       IN NS        ns1.client.domain.
@                       IN NS        ns2.client.domain.
241                     IN PTR          test.client.domain.
242                     IN PTR          test2.client.domain.
245                     IN PTR          test5.client.domain.

И в named.conf дописываем описание нашего нового файла:

zone "255-240.9.8.7.in-addr.arpa." IN {
        type master;
        file "master/255-240.9.8.7.in-addr.arpa";
};

B перезапускаем процесс bind.

/etc/init.d/named restart

Все. Теперь можно проверять.

#>  host 7.8.9.245 
245.9.8.7.in-addr.arpa is an alias for 245.255-240.9.8.7.in-addr.arpa.
245.255-240.9.8.7.in-addr.arpa domain name pointer test5.client.domain.

Обратите внимание, что отдается не только PTR-запись и но и CNAME. Так и должно быть. Если интересно почему, то добро пожаловать в следующую главу.

2. Теория. Как это работает.

Сложно настраивать и отлаживать черный ящик. Гораздо проще, если понимаешь что происходит внутри.

Когда мы делегируем поддомен в домене domain, то пишем что-то вроде этого:

client.domain.	NS	ns1.client.domain.
ns1.client.domain.	A	7.8.7.8

Мы говорим всем спрашивающим, что за этот участок не отвечаем и говорим кто отвечает. И все запросы на client.domain редиректятся на 7.8.7.8. При проверке мы видим следующую картину (опустим что там у клиента. это неважно):

# host test.client.domain
test.client.domain has address 7.8.9.241

Т.е. нам сообщили, что есть такая А запись и ее ip 7.8.9.241. Никакой лишней информации.

А как то же самое можно сделать с подсетью?

Т.к. наш DNS-сервер прописан в RIPE, то при запросе PTR ip-адреса из нашей сети, все равно первый запрос будет к нам. Логика та же что и с доменами. Вот только как вписать подсеть в файл зоны?

Пробуем вписать вот так:

255-240  IN  NS      7.8.7.8

И… чуда не произошло. Мы не получаем никакого перенаправления запроса. Все дело в том, что bind вообще не в курсе что вот эти записи в файле обратной зоны это ip-адреса и уж тем более не понимает запись диапазона. Для него это просто некий символьный поддомен. Т.е. для bind не будет разницы между «255-240» и «oursuperclient«. И запрос чтобы запрос ушел куда надо, адрес в запросе должен выглядеть вот так: 241.255-240.9.8.7.in-addr.arpa. Или вот так, если мы используем символьный поддомен: 241.oursuperclient.9.8.7.in-addr.arpa. Это отличается от обычного: 241.9.8.7.in-addr.arpa.

Руками такой запрос будет сделать проблематично. А если и получится, то все равно непонятно как это применить в реальной жизни. Ведь по запросу 7.8.9.241 нам по прежнему отвечает провайдерский DNS, а не клиентский.

А вот тут в игру вступают CNAME.

На стороне провайдера нужно сделать для всех ip-адресов подсети алиас в формат, который переправит запрос клиентскому DNS.

255-240  IN  NS      ns1.client.domain.
241     IN  CNAME   241.255-240
242     IN  CNAME   242.255-240
и т.д.

Это для трудолюбивых =).

А для ленивых больше подойдет конструкция ниже:

255-240  IN  NS      ns1.client.domain.
$GENERATE 240-255 $ CNAME $.255-240

Теперь запрос информации по адресу 7.8.9.241 из 241.9.8.7.in-addr.arpa на днс-сервере провайдера будет преобразован в 241.255-240.9.8.7.in-addr.arpa и уйдет на днс-клиента.

Со стороны клиента нужно будет обрабатывать такие запросы. Соответственно мы создаем зону 255-240.9.8.7.in-addr.arpa. В ней мы в принципе можем размещать обратные записи для любых ip всей подсети /24, но спрашивать у нас будут только про те, которые провайдер к нам переадресует, так что побаловаться не получится =).
Для иллюстрации еще раз приведу пример содержания файла обратной зоны со стороны клиента:

$ORIGIN 255-240.9.8.7.in-addr.arpa.
$TTL 1W
@                       1D IN SOA       ns1.client.domain. root.client.domain. (
                        2008152607      ; serial
                        3H              ; refresh
                        15M             ; retry
                        1W              ; expiry
                        1D )            ; minimum
@                       IN NS        ns1.client.domain.
@                       IN NS        ns2.client.domain.
241                     IN PTR          test.client.domain.
242                     IN PTR          test2.client.domain.
245                     IN PTR          test5.client.domain.

Вот из-за того, что мы со стороны провайдера используем CNAME, то и получаем в ответ на запрос данных по ip-адресу две записи, а не одну.

#>  host 7.8.9.245 
245.9.8.7.in-addr.arpa is an alias for 245.255-240.9.8.7.in-addr.arpa.
245.255-240.9.8.7.in-addr.arpa domain name pointer test5.client.domain.

И не забывайте корректно настраивать ACL. Потому что бессмысленно забирать себе PTR-зону и не отвечать никому из внешки =).

Источник: habr.com