LXF97:Служба доменных имен

Материал из Linuxformat.

Перейти к: навигация, поиск

Содержание

Служба доменных имен

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

DNS: Cвязующее звено Интернета

Четырехбайтная адресация, лежащая в основе IP-протокола, на котором, помимо всего прочего, зиждется сеть Интернет, удоб- на для операционных систем, но слишком тяжела для слабого и изнеженного человеческого мозга. Поэтому «записная книжка», из которой в любое время можно было бы узнать, что сайт http://linuxformat.ru нужно искать по адресу 88.212.196.134, а почту для http://mail.ru отправлять на 194.67.23.20, всегда будет востребована.

Поначалу с ролью такой «записной книжки» превосходно справлялся простой текстовый файл HOSTS.TXT. За его формирование отвечал Сетевой информационный центр Стенфордского института, а администраторы и пользователи периодически скачивали его по FTP. Но по мере роста числа компьютеров, объединенных в единую сеть, такое решение стало абсолютно неэффективным.

В конечном итоге DNS (Domain Name System, система доменных имен) уверенно и, похоже, надолго, заняла место службы, снабжающей нас информацией о том, какой же IP-адрес соответствует интересующему нас доменному имени. Основным преимуществом DNS является ее распределенная природа – информация не концентрируется в одном месте, а разбросана по всему Интернету в соответствии с иерархической структурой пространства доменных имен.

Во главе этой иерархии размещается так называемый корневой домен, обозначаемый одиночной точкой. Из этого корня «растут» домены первого уровня – ru, uk, com, net, org и т.д. Для реального использования доступны домены, начиная со второго уровня. Внутри домена могут размещаться как отдельные хосты, так и поддомены. Например, http://www.ibm.com – хост в домене ibm.com, а http://austin.ibm.com – поддомен.

Здесь нужно ввести еще одно понятие – «зона». Зоной называют область пространства имен домена, которая администрируется независимо от остального пространства имен. Жесткой привязки к делению на поддомены здесь нет – поддомен может обслуживаться как автономная единица, т.е. иметь свою зону (в этом случае говорят о делегировании поддомена), а может входить в родительскую зону.

Так как же DNS позволяет узнать IP-адрес того или иного хоста, например, http://www.yandex.ru? Выглядит это примерно так. Клиент отправляет запрос близлежащему DNS-серверу (обычно это сервер провайдера, но мы увидим далее, что можно запустить и собственный). Этот сервер в общем случае не знает требуемый IP, и даже не представляет, где его искать. Поэтому обращается к одному из корневых DNS-серверов. Корневой сервер физически не в силах держать информацию обо всех доменах третьего (да даже и второго) уровня, так что все, что он может сделать, это послать нас... правильно, к DNS-серверу первого уровня, который обслуживает зону ru.

В дела отдельных доменов и этот сервер не вникает, так что адреса конкретных узлов не обслуживает. Зато он знает, какой DNS-сервер отвечает за домен http://yandex.ru. Туда он нас (точнее, сервер нашего провайдера) и отправит. А вот DNS-сервер домена http://yandex.ru уже просто обязан вернуть нам IP-адрес входящего в его зону ответственности хоста. Ну или послать... на этот раз просто послать, если искомый хост не существует в природе.

Таким образом, за каждый домен может отвечать свой администратор, настраивая DNS-сервер для его обслуживания, а вышестоящим серверам достаточно знать, что и кому они делегировали. За счет этого и обеспечивается потрясающая масштабируемость, сделавшая службу DNS столь эффективной.

Желание клиента – закон

Начнем наше знакомство с клиентской части. Реализована она в виде стандартной библиотеки, и используем мы ее, можно сказать, ежеминутно, сами того не замечая. Если точнее, то используют ее те приложения, с которыми мы работаем – браузеры, FTP- и почтовые клиенты, различные сетевые серверы, да практически любые приложения, работающие в сети.

Настраивается клиент с помощью файла /etc/resolv.conf. В большинстве случаев достаточно указать там DNS-серверы, адреса которых предоставляет вам провайдер:

