Как правильно настроить DNS, чтобы потом не было мучительно больно…
28.01.2005 | admin

«Доменная система имен (Domain Name System, DNS) – это распределенная база данных, которая содержит информацию о компьютерах, включенных в сеть Internet.» (UNIX: руководство системного администратора, Эви Немет и др. Пер. с англ.)

Так начинается описание системы DNS в одной из лучших, на мой взгляд, книг по UNIX. Подобные утверждения можно встретить и во многих других книгах и статьях, посвященных DNS. Неудивительно, что в сознании людей система DNS оказывается неразрывно связанной с Internet. К несчастью, такая ассоциация оказывается крайне опасной для системного администратора. «Обращение к интернет-ресурсам по символическим именам происходит нормально,значит с DNS все в порядке» – администратор легко может впасть в подобное заблуждение под влиянием этой устойчивой ассоциации.

Типичная ситуация. Загружен новый сервер, пробуем зайти на него используя (ssh, ftp, pop3, smtp, telnet – недостающий протокол добавить ;-) ) с соседней машины в локальной сети. Обнаруживаем, что соединения приходится ждать пару минут… В чем дело? Одной из возможных причин может быть неверная настройка DNS на сервере.

Дело в том, что установление соответствия между именами и ip-адресами нужно не только пользователю. Многие программы – сервера пытаются определить имя машины клиента по ее ip-адресу. Зачем? А чтобы в лог записать – осуществлено, мол, соединение с машины с таким-то именем и таким-то ip. А если не удалось ip-адрес в имя преобразовать, то записывают – имя клиента определить не удалось, ip-адрес такой-то. Так работают, например, telnetd, wu-ftpd, postfix, imapd… Встречаются, впрочем, и программы, которые так не поступают, а пишут в логи только ip-адреса. Так работают, в частности, apache, squid, popa3d.

Кроме того, утилиты, предназначенные для диагностики состояния сети, также довольно часто по умолчанию пытаются выполнить трансляцию IP-адресов в символические имена. Так работают, например, netstat, traceroute, ipchains. Трансляцию адресов в них, впрочем, можно отключить, используя при вызове ключ -n Утилита ping, как правило, по умолчанию подобную трансляцию не выполняет. Впрочем из правила есть и исключения. О них дальше.

Посмотрим на примерах, к каким проблемам может привести некорректная настройка DNS

1. При инсталляции Linux программа установки предложила ввести адрес DNS сервера и при этом установила в этом поле значение по умолчанию, а Вы его оставили. Или же сами ввели ip-адрес DNS-сервера и ошиблись. Теперь Вы пытаетесь зайти с клиентской машины, к примеру, по ftp. Программа ftp-server пытается определить имя машины клиента. Допустим, в /etc/hosts его нет. Тогда она пытается использовать DNS. Шлет запрос к серверу на несуществующий IP-адрес, ждет… снова шлет запрос… снова ждет… наконец понимает, что больше пытаться не стоит, пишет в лог, что установлено соединение с таким-то ip-адресом. Все, теперь можно работать, но задержку в минуту – две таким образом вполне можно поиметь! При этом, что характерно, если на этой же машине запустить apache, то с ним клиенты будут работать без проблем. А если,скажем, после установки соединения с клиентом вызвать, например, netstat -a, то утилита отработает с изрядной задержкой. Все по той же причине – утилита долго и безуспешно будет пытаться определить символическое имя клиента. А вызов netstat -a -n отработает без всяких задержек. (Это, пожалуй, самый простой случай)

2. Вариация на тему: DNS задан правильно, но вот сетевое соединение между нашим сервером и сервером DNS ненадежное, пакетики теряются. Тот же результат.

3. Более сложная ситуация: корпоративная сеть со шлюзом для выхода в интернет. В сети две основные части: небольшая «демилитаризованная зона» с реальными IP-адресами и «внутренняя» с IP-адресами из диапазона private address space согласно RFC 1597. На стыке этих двух частей машина proxy и e-mail сервер. Она же – DNS-сервер для «демилитаризованной зоны» и кэширующий DNS-сервер для интернет. Используя собственный DNS, эта машина успешно разрешает в символические имена IP-адреса интернет-диапазона. А вот про адреса «внутренней» части сети система DNS «не знает». Тут картина будет более сложной, поскольку DNS сервер умеет кэшировать ответы на запросы. Как положительные, так и отрицательные. А через некоторое время кэш очищается. Что же происходит? Как я понимаю, примерно следующее: При первом запросе на преобразование в символическое имя IP-адреса из «внутренней» части сети сервер пробует сам это сделать, не может, шлет запросы к корневым серверам через internet, они тоже не могут… все это занимает значительное время и пользователь на машине-клиенте имеет изрядную задержку. Но отрицательный ответ кэшируется, и пока кэш не очищен, задержка при повторном обращении становится маленькой. Но если работает одновременно несколько клиентов, то может оказаться, что в момент повторного запроса DNS сервер будет обрабатывать другой «неразрешимый» запрос… Вобщем, получается крайне неприятная ситуация с «плавающей» ошибкой. Соединение устанавливается то быстро, то медленно и никакой разумной закономерности установить не удается.

