Доменная система имен - основа всей сети, поэтому обустроить свой "именной" уголок безопасно и корректно - одна из основных задач администратора.
djbdns - три в одном
Знакомься: djbdns - полноценная реализация для работы с DNS от Дэна Бернштейна. Как нельзя лучше подходит для решения именно этой проблемы. Итак, настройки требует DNS-сервер, который предоставлял бы внешним машинам информацию о нашей зоне, а клиентам Сети - информацию об адресах машин в интернете. Если ты имел дело с BIND, то знаешь, что он "и швец, и жнец, и на дуде игрец", то есть в зависимости от настроек может и держать зону, и играть роль кеширующего сервера/форвардера, и отдавать зону slave-серверам. Это не самое элегантное решение, что доказывает богатая история уязвимостей BIND и постоянные проблемы с его корректной настройкой у начинающих администраторов. Как же должно быть? Так, как в пакете djbdns, который представляет собой набор из трех основных программ: tinydns (не умеет ничего кроме как обслуживать зоны); dnscache (отвечает лишь за кеширование и разрешение внешних имен); axfrdns (занимается отдачей зон tinydns'a slave-серверам, точнее named'ам, так как для распространения зоны между двумя tinydns djb предлагает другие механизмы). Почему все так сложно? Эти три программы функционируют независимо друг от друга, и не существует даже теоретической возможности, например, некорректно настроить DNS-сервер так, чтобы он отвечал на рекурсивные запросы (такие сервера часто используются для DDoS-атак), или удаленно получить контроль над кешем (доступный для соединений извне tinydns не работает с кешем).
Будем считать, что у нас в распоряжении вторичный DNS-сервер BIND. Разгуляемся по полной настроив dnscache, tinynds и axfrdns. Если ты когда-нибудь имел дело с BIND, то постарайся забыть все, что ты знал о нем :). Если нет - тем лучше для твоей психики: named, как правило, слушает на всех доступных интерфейсах, принимая запросы на внутреннем интерфейсе от клиентов для разрешения имен внешних машин, а на внешнем интерфейсе - от серверов для предоставления информации о машинах в своей зоне и трансфера зоны вторичным серверам. Разбивая систему на функциональности, получаем следующую картину: на внутренний интерфейс приходят исключительно пользовательские запросы. Значит, на него нужно повесить dnscache, который будет резолвить адреса внешних машин и кешировать результат.
На внешний интерфейс приходят запросы к нашей зоне как на разрешение имен, так и на трансфер. Значит, на него повесим tinydns, который понятия не имеет, что такое рекурсивные запросы, и отвечает только на запросы своей зоны, и axfrdns, который будет отдавать зону определенным slave-серверам. В качестве ОС для построения DNS-сервера избираем FreeBSD. Но о вкусах не спорят. Все нижеизложенные инструкции легко можно применить и к Linux/OpenBSD/NetBSD и т.д.
# cd /usr/ports/dns/djbdns && make install clean
Добавляем пользователей для работы dnscache, tinydns и axfrdns, так как в целях безопасности каждый из демонов запускается под своей учетной записью. Обработчик логов запускается под отдельной учетной записью dnslog:
Ждем секунд десять и передаем проверку работы dnscache утилите из daemontools svstat:
# svstat /var/service/dnscache
/var/service/dnscache: up (pid 13722) 13 seconds
И все. Никаких проблем с named.conf. Софт djb вообще отличается тем, что его можно конфигурировать с помощью команды echo ;). Прописываем 192.168.0.1 в качестве nameserver:
# echo nameserver 192.168.0.1 > /etc/resolv.conf
DNS на страже имен
На очереди ответственный за зону DNS-сервер – tinydns, который конфигурируется похожим образом (заметь, что он вешается на внешний интерфейс):
Как только речь заходит о настройке зоны DNS, в голове сразу возникают ассоциации с ворохом файлов в namedb: опечатки, когда ничего не работает из-за того, что забыл поставить точку, неочевидный синтаксис конфигурационных файлов и прочие радости сношения с пакетом BIND.
Можешь расслабиться. Разумеется, чтобы понять все тонкости настройки, тебе придется прочитать документацию к tinydns, однако смотри пример создания зоны с SOA двумя MX-записями и несколькими хостами. И если ты скажешь, что это сложно, то ты - мой злейший враг на всю жизнь ;).
# cd /usr/local/etc/djbdns/ext_tinydns/root
# vi data
.mydomain.ru:11.22.33.44:ns.mydomain.ru
.33.22.11.in-addr.arpa:11.22.33.44
@ank-pki.ru:11.22.33.44:mail.mydomain.ru:0
@ank-pki.ru:11.22.33.50:mx1.mydomain.ru:10
host1.mydomain.ru:11.22.33.45
= host2.mydomain.ru:11.22.33.46
= host3.mydomain.ru:11.22.33.47
Cwww.mydomain.ru:host1.mydomain.ru
Cjabber.mydomain.ru:host2.mydomain.ru
# make
Как видно, каждая запись предваряется типом. Точка - SOA, @ - MX, = - A и PTR запись одновременно, C - CNAME. Очевидно, мы присвоили хосту 11.22.33.44 имя ns.mydomain.ru, он же - mail.mydomain.ru. Второй почтовый сервер, mx1.mydomain.ru, расположен по адресу 11.22.33.50 в этом же домене. host1-host3 - хосты, на которых крутятся сетевые сервисы. Jabber и www - алиасы, чтобы было понятно, что на host1 работает Apache, а на host2 - Jabberd. После правки конфигурационного файла набери make, чтобы программа tinydns-data перечитала его и обновила бинарный файл data.cdb. tinydns осуществляет поиск в бинарном файле, а не текстовых конфигурационных файлов, благодаря чему работает намного быстрее того же named. Кстати, файл можно не править вручную: в том же каталоге присутствуют скрипты для добавления записей. И тут у тебя просто начинает проситься наружу вопрос: "Как же dnscache и tinydns будут уживаться на одной машине, если за резолвом машины из mydomain.ru dnscache полезет в интернет, а машина - вот она, тут же". "Склеить" два демона можно таким образом:
Замечу, что если провайдер не делегировал тебе обратную зону, то заморачиваться с in-addr.arpa вряд ли имеет смысл, так как в глобальном масштабе твой сервер будет не прав: он необоснованно считает себя ответственным за обратную зону.
Синхронизируем зону
Осталось только отдать нашу зону вторичному серверу. Как правило, чаще всего таким сервером бывает BIND. Конфигурируем axfrdns уже до боли знакомым образом:
Добавился новый аргумент - путь к месту расположения конфигурационных файлов tinydns. Не пугайся, что axfrdns слушает на том же интерфейсе, что и tinydns: он bind’ит порт 53/tcp, тогда как tinydns - 53/udp (named для трансфера зоны использует протокол TCP). Настроив BIND как slave, разрешим ему стягивать зону.
Вот так и была установлена переменная AXFR для хоста 22.33.44.55 (это адрес вторичного сервера) в значение "mydomain.ru". Это значит, что axfrdns позволит передачу соответствующей зоны машине 22.33.44.55.
Ну а что если твой slave тоже использует tinydns? Например, если ты отвечаешь и за первичный, и за вторичный серверы. Тогда синхронизировать зоны можно и без axfrdns. DJB предлагает не изобретать велосипед в виде 53/tcp, а использовать удобный и безопасный способ - rsync over ssh. Для чего потребуется всего три шага:
- Создаем на slave-сервере отдельного пользователя, который будет владеть базой имен (файл data.cdb), которая подлежит синхронизации. Ничто не мешает использовать рабочий логин:
Теперь при внесении изменений на первичном сервере и при последующем обновлении data.cdb командой make данные обновятся и на вторичном сервере. Так как используется rsync (естественно, пакет rsync не входит в базовую поставку FreeBSD, поставь его из порта net/rsync). По Сети будут переданы лишь изменения, а не весь data.cdb. Если ты настроишь ssh-авторизацию по ключам, у тебя даже пароля не попросят :).
Что получили в результате? Dnscache знай себе кеширует запросы из локальной сети, tinydns спокойно и размеренно рассказывает внешним машинам о хостах нашего домена, ну а axfrdns помогает тем несчастным, которые еще используют BIND, стягивать нашу name-зону. Теперь ты можешь смело оставить свой сервер жить своей жизнью - патчить djbdns тебе не придется. Ну а если возникнут какие проблемы, знай, что www.google.com не собирается менять свой URL ;).
Порядок делегирования зоны
Очень важно помнить последовательность добавления вторичных серверов и не совершать популярной ошибки под названием lame delegation. Правильный порядок действия таков.
1. Настроить вторичный dns-сервер на получение зоны c первичного.
2. Разрешить на первичном сервере трансфер зоны вторичным dns-сервером. В случае BIND эта процедура включает в себя правку конфигурационных фалов named.conf на обоих серверах, открытие портов 53/tcp на соответствующие хосты, просмотр логов named на наличие ошибок и т.д. В случае tinydns эта процедура сводится к прописыванию одной строчки в Makefile. Если что не так, rsync тут же выдаст на консоль диагностические ошибки.
3. Добавить в конфиг зоны первичного сервера NS-запись, указывающую на новый вторичный сервер.
4. Если новый вторичный сервер входит в обслуживаемую зону, добавить соответствующую A-запись.
5. Сообщить вышестоящему регистратору о новом сервере имен для своей зоны. Как правило, это делается через web-формы администрирования соответствующего держателя вышестоящего домена (domainpeople.com, nic.ru, etc).
Очень часто забывают выполнить третий пункт, и тогда информация на вышестоящих серверах имен о NS'ах твоей зоны не совпадает с информацией о таковых, полученных непосредственно с них самих. Вся беда в том, что ответ твоих name-серверов считается авторитетным, тогда как ответ вышестоящих - нет. Это и называется lame delegation: dns-сервер является вторичным для зоны, но сам об этом не знает.