nameserver 1.2.3.4
nameserver 4.3.2.1

В современных дистрибутивах эта операция зачастую выполняется через графический интерфейс. Если для настройки сети используется DHCP-клиент, то он, как правило, и осуществляет «редактирование» /etc/resolv.conf. Т.е. обычный пользователь сталкивается с данным файлом не часто. Тем не менее, полезно знать, куда заглянуть в случае проблем.

Помимо упомянутой опции nameserver, в resolv.conf могут задавать ся и некоторые другие параметры, но сейчас они нам не слишком интересны. Подробности ищите на странице man resolv.conf(5).

BIND: Узелок на память

Теперь поговорим о сервере. Наиболее распространенным пакетом, обеспечивающим работу службы DNS на Unix-подобных системах, в настоящее время является BIND (Berkeley Internet Name Domain). Посмотрим, какая от него может быть польза, даже если вы не располагаете собственным доменом.

Скорая помощь

Если, несмотря на все шаманство с resolv.conf, разрешение имен идет как-то не так, загляните в /etc/nsswitch.conf, в строку hosts. Там указан порядок поиска доменных имен: files означает файл /etc/hosts, dns – поиск с помощью DNS-клиента. Возможно, тут и кроется проблема?

Установка сложностей никаких не представляет – даже если BIND не включен в состав вашего дистрибутива изначально, его, как правило, несложно найти в официальном репозитории. Скажем, в Ubuntu достаточно одной команды – sudo aptitude install bind9, и спустя 300 килобайт трафика один из лучших DNS-серверов в мире будет трудиться вам на благо.

Самое интересное то, что свежеустановленный BIND уже готов к работе в качестве кэширующего DNS-сервера. То есть он не отвечает ни за какую зону (за исключением localhost), но способен разрешать поступающие к нему запросы, сохраняя ответы в локальном кэше. При повторном запросе ответ уже будет возвращен из кэша, за счет чего достигается некоторая экономия трафика и времени.

Для управления сервером (его исполняемый файл носит название named) можно использовать стандартные средства вашего дистрибутива (скажем, сценарий /etc/init.d/bind9; в других дистрибутивах он может называться просто bind или named). Помимо этого, существует специальная утилита rndc (замечу, что, поскольку во время работы она взаимодействует с уже запущенным демоном named, то запускать его она как раз и не умеет). Чаще всего вы будете сталкиваться с командой rndc reload [zone], позволяющей перезагрузить зону (или все зоны) после внесения изменений. Состояние сервера вернет вам rndc status. Введите rndc без параметров, и вы узнаете обо всех ее возможностях. Чтобы начать использовать свой DNS-сервер, укажите его IP-адрес в /etc/resolv.conf.

Пусть работает трактор в поле...

Как нетрудно догадаться, чтобы получить IP-адрес, соответствующий имени http://www.yandex.ru, кэширующий сервер будет вынужден итеративно обращаться к различным серверам, начиная с корневого, пока не получит искомое. Для крупного DNS-сервера это вполне нормальный режим работы (заодно пополняющий кэш сведениями о промежуточных серверах), но в нашей небольшой сети мы хотели бы максимально снизить нагрузку и трафик. В случае с BIND львиную долю нагрузки можно переложить на плечи DNS-сервера нашего провайдера, указав в конфигурационном файле named.conf (в Ubuntu его можно найти в /etc/bind) параметр forwarders в разделе options:

options {
. . . другие опции . . .
forwarders {
1.2.3.4; # IP-адрес DNS-сервера провайдера
};
// forward only;
};

Теперь все запросы, на которые наш сервер не сможет ответить из своего кэша, он будет пересылать DNS-серверу провайдера (можно указать и несколько), ожидая от последнего уже готового ответа. Раскомментировав строку forward only, мы вообще запретим нашему серверу самостоятельно искать ответ, даже если ни один из forward-серверов наш запрос не удовлетворит.