Реальная история, кстати… Сколько я времени потратил, пока понял, в чем дело… врагу такого не пожелаю. Вылечил, кстати, очень просто. Для всех машин «внутренней» части сети были созданы фиктивные записи в файле /etc/hosts сервера. Примерно так:

172.16.1.1 pc01.l1
172.16.1.2 pc02.l1
172.16.1.3 pc03.l1

Можно было бы, конечно, прописать и реальные имена. Для удобства чтения логов.
Примечание: решение без использования /etc/hosts см. дальше (использование forward-зон)

4. Особенности конкретных дистрибутивов. В Black Cat Linux 6.2 (наверно и в Red Hat 6.2, соответственно) утилита ping по умолчанию пытается произвести трансляцию IP-адреса в символическое имя. Отменяется трансляция ключом -n (справедливости ради скажу, что с ftp можно скачать обновленную версию пакета, в которой эта особенность ликвидирована) Подвисание такого ping может означать не отсутствие связи с проверяемой машиной, а проблему с трансляцией ее IP-адреса в символическое имя. Попытка диагностирования проблем в сети с помощью такого ping‘а легко может поставить администратора в тупик. (Ну что можно сказать по поводу подобной «доработки» ping? Воистину «благими намерениями вымощена дорога в ад»)

Приведенные примеры показывают: к DNS нельзя относиться пренебрежительно.

Если на сервере включено использование DNS, то следует внимательно следить, чтобы ip-адреса всех машин-клиентов тем или иным способом разрешались в имена.

Несоблюдение этого принципа может привести к серьезным проблемам.

Использование forward – зон для одновременного разрешения Internet и Intranet имен

Предположим, что в у нас уже есть отдельный DNS-сервер для локальной сети и отдельный DNS-сервер для Internet. Оказывается, возможно (man named.conf) настроить машину так, чтобы для разных диапазонов IP-адресов использовались разные DNS сервера. Для этого на ней нужно запустить свой DNS-сервер, который бы перенаправлял поступающие на него запросы на другие DNS-сервера, в зависимости от того, какой запрос получен.

Пример: машина, работающая как с интернет, так и с локальной сетью. Для разрешения internet-адресов следует использовать существующий DNS сервер c IP-адресом 195.19.6.10 . Для разрешения intranet-адресов (Private диапазон 172.16.0.0) – существующий DNS сервер с IP-адресом 172.16.3.1 . В Intranet – сети используется «внутренний» домен первого уровня «cge». На машине запускаем локальный DNS сервер, и в дальнейшем используем его. Файлы конфигурации:

/etc/resolv.conf

nameserver 127.0.0.1

/etc/named.conf(bind 8.2.3)

options {
 directory "/var/named";
 forward first;
 forwarders {195.19.6.10;};
 // по умолчанию все запросы передаются
 // на DNS-server 195.19.6.10
};
//стандартная локальная зона
zone "0.0.127.in-addr.arpa" {
 type master;
 file "named.local";
};
//Эти правила - более приоритетные!
zone "16.172.in-addr.arpa" in{
 type forward;
 forward first;
 forwarders {172.16.3.1;};
 // для этой зоны все запросы передаются
 // на DNS-server 172.16.3.1
};
zone "cge" in{
 type forward;
 forward first;
 forwarders {172.16.3.1;};
 //для этой зоны все запросы передаются
 // на DNS-server 172.16.3.1
};

Примечание: Задача не решается простым прописыванием двух DNS-серверов в /etc/resolv.conf . Hint: Отрицательный ответ от одного DNS-сервера не является основанием для обращения к другому.

Еще одно возможное решение – вписать forward-зоны прямо на интернетовском DNS-сервере. Примерно так:

/etc/named.conf(bind 8.2.3)

zone "." {
 type hint;
 file "named.ca";
};

zone "0.0.127.in-addr.arpa" {
 type master;
 file "named.local";
};
//
// Прямая и обратная зоны домена cge.ru (Internet)
//
zone "cge.ru" in{
 type master;
 file "named_cge.data";
};

zone "6.19.195.in-addr.arpa" in{
 type master;
 file "named_cge.rev";
};
//
// Intranet сеть - 172.16.0.0, зона cge
// запросы переправляются на DNS сервер 172.16.3.1
//
zone "16.172.in-addr.arpa" in{
 type forward;
 forward only;
 forwarders {172.16.3.1;};
};

zone "cge" in{
 type forward;
 forward only;
 forwarders {172.16.3.1;};
};

Я проверил этот вариант, он работает, но имеет один недостаток – для forward-зон нельзя написать правила allow-query и allow-transfer, поэтому информация о структуре внутренних зон может быть прочитана любым желающим.

Все зоны на одном DNS-сервере

Возможно, это самый лучший способ. Внутренняя зона поддерживается тем же DNS-сервером, что и внешняя, а чтобы извне нельзя было посмотреть структуру внутренних зон, для них пишутся правила allow-query и allow-transfer.

К сожалению, для того, чтобы использовать этот способ, мне пришлось бы поменять настройку DNS на всех машинах Intranet-сети. Увы, я не готов к подобному подвигу. ;-( Впрочем, если ваша сеть находится еще в процессе становления, этот способ легко применим.

Автор: Александр Жегалло

Просмотров новости: 40 285  <, , >


-->