"Старые песни о главном" |
"Доменная система имен (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, как
правило, по умолчанию подобную трансляцию не выполняет. Впрочем из
правила есть и исключения. О них дальше.
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-адреса всех машин-клиентов тем или иным способом разрешались в
имена.
Несоблюдение этого принципа может привести к серьезным
проблемам.
Предположим, что в у нас уже есть
отдельный 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-сервером, что и внешняя, а
чтобы извне нельзя было посмотреть структуру внутренних зон, для них
пишутся правила allow-query и allow-transfer.
К сожалению, для того, чтобы
использовать этот способ, мне пришлось бы поменять настройку DNS на
всех машинах Intranet-сети. Увы, я не готов к подобному подвигу. ;-(
Впрочем, если ваша сеть находится еще в процессе становления, этот
способ легко применим.
Комментировать | « Пред. запись — К дневнику — След. запись » | Страницы: [1] [Новые] |