Раз уж мы здесь, рассмотрим конфигурационный файл named.conf чуть подробнее. Синтаксис у него, как видите, «Си-подобный», поэтому не забывайте завершать каждую опцию и блок точкой с запятой. Блок options содержит общие для сервера опции, для каждой обслуживаемой зоны должен присутствовать блок zone (обратите внимание на зоны, по умолчанию присутствующие в named.conf; зона «.» – подсказка серверу, где искать корневые серверы, чтобы с чего-то начать).

Своя зона

Что еще можно сделать, имея собственный DNS-сервер? Ну, например, мы можем создать «локальную» зону для наших внутренних узлов. Скажем, чтобы по адресу http://webserver.local открывалась наша внутренняя интернет-страничка, а ftp://ftpserver.local вел на FTP-сервер. Конечно, можно прописать необходимые соответствия в /etc/hosts на каждом узле локальной сети, но зачем так усложнять себе жизнь?

Итак, в named.conf добавляем описание нашей «зоны»:

zone “local” {
type master;
file “/etc/bind/local.db”;
};

И в файл /etc/bind/local.db заносим информацию о наших узлах:

$TTL 3d
@ IN SOA admin.ns.local. (
1 ; Порядковый номер
2d ; Период обновления
1h30m ; Повторение попытки
1w ; Устаревание slave-зоны
1h ) ; Время жизни отрицательных ответов
;
IN NS ns.local.
ns IN A 192.168.0.254
webserver IN A 192.168.0.2
ftpserver IN CNAME webserver.local.

В подробности вдаваться не будем – если интересно, ответы на все вопросы вы найдете в замечательной документации (man 5 named.conf). Пока достаточно знать, что A-запись ставит в соответствие имя хоста его IP-адресу, а CNAME-запись позволяет указать для хоста дополнительное имя. NS указывает на DNS-сервер, отвечающий за данную зону (т.е. на наш сервер). Полные доменные имена обязательно должны заканчиваться точкой, имена без точки будут дополняться именем зоны. Ну и нужно знать про еще одну запись – PTR, отвечающую за «обратное» разрешение (т.е. поиск доменного имени по IP-адресу), для которого нужно создать еще и in-addr.arpa-зону:

zone “0.168.192.in-addr.arpa” {
type master;
file “/etc/bind/0.168.192.in-addr.arpa.db”;
};

Соответствующий файл 0.168.192.in-addr.arpa.db:

Маленькие шалости с DNS

Думаю, вы уже поняли, что собственный DNS-сервер позволяет и немножко пошалить. Например, что помешает нам создать master-зону microsoft.com? Вот наши пользователи удивятся, когда вместо http://www.microsoft.com попадут на http://linux.org ! Главное – не переусердствовать, ведь потерять доверие других людей – это уже совсем не шутки...

$TTL 3d
@ IN SOA admin.ns.local. (
1 ; Порядковый номер
2d ; Период обновления
1h30m ; Повторение попытки
1w ; Устаревание slave-зоны
1h ) ; Время жизни отрицательных ответов
;
IN NS ns.local.
2 IN PTR webserver
254 IN PTR ns

Фигурирующую в самом начале SOA-запись можно, не вдаваясь в особые подробности, скопировать из какого-нибудь файла-примера – в ней задаются преимущественно различные таймауты, и значения по умолчанию обычно неплохо подходят. Точка с запятой начинает комментарий.

На всякий случай замечу, что файлы зон вы вольны называть как душе угодно. Просто для удобства принято, чтобы имя файла соответствовало обслуживаемой зоне: сразу видно, за что именно тот или иной файл отвечает, и не обязательно сверяться с named.conf.

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

Служить бы рад...

Рассмотрим еще один случай. Предположим, что пользователи вашей небольшой локальной сети активно работают с ресурсами, имена которых обслуживаются зоной вашего провайдера. Безусловно, использование кэширующего DNS-сервера поможет разгрузить и DNS-сервер провайдера, и ваш интернет-канал. Однако можно поступить еще лучше – настроить свой BIND в качестве slave-сервера для зоны провайдера. Подчиненный (slave) сервер DNS предназначен для резервирования основного сервера, т.е. он тоже занимается обслуживанием зоны, но с той разницей, что файл зоны он берет не с диска, а скачивает с основного (master) сервера. Если данные этой зоны меняются не часто, то, единожды загрузив файл зоны (выполнив трансфер зоны), вы сможете самостоятельно обслуживать запросы к ней без обращений к DNS-серверу провайдера. Описывается slave-зона столь же легко:

