На главную

djbdns: tinydns — полномочный DNS-сервер


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



25.08.2009:
    Исправлено несколько опечаток

Содержание:
tinydns — это DNS-сервер из состава djbdns, который принимает только итеративные DNS-запросы (чтобы организовать сервер, отвечающий на рекурсивные запросы, используйте dnscache).

Запуск


Перед настройкой вам необходимо иметь установленные пакеты djbdns (его установка описана в предыдущей статье) и daemontools (его установка также рассматривалась). Затем, необходимо создать учетные записи tinydns and dnslog. Не забудьте установить для них оболочку вроде /bin/false и сделать их отключенными.

Для первоначального конфигурирования сервиса служит программа tinydns-conf. Синтаксис её вызова следующий:
    tinydns-conf acct logacct D ip
где
    acct — учетная запись, под которой будет работать tinydns,
    logacct — учетная запись, под которой будет работать multilog
    D — каталог, в котором будет размещен сервис (обычно /etc/tinydns)
    ip — адрес, на котором будет слушаться 53 UDP порт.
Не стоит забывать, что если в этой же системе запущен dnscache, то dnscache и tinydns должны слушать порты на разных IP-адресах.

Итак:

# tinydns-conf tinydns dnslog /etc/tinydns 1.2.3.4

Создаем новый сервис в каталоге /services:

# ln -s /etc/tinydns /service

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

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

Кратко о принципах работы tinydns. При запуске tinydns делает chroot в каталог, указанный в переменной окружения $ROOT (указанной в файле /etc/tinydns/env/ROOT), создаваемой программой envdir при запуске. Tinydns работает под uid and gid, содержащихся в переменных окружения $UID and $GID. Tinydns слушает 53 порт UDP на IP-адресе, указанном в переменной окружения $IP (устанавливается так же, как $ROOT). Соединения на 53 порт TCP не принимаются.
Данные для работы tinydns берет из файла data.cdb — БД, созданной tinydns-data.

Теперь tinydns запущен, приступим к созданию записей.

tinydns-data и общий формат данных


В каталоге /etc/tinydns содержится make-файл, в котором единственное действие — вызов программы tinydns-data. Команда make вызывается после каждого изменения data, чтобы внести изменения в data.cdb (не забывайте об этом!). tinydns-data читает информацию о DNS-записях из файла "data" в текущем каталоге и создает двоичный файл data.cdb — это БД, предназначенная для быстрого доступа tnydns к информации. tinydns-data также может создавать другие файлы с именами, начинающимися с "data" во время работы.

tinydns-data автоматически обновляет data.cdb, так что вы можете безопасно использовать её в то время, когда tinydns запущен. Если по время обновления или создания data.cdb происходит сбой, tinydns-data остановится и оставит старый файл data.cdb без изменений.

Информация о DNS-записях хранится в файле data в строках, каждая строка может содержать больше одной DNS-записи (например, записи A и NS одновременно).

Каждая строка начинает со специального символа и продолжается несколькими разделенными двоеточиями полями. В некоторых случаях поля могут быть не заполнены, тем не менее, все разделители должны присутствовать, исключая двоеточия в конце строки. Пробелы и табуляции в конце строки, а также пустые строки игнорируются.

Каждая строка содержит TTL ("time to live"), поле, определяющее количество секунд, которое DNS-записи, содержащиеся в строке, будут кэшироваться клиентами. Помните, что TTL меньше 300 может восприниматься как 300 некоторыми клиентами, и TTL для записи NS меньше 2 сек могут вызывать сбои при разрешении имен. Можно не указывать TTL, в этом случае tinydns-data будет использовать значения TTL по умолчанию, которые подходят в большинстве обычных ситуаций.

Вы можете включать временную метку (timestamp) в каждую строку. Если поле TTL пропущено или не равно 0, временная метка является временем старта для информации, указанной в строке, строка будет игнорироваться до этого времени. Если TTL рано 0, временная метка является временем окончания действия информации в строке ("time to die"), tinydns динамически назначает TTL таким образом, чтобы записи из этой строки не кэшировались больше чем на несколько секунд после времени окончания действия записи. Временная метка является внешней TAI64 временной меткой, обозначаемой шестнадцатеричным набором символов. Например:
    +www.heaven.af.mil:1.2.3.4:0:4000000038af1379
    +www.heaven.af.mil:1.2.3.7::4000000038af1379
определяет, что запись www.heaven.af.mil соответствует IP-адресу 1.2.3.4 до времени 4000000038af1379 (2000-02-19 22:04:31 UTC) и затем переключается на IP-адрес 1.2.3.7. По поводу конвертирования дат в формат TAI64 см. ссылки в конце статьи.

В djbdns версии 1.04 и позже вы можете определить расположение клиента в каждой строке (в BIND подобная функция называется "split horizon"). Записи в строке не будет отдаваться клинету, если его расположение не совпадает с указанным. Расположение определяется строками, начинающимися символом процента — "%". Например, запись:
    %lo:ipprefix
говорит, что IP-адрес, начинающийся с ipprefix относится к области (расположению) lo. lo есть один или два ASCII-символа. Клиент может находиться только в одной области, более длинные префиксы имеют преимущество над более короткими, например:
    %in:192.168
    %ex
    +jupiter.heaven.af.mil:192.168.1.2:::in
    +jupiter.heaven.af.mil:1.2.3.4:::ex
определяет, что jupiter.heaven.af.mil имеет адрес 192.168.1.2 для клиентов из сети 192.168.* и адрес 1.2.3.4 для всех остальных.

Наиболее распространенные типы строк




    .fqdn:ip:x:ttl:timestamp:lo
Принятие делегирования для домена fqdn. tinydns-data создает:
  • NS ("name server") запись, указывающую, что x.ns.fqdn сервер имен (name server) для fqdn;
  • A ("address") запись указывающую, что ip является IP-адресом x.ns.fqdn;
  • SOA ("start of authority") запись fqdn с x.ns.fqdn в роли первичного сервера имен (primary name server) и hostmaster@fqdn в качестве контактного адреса.
Вы можете иметь несколько таких строк для одного домена, с разными x для каждого сервера. tinydns вернет только одну запись SOA на каждый домен (хотя, imho проще воспользоваться специальной записью для NS-серверов).

Если x содержит точку, tinydns-data будет использовать x как имя NS-сервера вместо x.ns.fqdn. DJB пишет, что эта возможность предусмотрена только для целей совместимости; имена, не заканчивающиеся на fqdn, вынуждают клиентов обращаться к родительским (parent) серверам намного чаще, чем это нужно, и это снижает общую надежность DNS. Т.е. если вы укажете имя NS-сервера из другого домена, клиент будет вынужден запрашивать информацию у серверов, полномочных для того домена, а это есть лишнее время, трафик и еще одно звено в цепочке, которое может привести к сбою. Однако если указать ns-сервер из домена, за который отвечает ваш ns-сервер (т.е. IP-адреса ns-серверов ему известны), то при запросе NS-записей нужные IP-адреса ns-серверов будет возвращены в ответе ("ADDITIONAL SECTION" в dig).
Вы можете опустить ip если x имеет IP-адрес, назначенный для x в другом места файла data; в этом случае tinydns-data не будет создавать запись типа A.
В случае использования этой строки для создания SOA-записи серийный номер зоны проставляется автоматически при выполнении make.

Примеры:
    .panic.mil:1.8.7.55:a
создаст NS-запись, указывающую, что a.ns.panic.mil — сервер имен (name server) для panic.mil; запись типа A, указывающую, что 1.8.7.55 — IP-адрес для a.ns.panic.mil, и запись SOA для panic.mil.
    .panic.mil:1.8.7.56:dns2.panic.mil
создаст NS-запись, указывающую на dns2.panic.mil как name server для panic.mil, A-запись, указывающую что 1.8.7.56 — IP-адрес для dns2.panic.mil, и запись SOA для panic.mil.
    .panic.mil::a.ns.heaven.af.mil
создает NS-запись, указывающую, что a.ns.heaven.af.mil — name server для panic.mil, и SOА-запись для panic.mil.



    &fqdn:ip:x:ttl:timestamp:lo
Сервер имен для домена fqdn. tinydns-data создает:
  • NS-запись, указывающую, что x.ns.fqdn — сервер имен для fqdn и
  • А-запись, указывающую, что ip — это IP-адрес для x.ns.fqdn.
Если x содержит точку, тогда x будет интерпретироваться как полное имя ns-сервера (см. выше).

Вы можете иметь несколько серверов имен для одного домена, с разными x для каждого сервера.

DJB пишет, что обычно строка "&" используется для делегирования доменов этим сервером подчиненным (child) серверам, тогда как строка "." используется для делегирования доменов этом серверу (т.е. создается несколько строк "." — по количеству NS-серверов), хотя imho можно поступить классически: одна строка "." (SOA + 1 NS) и несколько строк "&" (остальные NS-сервера).

Примеры:
    &serious.panic.mil:1.8.248.6:a
создает NS-запись, указывающую, что a.ns.serious.panic.mil — сервер имен для serious.panic.mil, и A-запись, указывающую, что 1.8.248.6 — IP-адрес a.ns.serious.panic.mil.
    &serious.panic.mil:1.8.248.7:ns7.panic.mil
создает NS-запись, указывающую, что ns7.panic.mil — сервер имен для serious.panic.mil, и A-запись, указывающую, что 1.8.248.7 — IP-адрес ns7.panic.mil.
    &serious.panic.mil::ns7.panic2.mil
создает NS-запись, указывающую, что ns7.panic2.mil — сервер имен для serious.panic.mil.



    =fqdn:ip:ttl:timestamp:lo
Хост fqdn с IP-адресом ip. tinydns-data создает:
  • A-запись, указывающую, что ip — это IP-адрес для fqdn
  • PTR-запись ("pointer" record), указывающую, что fqdn — имя хоста для d.c.b.a.in-addr.arpa, если ip соответствует a.b.c.d.
Помните, что необходимо создать запись SOA для fqdn (строка ".") и NS-запись, указывающую на ваш сервер; иначе tinydns не будет отвечать на запросы о fqdn. Также, необходимо будет создать SOA- и NS-запись (указывающую на ваш сервер) для d.c.b.a.in-addr.arpa, если этот домен делегирован вам.

Пример:
    =button.panic.mil:1.8.7.108
создает A-запись, указывающую, что 1.8.7.108 — IP-адрес для button.panic.mil, и PTR-запись, указывающую, что button.panic.mil — имя для 108.7.8.1.in-addr.arpa.



    +fqdn:ip:ttl:timestamp:lo
A-запись для fqdn c IP-адресом ip. Эта запись похожа на =fqdn:ip:ttl, за тем исключением, что tinydns-data не создает PTR-запись.

Для версии 1.04 и выше: tinydns возвращает A-записи (из линий "+" или "=" или "@" или "." или "&") в случайном порядке в ответах клиентам. Если существует больше чем 8 записей, tinydns вернет выбранные случайным образом 8 записей (т.н. "round-robin" алгоритм).

Например:
    +button.panic.mil:1.8.7.109
создает A-запись, указывающую, что 1.8.7.109 — IP-адрес для button.panic.mil.



    @fqdn:ip:x:dist:ttl:timestamp:lo
Mail exchanger (MX) для fqdn. tinydns-data создает:
  • MX (&mail exchanger&) запись, указывающую, что x.mx.fqdn является mail exchanger'ом для fqdn с расстоянием (distance) dist
  • A-запись, указывающую, что ip — IP-адрес x.mx.fqdn.
Вы можете не указывать dist; значение по умолчанию — 0.

Если x содержит точку, это трактуется как было описано выше.

Вы можете создать несколько MX-записей для fqdn, с разными x для каждого сервера. Только убедитесь, что настроили эти сервера так, чтобы они принимали почту для fqdn.

Пример:
@panic.mil:1.8.7.88:mail.panic.mil
создает MX-запись, указывающую, что mail.panic.mil — mail exchanger для panic.mil с расстоянием (distance) 0;
A-запись, указывающую, что 1.8.7.88 — IP-адрес mail.panic.mil.

В этой записи также можно пропустить x, как это было в случае NS-записи (&).



    #comment
Комментарии. Такие строки будут игнорироваться

Менее распространенные типы строк



    -fqdn:ip:ttl:timestamp:lo
Для версии 1.04 и выше: этот тип записи используется программами, автоматически изменяющими выдачу строк "+" для временного исключения адресов перегруженных или отключенных машин. Эта строка ("+") будет игнорироваться.


    'fqdn:s:ttl:timestamp:lo
TXT ("text") запись для fqdn. tinydns-data создает TXT-запись для fqdn, содержащую строку s. Вы можете использовать восьмеричные \nnn коды для включения в s произвольных байт; например, \072 — двоеточие.


    ^fqdn:p:ttl:timestamp:lo
PTR-запись для fqdn. tinydns-data создаст PTR-запись для fqdn, указывающую на доменное имя p.


    Cfqdn:p:ttl:timestamp:lo
CNAME ("canonical name") запись для fqdn. tinydns-data создаст CNAME-запись для fqdn, указывающую на доменное имя p.

Не используйте Cfqdn если существуют любые другие записи для fqdn, не используйте Cfqdn для обычных aliases (псевдонимов); используйте взамен +fqdn. DJB цитирует слова Inigo Montoya, которые мне так и не удалось перевести: "You keep using CNAME records. I do not think they mean what you think they mean." Скорее всего, смысл в том что "настоящие пацаны CNAME-записи не используют." ;)


    Zfqdn:mname:rname:ser:ref:ret:exp:min:ttl:timestamp:lo
SOA-запись для fqdn, указывающая, что mname — первичный сервер имён, rname (где первая точка преобразуется в @) — контактный e-mail адрес, ser — серийный номер, ref — refresh time, ret — retry time, exp — expire time, и min — minimum time. ser, ref, ret, exp, и min могут быть опущены, тогда они будет установлены по умолчанию, соответственно в: время изменения файла, 16384 секунд, 2048 секунд, 1048576 секунд, и 2560 секунд.


    :fqdn:n:rdata:ttl:timestamp:lo
Настраиваемая запись для fqdn. tinydns-data создает запись с типом n для fqdn указывающую на rdata. n должно быть целым числом между 1 и 65535; n не должно быть 2 (NS), 5 (CNAME), 6 (SOA), 12 (PTR), 15 (MX), и 252 (AXFR). Соответственно, формат rdata зависит от значения n. Вы можете использовать восьмеричные коды (\nnn) чтобы включить произвольные байты внутрь rdata.
Существует несколько патчей, позволяющих использовать символьные обозначения для типов записей, не имеющих обозначения в оригинальном djbdns (LOC, AAA и др.), однако вместо их использования можно применять этот формат строки, т.е. числовые коды. Т.о. tinydns позволяет использовать неизвестные ему изначально типы записей.
Список существующих на настоящий момент типов записей приведен в http://www.iana.org/assignments/dns-parameters


Знаки подстановки


tinydns поддерживает знаки подстановки в формате *.fqdn. Информация в *.fqdn подходит для каждого имени, заканчивающегося на .fqdn, исключая имена, которые уже имеют свои записи и имена, которые уже более точно совпали с другим шаблоном.

Например, строки:
    +pink.floyd.u.heaven.af.mil:1.2.3.4
    +*.u.heaven.af.mil:1.2.3.200
имеют такой же эффект, как и
    +pink.floyd.u.heaven.af.mil:1.2.3.4
    +joe.u.heaven.af.mil:1.2.3.200
    +bill.u.heaven.af.mil:1.2.3.200
    +floyd.u.heaven.af.mil:1.2.3.200
    +ishtar.u.heaven.af.mil:1.2.3.200
    +joe.bob.u.heaven.af.mil:1.2.3.200
    +sally.floyd.u.heaven.af.mil:1.2.3.200
    +post.pink.floyd.u.heaven.af.mil:1.2.3.200
    и так далее...
Как другой пример, строки
    +pink.floyd.u.heaven.af.mil:1.2.3.4
    @*.u.heaven.af.mil::mail.heaven.af.mil
имеют такой же эффект, как и
    +pink.floyd.u.heaven.af.mil:1.2.3.4
    @joe.u.heaven.af.mil::mail.heaven.af.mil
    @bill.u.heaven.af.mil::mail.heaven.af.mil
    @floyd.u.heaven.af.mil::mail.heaven.af.mil
    @ishtar.u.heaven.af.mil::mail.heaven.af.mil
    @joe.bob.u.heaven.af.mil::mail.heaven.af.mil
    @sally.floyd.u.heaven.af.mil::mail.heaven.af.mil
    @post.pink.floyd.u.heaven.af.mil::mail.heaven.af.mil

и так далее. Обратите внимание, что этот шаблон не будет применим к pink.floyd.u.heaven.af.mil, т.к. это имя имеет собственную запись.

В конце небольшой совет. При делегировании вам зоны в домене ru. через www.nic.ru происходит непродолжительное тестирование вашей зоны, и случае настроек по умолчанию возникают некоторые проблемы, т.к. nic.ru не нравятся тайминги в записи SOA. Поэтому лучше сразу выставить их следующим образом:
    .your-domain.ru:1.2.3.4:ns.your-domain.ru::::1209600:86400
Также он ругается на формат серийного номера зоны, т.к. в BIND они идет в формате YYYYMMDDnn, однако в djbdns он проставляется автоматически при создании data.cdb и соответствует времени изменения файла data. Т.к. в RFC по этому поводу написано "recommended", а не "required", то эти придирки можно смело игнорировать, т.к. способ, применяемый в djbdns более удобный, и приводит к меньшему числу ошибок.

Методы решения основных задач


Принятие делегирования


Существует две основные стадии в процессе принятия делегирования и управления вашими DNS-серверами.

Во-первых, сервер должен принять делегирование. Ваш сервер не будет отвечать на запросы об именах, пока он не узнает, что отвечает за эти имена. Следующие команды скажут серверу, что он отвечает за имена, заканчивающиеся на af.mil и 7.8.1.in-addr.arpa:
    cd /service/tinydns/root
    ./add-ns heaven.af.mil 1.8.7.200
    ./add-ns heaven.af.mil 1.8.7.201
    ./add-ns 7.8.1.in-addr.arpa 1.8.7.200
    ./add-ns 7.8.1.in-addr.arpa 1.8.7.201
    make
Эти команды также скажут серверу:
  • считать a.ns.heaven.af.mil с IP-адресом 1.8.7.200 и b.ns.heaven.af.mil с IP-адресом 1.8.7.201 DNS-серверами для домена heaven.af.mil и,
  • считать a.ns.7.8.1.in-addr.arpa с IP-адресом 1.8.7.200 и b.ns.7.8.1.in-addr.arpa с IP-адресом 1.8.7.201 DNS-серверами для домена 7.8.1.in-addr.arpa.
Во вторых, родительские сервера должны делегировать домен вашим серверам. DNS-кэши из Internet не будут спрашивать ваши DNS-сервера об именах из вашего домена, пока этот домен не будет делегирован вашим DNS-серверам. В примере выше,
  • администратор домена af.mil должен делегировать домен heaven.af.mil серверу a.ns.heaven.af.mil, работающему на IP-адресе 1.8.7.200, и серверу b.ns.heaven.af.mil, работающему на IP-адресе 1.8.7.201, и
  • администратор домена 8.1.in-addr.arpa должен делегировать домен 7.8.1.in-addr.arpa серверу a.ns.7.8.1.in-addr.arpa, работающему на IP-адресе 1.8.7.200, и серверу b.ns.7.8.1.in-addr.arpa, работающему на IP-адресе 1.8.7.201.
Также, можно прописать делегирование и NS-сервера вручную, как было описано выше (строки "." и "&").
    .heaven.af.mil:1.8.7.200:a:
    .heaven.af.mil:1.8.7.201:b:
    .7.8.1.in-addr.arpa:1.8.7.200:a:
    .7.8.1.in-addr.arpa:1.8.7.201:b:
Следует иметь в виду, что поскольку каждая строка в data может создавать больше одной DNS-записи, одни и те же записи можно создать различными вариациями строк, например:
    .heaven.af.mil:1.8.7.200:ns1.heaven.af.mil:
    .heaven.af.mil:1.8.7.201:ns2.heaven.af.mil:
    .7.8.1.in-addr.arpa:1.8.7.200:ns1.heaven.af.mil:
    .7.8.1.in-addr.arpa:1.8.7.201:ns2.heaven.af.mil:


    или

    .heaven.af.mil:1.8.7.200:ns1.heaven.af.mil:
    &heaven.af.mil:1.8.7.201:ns2.heaven.af.mil:
    .7.8.1.in-addr.arpa:1.8.7.200:ns1.heaven.af.mil:
    &7.8.1.in-addr.arpa:1.8.7.201:ns2.heaven.af.mil:


    или

    .heaven.af.mil::ns1.heaven.af.mil:
    &heaven.af.mil::ns2.heaven.af.mil:
    .7.8.1.in-addr.arpa::ns1.heaven.af.mil:
    &7.8.1.in-addr.arpa::ns2.heaven.af.mil:
    +ns1.heaven.af.mil:1.8.7.200
    +ns2.heaven.af.mil:1.8.7.201
Также следует заметить, что вопрос использовать ли программы add-* или редактировать файл data вручную — вопрос философского плана, выбирайте сами, что вам ближе.

Публикация адресов компьютеров


C того момента, как имена, такие как heaven.af.mil делегированы вашим серверам, вы можете опубликовать IP-адрес для heaven.af.mil и для любых имен, заканчивающихся на heaven.af.mil.

Обычная практика публиковать два типа имен:
  • Имена компьютеров. Выбирайте имя для каждого компьютера и запустите add-host с именем компьютера и IP-адресом. Вы также должны настроить на компьютере этот IP-адрес.
  • Имена сервисов. Для каждого сервиса (www, pop, etc.), запустите add-alias с именем сервиса и IP-адресом.
Отделение имени компьютера от имени сервиса будет полезно, если вы позднее решите переместить сервис с одного хоста на другой.

Например, допустим, что вы — администратор домена heaven.af.mil; вы имеете три компьютера, с IP-адресами 1.8.7.4, 1.8.7.5, и 1.8.7.6; вы имеете web-сервер и FTP-сервер, запущенные на первой машине. Вы выбрали имена lion, tiger и bear, для своих машин и выполняете следующие команды:
    cd /service/tinydns/root
    ./add-host lion.heaven.af.mil 1.8.7.4
    ./add-host tiger.heaven.af.mil 1.8.7.5
    ./add-host bear.heaven.af.mil 1.8.7.6
    ./add-alias www.heaven.af.mil 1.8.7.4
    ./add-alias ftp.heaven.af.mil 1.8.7.4
    make
Программы add-host и add-alias редактируют /service/tinydns/root/data — файл в формате tinydns-data. make запускает программу tinydns-data, которая изменяет файл data.cdb на основе информации из data. Tinydns начинает сразу же использовать новую информацию. Если что-то пойдет не так, tinydns-data выводит сообщение об ошибке и tinydns продолжает использовать старую информацию.

Теперь, любой, кто пытается разрешить имя lion.heaven.af.mil или www.heaven.af.mil или ftp.heaven.af.mil получит IP-адрес 1.8.7.4. Любой, кто попытается разрешить IP-адрес 1.8.7.4 в имя компьютера получит lion.heaven.af.mil.

В качестве альтернативы применению add-host и add-alias вы можете изменить /service/tinydns/root/data вручную, добавив следующие строки:
    =lion.heaven.af.mil:1.8.7.4
    =tiger.heaven.af.mil:1.8.7.5
    =bear.heaven.af.mil:1.8.7.6
    +www.heaven.af.mil:1.8.7.4
    +ftp.heaven.af.mil:1.8.7.4

Существуют две причины использовать программы add-host и add-alias взамен редактирования файла data вручную. Первая — add-host предохранит вас от случайного повторного использования имени компьютера или повторного использования существующего IP-адреса. Второе — если вы хотите защитить data от внезапных сбоев (например, выключения электричества), вам придется скопировать его в data.tmp, редактировать data.tmp, синхронизировать data.tmp на диск (sync) и использовать mv для переименования data.tmp в data; add-host и add-alias делают все это автоматически.

Немного о выборе имен. Следует помнить, что add-host задает уникальные имена машин, поэтому для каждого IP-адреса используется свое имя. По этой же причине add-alias не запускается с именем машины в качестве параметра (только с именем псевдонима).

Ниже преведены несколько неплохих источников для выбора имен компьютеров:
  • Животные: lion, tiger, bear, etc. Но не используйте их, если вы биолог, изучающий животных. Имена машин должны быть словами, которые вы не используете в другом контексте.
  • Планеты: mercury, venus, mars, etc. Не используйте их, если вы астроном!
  • Боги: zeus, athena, hermes, etc.
  • Элементы: hydrogen, helium, lithium, etc.
  • Цветы: tulip, rose, lilac, etc.
Если вы добавляете второй адрес на компьютере, будет хорошей идеей использовать add-host с новым именем, как будто второй IP-адрес по настоящему являлся отдельным компьютером.
    ./add-host zebra.heaven.af.mil 1.8.7.240
В этом случае вам не придется ничего менять, если этот IP-адрес будет реально перемещен на другой компьютер.

Проверка адресов ваших компьютеров


Здесь описывается, как проверить, что tinydns публикует правильные IP-адреса для имени: например, что опубликован IP-адрес 1.8.7.4 для www.heaven.af.mil.

Во-первых, проверьте, что адрес есть в /service/tinydns/root/data в формате tinydns-data:
    +www.heaven.af.mil:1.8.7.4
IP-адреса могут быть назначены в строках "+", "=", "@", ".", и "&".

Во вторых, используйте tinydns-get для проверки того, что адрес присутствует в /service/tinydns/root/data.cdb:
    cd /service/tinydns/root
    tinydns-get a www.heaven.af.mil
Вывод должен выглядеть так:
    answer: www.heaven.af.mil 86400 A 1.8.7.4
Хотя, возможно с числом отличным от 86400. Основные причины того, что этот ответ будет отсутствовать или будет представлять собой предыдущие данные: вы не запустили make после изменения файла data; у вас нет строк "." (или "Z") в файле data, определяющих соответствующие сервера имен.

Если вы хотите проверить обратное разрешение, замените "a www.heaven.af.mil" на "ptr 4.7.8.1.in-addr.arpa".

В третьих, проверьте, что IP-адрес, слушаемый tinydns — один из IP-адресов машины, на которой он запущен:
    cat /service/tinydns/env/IP
    netstat -n -i
В четвертых, проверьте, что сервис tinydns запущен:
    svstat /service/tinydns
Если tinydns-get отвечает объемом, большим чем 512 байт, вы также нуждаетесь в TCP сервисе; проверьте, что сервис axfrdns работает.

В пятых, сделайте запрос к tinydns об имени:
    dnsq a www.heaven.af.mil 1.8.7.200
    dnsq a www.heaven.af.mil 1.8.7.201
Здесь 1.8.7.200 и 1.8.7.201 — IP-адреса ваших DNS-серверов. Вывод dnsq должен быть идентичен предыдущему выводу tinydns-get.

В шестых, спросите ваш DNS-cache об адресе:
    dnsqr a www.heaven.af.mil
Если dnscache не может найти адрес, проблема, скорее всего в том, что родительские сервера не делегировали соответствующий домен вашим DNS-серверам. Посмотрите лог в /service/dnscache/log/main/current чтобы посмотреть, с какими серверами общался dnscache, и какую информацию он получил от них. Для полного отладочного сканирования используйте dnstrace.

Использовать nslookup не рекомендуется по причинам, изложенным в http://cr.yp.to/djbdns/nslookup.html. Вместо него можно использовать dig. Также, если у вас запущен axfrdns (см. ниже) можно сделать перенос зоны, чтобы посмотреть, что реально отдает tinydns.

Публикация адресов почтовых серверов


Когда агент доставки почты (mail transfer agent — MTA) собирается доставить почту, адресованную в домен heaven.af.mil, он смотрит IP-адрес heaven.af.mil, и пытается соединиться с SMTP сервером на этом IP-адресе. Вы можете использовать add-mx чтобы указать другой адрес.
    cd /service/tinydns/root
    ./add-mx heaven.af.mil 1.8.7.193
    make
(mx означает "mail exchanger"') Как альтернатива использованию add-mx, вы можете отредактировать файл data, добавив следующую строку:
    @heaven.af.mil:1.8.7.193:a
Если вы добавляете несколько mail-серверов для heaven.af.mil, используйте "a" для первого, "b" для второго etc. add-mx делает это автоматически. Также, можно использовать и классический вариант, как указано выше.

Делегирование имен (домена) другому серверу


Чтобы делегировать домен подчиненному серверу, запустите add-childns с делегируемым именем и IP-адресом подчиненного сервера:
    cd /service/tinydns/root
    ./add-childns elysium.heaven.af.mil 1.2.3.144
    make
В качестве альтернативы add-child вы можете редактировать файл data вручную, добавив следующую строку:
    &elysium.heaven.af.mil:1.2.3.144:a
Если вы делегируете elysium.heaven.af.mil нескольким IP-адресам, используйте "a" для первого, "b" для второго и т.д. add-childns делает это автоматически.

Вы можете выбрать имя сервера, отличное от используемого по умолчанию a.ns.elysium.heaven.af.mil. Чтобы избежать "triggering a BIND bug", родительский и подчиненный сервера должны использовать одно и то же имя для подчиненных серверов. Например, если подчиненный сервер использует
    .elysium.heaven.af.mil:1.2.3.144:dns1.elysium.heaven.af.mil
тогда родительский сервер должен использовать то же самое имя:
    &elysium.heaven.af.mil:1.2.3.144:dns1.elysium.heaven.af.mil
Можно опустить IP-адрес, если имени уже сопоставлен IP-адрес в другой строке data:
    &elysium.heaven.af.mil::dns1.elysium.heaven.af.mil

Настройка независимых DNS-серверов


Вы можете запустить несколько серверов (на разных IP-адресах) с разными файлами data. Например, вы можете запустить четыре сервера, когда два сервера обслуживают зону heaven.af.mil, и два сервера обслуживают зону panic.mil. Изменения в heaven.af.mil делаются на первом сервере и копируются на второй. Изменения в panic.mil делаются на третьем и копируются на четвертый.

Конечно, одиночный сервер может поддерживать и heaven.af.mil и panic.mil. Тем не менее, если вы обладаете файлом data размером около гигабайта, вы можете задумываться о запуске нескольких независимых серверов, по одному на каждую часть данных

Перемещение зоны на независимый DNS-сервер


Здесь описано, как переместить зону heaven.af.mil с двух DNS-серверов с IP-адресами 1.8.7.200 и 1.8.7.201 на два других DNS-сервера с IP-адресами 1.8.11.50 и 1.8.11.51.
  1. Скопируйте файл data со старых серверов на новые.
  2. На новых серверах измените IP-адрес хоста a.ns.heaven.af.mil с 1.8.7.200 на 1.8.11.50, путем изменения

      .heaven.af.mil:1.8.7.200:a

    на
      .heaven.af.mil:1.8.11.50:a

    в /service/tinydns/root/data. Таким же образом измените IP-адрес хоста b.ns.heaven.af.mil с 1.8.7.201 на 1.8.11.51. Выполните

      make

    чтобы новые сервера начали публиковать новые IP-адреса.

  3. Сделайте те же самые изменения на родительских серверах.

  4. Сделайте те же самые изменения на старых серверах. Это очень важно, потому что DNS-кэши могут продолжать опрашивать старые сервера на протяжении некоторого времени.

  5. Подождите несколько дней, пока кэши не перестанут опрашивать старые сервера. Если вы делаете какие-либо изменения в файле data для зоны heaven.af.mil во время этого периода, делайте эти же изменения на старых серверах.

  6. Удалите файл data для heaven.af.mil со старых серверов.

Синхронизация зоны между полномочными серверами

Отдача зон серверу BIND

Чтобы djdbs мог отдавать dns-записи по протоколу TCP (в т.ч. и при переносе зон) необходимо запустить axfrdns. Для его работы необходимы установленные пакеты djbdns (установка), ucspi-tcp (установка) и daemontools (установка). DJB пишет, что в большинстве случаев нет необходимости отвечать на TCP-запросы, однако imho возможность посмотреть зону в BIND формате иногда может быть полезной, т.к. для многих этот формат более привычен. Кроме того, иногда необходимо дать возможность серверу BIND переносить зону или отсылать ответы больше 512 байт.

Для установки создаем учетную запись axfrdns. Не забудьте установить для неё оболочку вроде /bin/false и сделать её отключенной.

Для первоначального конфигурирования сервиса служит программа axfrdns-conf. Синтаксис её вызова следующий:
    axfrdns-conf acct logacct D tiny ip
где:
  • acct — учетная запись, под которой будет работать axfrdns,
  • logacct — учетная запись, под которой будет работать multilog
  • D — каталог, в котором будет размещен сервис (обычно /etc/axfrdns)
  • tiny — каталог tinydns (например, /etc/tinydns)
  • ip — адрес, на котором будет слушаться 53 UDP порт.
Не забывайте, что это должен быть тот же IP-адрес, на котором tinydns слушает 53 UDP-порт.

# axfrdns-conf axfrdns dnslog /etc/axfrdns /etc/tinydns 1.2.3.4

Создаем файл tcp, в котором разрешаем всем делать TCP-запросы (но не перенос зон):

# echo ':allow,AXFR=""' > /etc/axfrdns/tcp

Разрешаем самому себе переносить зону (не забудьте про двойные скобки!):

# echo '1.2.3.4:allow,AXFR="mydomain.ru"' >> /etc/axfrdns/tcp
# echo '127.0.0.1:allow,AXFR="mydomain.ru"' >> /etc/axfrdns/tcp

Если необходимо дать разрешение переносить зону с других машин, укажите их IP-адреса вначале строки. Если необходимо дать разрешение для переноса нескольких зон, укажите их вместе, разделяя слешем (/). Например, разрешение переносить зоны mydomain1.ru и mydomain2.ru с IP-адреса 192.168.0.100 в файле tcp будет выглядеть так:
    192.168.0.100:allow,AXFR="mydomain1.ru/mydomain2.ru"
Для одного IP-адреса допустима только одна строка.
Не помешает в конце добавить строку:
    :deny
Более подробно о правилах tcpserver можно прочитать на странице http://cr.yp.to/ucspi-tcp/tcprules.html

Теперь нужно создать БД для tcpserver:

# cd /etc/axfrdns
# make

Эту операцию нужно делать каждый раз при изменении файла tcp.

Создаем новый сервис в каталоге /services:

# ln -s /etc/axfrdns /service

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

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

пробуем перенести зону:

# dig @1.2.3.4 -t axfr midomain.ru

Вкратце, как работает axfrdns.

Axfrdns при запуске делает chroot в каталог, указанный в переменной окружения $ROOT, под uid и gid, указанных в переменных окружения $UID и $GID. Эти переменные окружения устанавливаются программой envuidgid (из состава daemontools) в скрипте запуска.

Обычно axfrdns запускается из-под tcpserver и принимает соединения на 53 порт TCP на одном из локальных адресов. Tcpserver отвечает за обрыв соединений от хостов, не уполномоченных на перенос зоны. Axfrdns также можно запустить под программами, поддерживающими защищенное соединение с UCSPI-совместимым интерфейсом (к сожалению, кроме ssl-патча для ucspi-tcp мне больше ничего неизвестно).

Axfrdns берет информацию для переноса зон в файле data.cdb, созданным tinydns-data. Также, axfrdns отвечает на обычные запросы клиентов, такие как записи SOA.

Axfrdns разрешает перенос зоны для любых зон, указанных в переменной окружения $AXFR. $AXFR является списком имен доменов разделенных обычным слешем. Если $AXFR не установлена, axfrdns разрешает перенос зоны для всех доменов, определенных в data.cdb (крайне не рекомендуется так делать!).

Синхронизация между двумя серверами под djbdns

Если у вас два DNS-сервера с запущенным djbdns, то организовать синхронизацию копий зон намного проще. Для этого можно использовать rsync поверх ssh. Т.о. обеспечивается передача только изменений в файле data.cdb и шифрование передаваемых данных.
Если у вас запрещен вход как root по ssh на сервере, который является вторичным для зоны (т.е. на котором хранится копия), необходимо определиться, под каким пользователем мы будем туда заходить. В моем случае это будет пользователь "max", замените это имя пользователя в примерах на свое.
На вторичном сервере нам необходимо дать права пользователю max на изменение файла data.cdb и запись в каталог /etc/tinydns/root (необходимо для rsync):

# cd /etc/tinydns/
# chown max:max root/data.cdb
# chown max:max root

Теперь изменяем файл /etc/tinydns/root/Makefile на первом (главном) сервере следующим образом:

remote: data.cdb
          rsync -az -e ssh data.cdb max@1.2.6.7:/service/tinydns/root/data.cdb
data.cdb: data
          /usr/local/bin/tinydns-data

В этом примере вам необходимо будет заменить имя пользователя на свое и IP-адрес с 1.2.6.7 на адрес вашего второго сервера.
Помните, что отступы в make-файлах делаются не пробелами, а знаками табуляции. У меня mc заменял их пробелами, так что редактирование лучше делать в vi.

DJB рекомендует как root создать на втором сервере файл data следующего содержания:
    # Do not edit data on this computer! data.cdb is copied from 1.8.7.200.
    # The following line protects data.cdb by stopping make.
    9
чтобы напомнить себе, что его не нужно редактировать и предотвратить случайную перезапись data.cdb

Синхронизация зоны с BIND-сервером

axfr-get — это клиент переноса зоны DNS. Он посылает запроса на перенос зоны в формате DNS-over-TCP в дескриптор 7, читает результат из дескриптора 6 и сохраняет результат в файл.
Обычно, axfr-get запускается из-под tcpclient, который запускает приложение и устанавливает дескрипторы 6 и 7 как TCP-соединение с удаленным хостом.

Формат вызова:
    axfr-get z fn fn.tmp
axfr-get выполняет передачу зоны для домена z. Он читает результаты из файла fn.tmp в формате, который используется как входные данные для tinydns-data. Если передача зоны завершена удачно, axfr-get переименовывает fn.tmp в fn. Файлы fn.tmp и fn должны находиться на одной файловой системе.

axfr-get записывает серийный номер зоны как комментарий в начале fn.tmp. Он пропускает передачу зоны и оставляет fn без изменений, если fn уже существует или если fn имеет серийный номер, совпадающий с серийным номером зоны и оба номера не равны нулю.

Результат переноса зоны зачастую имеет дублирующиеся записи, поэтому необходимо пропустить результат через sort -u.

axfr-get отбрасывает все записи, не принадлежащие домену z. Он принимает записи в подчиненных зонах, но помечает все подчиненные зоны как non-authoritative, так что tinydns не будет сообщать об этих записях, кроме как для связки ("except as glue"). Если Вы планируете объединять результаты axfr-get для домена и подчиненного домена, путем создания файла, полномочного для обеих зон, убедитесь, что устранили записи в первом выводе, которые имеют отношение к подчиненной зоне (исключая запись делегирования подчиненной зоны из основной зоны).

axfr-get будет принимать сколь угодно большую зону при переносе. Чтобы ограничить максимальный объем до 1 МБ, запускайте axfr-get из-под softlimit -f 1048576.

К сожалению, весь опыт в этом вопросе у меня состоял в однократном переносе зоны с сервера BIND при запуске djbdns, поэтому пример будет соответствующий.

# tcpclient 1.2.3.2 53 axfr-get my-domain.ru axfr-get.log axfr-get.log.tmp

здесь:
  • 1.2.3.2 — IP-адреса DNS-сервера с BIND,
  • domain.ru — имя домена,
  • axfr-get.log — файл с результатом,
  • axfr-get.log.tmp — временный файл.
(подробнее о ключах tcpclient можно почитать на странице ucspi-tcp (http://cr.yp.to/ucspi-tcp.html))

Вот, собственно, и все. Непереведенным остались некоторые моменты взаимодействия djbdns и BIND (в силу того, что не было опыта общения с BIND), г.о. касающиеся различных особенностей BIND. Imho если кого заинтересует этот вопрос, он сможет перевести эти моменты сам.

Это вторая и последняя статья о djbdns. В составе этого пакета также имеется rbldns (сервер для поддержки RBL-зон) и walldns. Назначение и смысл работы второго я затрудняюсь сформулировать, DJB позиционирует его как средство сокрытия информации об именах хостов. Для примера: при запросе PTR-записи для 4.3.2.1.in-addr.arpa (IP-адрес 1.2.3.4) walldns отдает А-запись 4.3.2.1.in-addr.arpa, при запросе A-записи для 4.3.2.1.in-addr.arpa — IP-адрес 1.2.3.4, т.е. делается своего рода "отзеркаливание". В отличие от простого отсутствия PTR-записей здесь устраняются тайм-ауты при разрешении имен. Если кто-нибудь захочет попробовать — документация есть на http://cr.yp.to/djbdns.html.

Сcылки:



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