На главную

djbdns: установка и настройка dnscache



Copyright © 2004 М. Альхименко.
Оригинал (и самая последняя версия) этого документа находится на http://lithium.opennet.ru.
По всем вопросам обращайтесь на articles <at> lithium.opennet.ru



24.08.2009:
    Добавлен патч для уязвимости, обнаруженной Matthew Dempsky.
    Патчи с постоянно меняющимся или несным местоположением помещены локально.
    Исправлено описание переменной IPSEND.

Содержание:

Введение

      В настоящей статье будет рассмотрена установка djbdns, настройка и запуск кэширующего DNS-сервера из состава djbdns. Следует иметь в виду, что в djbdns кэширующий и полномочный DNS-сервера разделены. Обоснование этого читайте на странице DJB. Imho весьма разумно. Функциональность кэширующего DNS-сервера обеспечивает программа dnscache. Полномочный DNS-сервер реализуется программой tinydns, сервер зонных пересылок — axfrdns. Про эти и другие программы вы можете почитать на странице djbdns.

      К несомненным достоинствам dnscache можно отнести как минимум НЕ более сложную настройку по сравнению с BIND, нетребовательность к ресурсам и намного более высокий уровень безопасности (автоматический chroot, авторство DJB и всего одна уязвимость за все время существования).

Установка:

      Внимательно читаем все, что есть на http://cr.yp.to/djbdns.html ;)
Перед установкой djbdns у вас должны стоять последняя версия daemontools и ucspi-tcp (если вы хотите переносить зоны с вашего DNS-сервера на BIND). Для запуска dnscache хватит и daemontools. Установка ucspi-tcp была ранее описана в статье о qmail. Сведения о установке и работе с daemontools см. в соответствующей статье.

# cd /usr/src

скачиваем и распаковываем исходники (со временем версия и путь могут измениться)

# wget http://cr.yp.to/djbdns/djbdns-1.05.tar.gz
# gunzip djbdns-1.05.tar
# tar -xf djbdns-1.05.tar
# cd djbdns-1.05

создаем каталог для патчей, скачиваем их и накладываем.

# mkdir patches
# cd patches
# wget http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/djbdns-1.05.errno.patch (патч для совместимости с glibc-2.3.1 и выше)
# wget http://lithium.opennet.ru/download/patches/round-robin.patch (патч для поддержки алгоритма round-robin для dnscache (не tinydns!))
# wget http://lithium.opennet.ru/download/patches/djbdns-secpatch-03-06-09.patch (патч для устранения уязвимости)
# cd ..
# patch -p1 < patches/djbdns-1.05.errno.patch
# patch -p1 < patches/round-robin.patch
# patch < patches/djbdns-secpatch-03-06-09.patch

собираем и устанавливаем:

# make
# make setup check

Отправляем отчет об установке DJB (наверное, для статистики)

# ( echo 'First M. Last'; cat `cat SYSDEPS` ) | mail djb-sysdeps@cr.yp.to


Первоначальная настройка

      Для начала неплохо было протестировать возможность обращения с нашей машины к внешним DNS-серверами. Попробуйте сделать пару запросов к полномочным DNS-серверам, например:

# host -t ns mail.ru 198.6.1.181

или

# dig @198.6.1.181 -t ns mail.ru

или

# dnsq a www.aol.com 192.203.230.10 (утилита из состава djbdns)

Адреса полномочных серверов могут измениться, так что лучше их уточнить, если что-то не будет работать. Если Вы собираетесь просто пересылать все запросы другим DNS-серверам (вышестоящего провайдера или своим собственным), то можете подставить их ip-адреса.

      Теперь следует создать учетные записи, под которыми будут работать dnscache и multilog, ведущий логи dnscache. В руководстве DJB описано создание аккаунтов Gdnscache and Gdnslog, однако в RH9 мне это сделать не удалось, useradd не нравились большие буквы, поэтому можете назвать их как dnscache и dnslog.

# adduser -d /none -M -s /bin/false -c "DJBDNS dnscache user" dnscache
# adduser -d /none -M -s /bin/false -c "DJBDNS dnslog user" dnslog

Теперь вам нужно определиться с двумя параметрами:

  1. Будет ли кэш доступен клиентам из вашей сети или только локальным процессам на вашем сервере. В первом случае мы говорим dnscache слушать 53 UDP порт на одном из интерфейсов, доступных извне, так чтобы клиенты могли слать на него свои запросы. Во втором случае кэш будет слушать порт на loopback-интерфейсе, и, соответственно, адресе 127.0.0.1.
  2. Будет ли кэш сам искать имена, делая запросы напрямую к полномочным DNS-серверам, или будет только пересылать запросы на другие DNS-сервера (если на найдет соответствие в своем кэше), то есть работать как DNS-relay.
Т.о. возможно четыре комбинации:
  1. Локальный DNS-cache (только для сервера). Напрямую делает запросы к ns-серверам, слушает 53 UDP порт на 127.0.0.1, обслуживает только локальные процессы.
  2. Локальный пересылающий (forwarding) DNS-cache (только для сервера). Пересылает запросы другому DNS-кэшу (если не находит соответствие в своем кэше), слушает 53 UDP порт на 127.0.0.1, обслуживает только локальные процессы.
  3. Внешний (доступный извне для клиентов) DNS-cache. Напрямую делает запросы к ns-серверам, слушает 53 UDP порт на одном из внешних интерфейсов.
  4. Внешний (доступный извне для клиентов) пересылающий (forwarding) DNS-cache. Пересылает запросы другому DNS-кэшу (если не находит соответствие в своем кэше), слушает 53 UDP порт на одном из внешних интерфейсов.

Первоначальная настройка dnscache осуществляется командой dnscache-conf. Она создает нужную структуру каталогов, настраивает основные параметры dnscache и имеет следующие параметры запуска:

      dnscache-conf acct logacct D ip

где

  • acct -учетная запись, под которой будет работать dnscache,
  • logacct - учетная запись, под которой будет работать multilog
  • D - каталог, в котором будет размещен сервис
  • ip - один из локальных адресов, на котором будет слушаться 53 UDP порт. Если этот параметр опущен, то делается настройка для адреса 127.0.0.1 и одновременно создается файл D/root/ip/127.0.0.1, разрешающий прием запросов с адреса 127.0.0.1 (см. дальше)

Т.о. для локального кэша команда будет выглядеть:

# dnscache-conf dnscache dnslog /etc/dnscache

Для внешнего (пусть 192.168.0.1 — адрес, на котором кэш должен быть доступен нашим клиентам):

# dnscache-conf dnscache dnslog /etc/dnscache 192.186.0.1

В файле /etc/dnscache/root/servers/@ в настоящий момент хранятся адреса корневых серверов Internet. Если Вы хотите, чтобы ваш кэш просто пересылал запросы другим DNS-серверам выполните следующие команды ( в этом примере 10.53.0.1 — адрес DNS-сервера, на который будут пересылаться запросы клиентов):

# echo 10.53.0.1 > /etc/dnscache/root/servers/@
(в этот файл можно поместить несколько адресов, если серверов несколько. В этом случае не забудьте использовать ">>")

# echo 1 > /etc/dnscache/env/FORWARDONLY (указывает кэшу только пересылать запросы, если не найдено совпадение в собственном кэше)

Следует обратить внимание, что если у вас есть DNS-сервера, полномочные для определенной зоны (например, local или mydomain.ru) то можно создать в каталоге /etc/dnscache/root/servers/ файлы с именами, соответствующими вашим зонам и в них поместить адреса полномочных серверов. После этого кэш будет посылать запросы для этих зон напрямую указанным серверам. Сейчас у нас есть только записи серверов для зоны ".".

Теперь, если вы явно указывали на каком ip слушать сокет, следует разрешить доступ для ваших подсетей к кэшу, т.к. по умолчанию все запросы игнорируются. В качестве примера мы разрешим принимать запросы с адресов 127.0.0.1 и из сети 192.168.0.0/24. Для этого надо поместить файлы с именами, соответствующими адресам сетей в каталог /etc/dnscache/root/ip/:

# touch /etc/dnscache/root/ip/127.0.0.1
# touch /etc/dnscache/root/ip/192.168.0

Логика тут очень простая: если надо дать доступ для сети 192.168.0.0/24, создается файл 192.168.0, если для сети 192.168.0.0/16 или для всех подсетей, начинающихся с 192.168, то создается файл 192.168.

После этого следует дать знать daemontools о существовании нового сервиса и проверить его работу:

# ln -s /etc/dnscache /service

ждем 5 секунд и проверяем, работает ли сервис

# svstat /service/dnscache
/service/dnscache: up (pid 32342) 7 seconds

Смотрим параметры readproctitle (ps -auxww) (см. статью про daemontools) на наличие ошибок.

После этого надо прописать на клиентах (если вы делали кэш доступным извне) и на самом сервере ip-адрес, который он слушает в /etc/resolv.conf (параметр nameserver). Все остальные записи этого типа можно закомментировать. Выглядит это примерно так:

если сервер слушает сокет на 127.0.0.1 :
nameserver 127.0.0.1 #разумеется, что это прописывается только на самом сервере

если сервер слушает сокет на 192.168.0.1 :
nameserver 192.168.0.1 #прописывается и на сервере, и на клиентах.

Подробнее — man resolv.conf

DJB в свое время забыл добавить в dnscache.c обработку сигнала SIGPIPE, поэтому если при выполнении TCP-запроса удаленная сторона закрывает сокет в то время как dnscache пишет в него, процесс получает сигнал SIGPIPE и завершается. Чтобы этого не происходило, добавьте в скрипт запуска строку:

trap "" SIGPIPE

Подробности — в man sh и в man 7 signal.

Основные возможности настройки.

      Рассмотрим вкратце основные возможности настройки dnscache. Все параметры представляют из себя файлы, сгруппированные в определенных каталогах:

Каталог D/env:

Отсюда берется переменные окружения программой envdir (см. руководство по daemontools) при запуске dnscache. Они в дальнейшем используются dnscache.

  • CACHESIZE — размер данных DNS-кэша (списка записей) в памяти
  • DATALIMIT — общее ограничение на память, занимаемую процессом
  • IP — ip-адрес, на котором будет слушаться 53 UDP порт. Устанавливается программой dnscache-conf при первоначальной настройке.
  • IPSEND — ip-адрес, с которого отсылаются запросы к серверам при разрешении имен.
  • ROOT - корневой каталог процесса (в который будет выполняться chroot при запуске).Устанавливается программой dnscache-conf при первоначальной настройке.
  • FORWARDONLY - существует и содержит значение "1" если кэш просто пересылает запросы серверам, указанных в качестве корневых.

Каталог D/root/ip:

Здесь находятся файлы, определяющие адреса сетей, которым разрешен доступ к кэшу. Например, для сети 10.0.0.0/8 (адреса 10.*) следует создать файл с именем "10", для подсети 192.168.100.0/24 (адреса 192.168.100.*) — файл "192.168.100". Для хоста 192.168.200.34 — файл с таким же названием.

Каталог D/root/servers:

Здесь находятся списки полномочных серверов. Список серверов для корневой зоны (зона ".") находится в файле с именем "@". Списки серверов для других зон хранятся в файлах, имена которых совпадают с именами зон.

Обратите внимание, что список корневых серверов для файла "@" берется dnscache-conf из файла /etc/dnsroots.global, который создается при сборке пакета. Откуда берется список корневых серверов на этом этапе мне выяснить пока не удалось. Т.к. этот список со временем меняется, то лучше всего его обновить актуальными данными. Для этого можно скачать список корневых серверов по адресу ftp://ftp.rs.internic.net/domain/named.root или ftp://ftp.internic.net/domain/named.root или воспользоваться nslookup. Полученный файл можно обработать несложным sed-скриптом (в нашем примере имя файла — djbroot.sed):
	# djbroot.sed
	/^$/d
	/^ *$/d
	/^;/d
	/^\./d
	s/[A-Z]\.ROOT-SERVERS\.NET\. *.*A *//
и заменить полученными данными файл "@", использовав команды:

# sed -f djbroot.sed named.root > /etc/dnsroots.global
# cp dnsroots.global /service/dnscache/root/servers/@

чтобы получить готовый список корневых серверов. После выполнения этих действий следует перезапустить dnscache:

# svc -t /service/dnscache

Также можно создать несколько файлов, соответствующим вашим полномочным серверам. Например, если у вас есть домен mydomain.ru и его обслуживают полномочные DNS-сервера, запущенные на ip-адресах 1.2.3.4 и 1.2.3.6, достаточно создать файл mydomain.ru и поместить в него ip-адреса полномочных серверов, по одному в каждой строке:

# echo "1.2.3.4" > /service/dnscache/root/servers/mydomain.ru
# echo "1.2.3.6" >> /service/dnscache/root/servers/mydomain.ru

Такие файлы можно создать для нескольких доменов. Теперь dnscache не будет запрашивать у корневых серверов NS-записи для домена mydomain.ru, а будет брать их прямо из файла "/service/dnscache/root/servers/mydomain.ru" .

Размер кэша:

Установленное по умолчанию значение размера кэша (параметр CACHESIZE) в вашем случае может быть не самым лучшим, поэтому можно попытаться его оптимизировать.
Dnscache периодически записывает в лог строки вида "stats 405674 46224023 1 0". Второе число после "stats" представляет собой приращение кэша (cache motion), т.е. количество байт записанное в кэш после запуска программы. Разница между текущим значение и значением спустя 24 часа даст суточное приращение кэша. (Или сделайте экстраполяцию, использовав ps или svstat, чтобы узнать сколько времени кэш работает.) Теперь разделите размер кэша на суточное приращение:
  • 0.01: Цикл обновления кэша около 15 минут. Большинство DNS-записей имеют больший TTL. Следует увеличить размер кэша.
  • 0.1: Цикл обновления кэша около 2 часов. Это больше чем TTL записей домена AOL, но меньше чем TTL большинства записей.
  • 1: Цикл обновления кэша около суток. Все еще есть некоторая выгода от увеличения кэша.
  • 10: Цикл обновления кэша около недели. Это оставляет достаточный запас памяти — обычно TTL не больше трех дней. Dnscache не может хранить записи больше недели.
Другой путь оценить эффективность кэша — это поделить приращение кэша на количество запросов (этот показатель первый после stats). Когда кэш очень большой, это отношение имеет минимально возможное значение, соответствующее неизбежному DNS-траффику; когда кэш очень маленький, это отношение очень большое.

Если вы переключились с BIND на dnscache, вы можете попытаться запомнить расход памяти BIND'ом и установить это значение для dnscache. В большинстве случаев это слишком много — dnscache потребляет гораздо меньше памяти.

Wayne Marshall предлагает более простой способ: посмотреть суточную разницу и поставить значение CACHESIZE немногим больше. Возможно, этот совет можно использовать для первоначальной грубой настройки.

В работе запускающих скриптов предлагаю разобраться самим — там все довольно просто и, кроме всего прочего, весьма познавательно ;) Можно порекомендовать добавить в скрипт запуска multilog после параметра "t" параметр "s10000000", который увеличит максимальный размер лога до ~10 МБ (можете использовать другое значение) и "!tai64nlocal", который преобразует дату в логе после ротации в удобочитаемый вид. Также, можно добавить параметр "n" — количество лог-файлов.

В заключении описания установки DJB предлагает поместить на вашу страницу упоминание, что "DNS cache is powered by djbdns". Это будет способствовать росту популярности продукта, увеличению числа пользователей, развитию инструментов для работы с ним и пр… Если не трудно — сделайте. Можно вставить соответствующий рисунок с тегом alt="Powered by djbdns".

Сcылки:



По всем вопросам пишите на articles <at> lithium.opennet.ru
Рейтинг@Mail.ru