zone “your.provider.ru” {
type slave;
file “/var/bind/slaves/your.provider.ru.db”;
masters { 1.2.3.4; }; # IP-адрес провайдерского DNS-сервера
};

После перезагрузки сервера (например, командой rndc reload) у вас должен появиться указанный файл. Вручную создавать его не нужно; только позаботьтесь, чтобы каталог /var/bind/slaves принадлежал пользователю BIND или, как минимум, был доступен ему на запись. Теперь ваш сервер сможет авторитативно (то бишь компетентно, официально) отвечать на запросы, касающиеся зоны http://your.provider.ru, без дополнительных обращений к серверу провайдера. (Нужно заметить, что зачастую администраторы DNS-серверов по соображениям безопасности запрещают передачу зоны на произвольные узлы. Если это ваш случай, то попросите провайдера разрешить трансфер для вашего адреса – в конце концов, он тоже заинтересован, чтобы его сервер не беспокоили по пустякам.)

Кстати, то, что мы получили, на самом деле не настоящий slave-сервер, поскольку ни одна из NS-записей зоны http://your.provider.ru на него не ссылается. Так что «чужие» о нашем сервере ничего не узнают и не смогут им пользоваться – а нам оно и не надо... Если же вы настраиваете полноценный slave-сервер для делегированного вам поддомена, то укажите его в файле зоны в качестве NS-сервера наряду с основным:

@ IN NS ns.mydomain.ru.
IN NS slave.mydomain.ru.

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

Другая точка зрения

Допустим, у вас есть делегированный вам домен http://mydomain.ru, который обслуживается вашим DNS-сервером. И здесь может возникнуть две интересные задачи. Во-первых, иногда нужно скрыть некоторую информацию от любопытных глаз, предоставляя ее лишь избранным. Например, ваша компания оказывает услуги доступа в Интернет, и вы хотите, чтобы ваш FTP-сервер посещали лишь ваши абоненты. (Да, это делается настройкой самого FTP-сервера, но было бы неплохо, чтобы посторонние о нем даже и не знали...) Можно ли предоставить адрес вашего сервера только пользователям конкретного домена?

Во-вторых, в локальной сети, как правило, используются «серые» IP-адреса, и обращение к «внешним» по отношению к ней ресурсам связано с трансляцией адресов. Но если ресурс работает на машине с несколькими сетевыми интерфейсами и доступен в том числе и по «серому» адресу, то такая трансляция уже несколько избыточна. Можно ли возвращать пользователям локальной сети «серый» адрес в ответ на запрос, не вынуждая их использовать альтернативные имена типа http://inner.mydomain.ru или тот же «домен» local?

В случае использования BIND9 ответы на оба вопроса будут положительны. В нем появилась одна замечательная штука – оператор view. Он позволяет разграничить «виды» одной и той же зоны для разных групп клиентов. Выглядит это примерно так:

view “clients” {
match-clients { 1.2.3/24; };
zone “mydomain.ru” {
type master;
file “/etc/bind/mydomain.clients.db”;
};
. . . прочие зоны . . .
};
view “others” {
match-clients { any; };
zone “mydomain.ru” {
type master;
file “/etc/bind/mydomain.db”;
};
. . . прочие зоны . . .
};

Такими настройками мы выделили два «вида» – для наших клиентов (сеть 1.2.3.0/24) и всех остальных. Осталось лишь подготовить различные файлы одних и тех же зон для разных «видов», и задача будет решена. Обратите внимание, что если вы приняли решение использовать «виды», то не должно быть ни одного оператора zone, не входящего в какой-нибудь оператор view.

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию