DNS был и остается одним из столпов интернета. Каждый раз, когда ты заходишь в сеть, ты его используешь. Но «стандарт де-факто» DNS-серверов, BIND, очень стар, громоздок и монолитен. В связи с этим мы решили рассмотреть несколько его современных альтернатив.

 

Введение

Раньше, в начале 2000-х, более-менее известных DNS-серверов было крайне мало. Де-факто стандартом для *nix-систем был BIND. Но время шло, BIND становился все более громоздким, и где-то в середине прошлого десятилетия начали обретать известность и другие реализации протокола DNS.

На данный момент существует более двадцати DNS-серверов — от самых маленьких, наподобие miniDNS, который содержит всего 107 строк кода (иное дело, что толком ничего, кроме выдачи одного ответа на любой DNS-запрос, от него не добьешься), до огромных проприетарных систем, содержащих, помимо DNS-сервера, еще много чего. Мы не будем описывать столь крайние случаи, опишем лишь более-менее распространенные и обновляемые свободные серверы имен. К таковым мы отнесли следующие:

  • PowerDNS;
  • NSD (только 4-ю версию);
  • Knot;
  • Unbound;
  • Yadifa;
  • pdnsd.

Все они имеют свои особенности, некоторые из них будут описаны в статье. Кроме того, не так давно на конференции HighLoad++ был представлен доклад о тестировании производительности DNS-серверов. Методы и результаты тестирования также будут здесь описаны.

 

Распределенный DNS

Ввиду попыток правительств некоторых государств «закрутить гайки» и ввести в интернет цензуру, некоторые задумались об альтернативной системе разрешения имен, которая была бы распределенной и децентрализованной и в которой доменное имя нельзя было бы отключить, просто попросив регистратора об этом. На данный момент возникло несколько подобного рода начинаний:

  • NameCoin;
  • BitDNS;
  • DNSchain;
  • DIANNA.

Все эти проекты основаны на принципе BitCoin — то есть, если вкратце, каждый домен хранится в DHT и на определенное время подписывается цепочкой блоков. Затем все происходит вновь.

Идея достаточно неплоха, но вот с реализацией пока что как-то мутновато — половина перечисленных проектов де-факто мертвы.

 

PowerDNS

PowerDNS — достаточно старый сервер, созданный в Голландии в конце 90-х годов прошлого века. Одна из его отличительных черт — разделение DNS-сервера на две совершенно независимые друг от друга части: авторитативный и рекурсивный серверы. Напомню, что авторитативный сервер для своей зоны царь и бог. Рекурсивный же запрашивает информацию аж от корневой зоны и кеширует ее.

PowerDNS поддерживает также множество источников информации — от файлов зон BIND до LDAP и собственных бэкендов, связь с которыми реализуется через пайпы, при этом их можно использовать одновременно. К слову, совместимость с конфигами BIND практически полная, и есть возможность конвертации файлов зон в базу данных. Помимо этого, в нем есть встроенный веб-сервер для снятия статистики и ограниченной возможности конфигурации.

Рекурсивный же сервер, PowerDNS Recursor, поддерживает Lua-скрипты для генерации ответов (впрочем, как и авторитативный), блок-листы и некоторые другие возможности, связанные с безопасностью.

Для установки PowerDNS в CentOS нужно добавить репозиторий — при этом их два: как для рекурсора, так и для авторитативного сервера. Переходим в каталог /etc/yum.repos.d/ и набираем следующие команды (для CentOS 6):

# wget https://www.monshouwer.eu/download/3rd_party/pdns-server/el6/pdns-server.el6.repo
# wget https://www.monshouwer.eu/download/3rd_party/pdns-recursor/el6/pdns-recursor.el6.repo

И теперь уже можно поставить один из них. Опишу сперва авторитативный сервер, а затем кратенько расскажу про рекурсор. Для установки авторитативного сервера (в качестве бэкенда будем использовать MySQL, но ты можешь выбрать любой другой) и некоторых полезных утилит набираем команду:

# yum install pdns-server pdns-server-backend-mysql pdns-tools

Рассмотрим интересные опции в файле конфигурации /etc/powerdns/pdns.conf:

  • any-to-tcp — принудительно переводит запрос ANY в TCP. Это может быть полезно для предотвращения amplification-атак вида (D)DoS-атак, которые основаны на том, что в протоколе UDP невозможно убедиться в подлинности отправителя пакета, и на том, что ответ содержит больше информации, чем сам запрос, что может привести к забиванию канала атакуемого объекта. Может быть равен yes или no;
  • webserver, webserver-address, webserver-password, webserver-port — относятся к встроенному веб-серверу, предоставляющему различную статистическую информацию, такую как частоту запросов, списки хостов, которые обращаются к серверу и которые шлют неверные запросы, и многое другое;
  • launch — указывает, какие модули бэкенда запускать для передачи им запросов. Собственно, это едва ли не основной параметр данного конфига. Допустимо указание нескольких бэкендов и псевдонимов для них.

После настройки фронтенда и выбора бэкенда необходимо настроить еще и последний. В случае с MySQL для этого нужно добавить примерно следующие строки в основной конфиг:

gmysql-host=localhost
gmysql-user=powerdnsuser
gmysql-password=password
gmysql-dbname=powerdns

И создать пользователя и базу данных, импортировав при этом схему из /usr/share/doc/pdns-server-backend-mysql-3.3.1/ (она разнится в зависимости от того, будет ли использоваться DNSSEC или нет). Но на этом мы подробно останавливаться не будем.

Конфигурационный файл PowerDNS
Конфигурационный файл PowerDNS

 

PowerDNS: веб-интерфейс статистики
PowerDNS: веб-интерфейс статистики

Установка рекурсора также проста, естественно, при условии наличия соответствующего репозитория:

# yum install pdns-recursor

Конфиг находится в том же самом каталоге, что и конфиг авторитативного сервера, только называется он recursor.conf. Естественно, одновременный запуск рекурсора и авторитативного сервера невозможен. В конфиге стоит отметить разве что опции max-cache-entries — максимальное количество закешированных записей, max-cache-ttl — время жизни записи в кеше и max-negative-ttl — время жизни тех записей, на которые сервер верхнего уровня вернул отрицательный ответ.

Авторитативный сервер PowerDNS с его возможностью получать данные о зонах оказывается в итоге очень гибким. К сожалению, эта гибкость выходит ему боком — из-за большого overhead’а он, вероятнее всего, будет реагировать на высокие нагрузки медленнее альтернатив.

Cписок RFC, относящихся к DNS

NSD 4

NSD разработан нидерландской организацией NLnet Labs. Разработка началась в 1999 году. К настоящему времени в продакшене используются две версии данного сервера, но в статье будет описана лишь последняя, четвертая. Основные особенности:

  • некеширующий, только авторитативный;
  • полностью совместим с форматом зонных файлов BIND, которые заранее компилируются во внутреннюю memory-mapped БД NSD, nsd.db, что позволяет ускорить запуск сервера имен за счет предварительного парсинга файлов зон;
  • добавление зон на лету;
  • поддержка DNSSEC.

По состоянию на 2008 год NSD использовался как минимум в трех корневых серверах, а именно k.root-servers.net, h.root-servers.net (три сервера с балансировкой нагрузки) и l.root-servers.net. Сейчас, возможно, их количество выросло.

Для установки четвертой версии NSD потребуется скомпилировать его из исходников, поскольку пакеты для него пока что недоступны. Скачиваем их с официального сайта, распаковываем, собираем и ставим. В моем случае для сборки понадобилось поставить пакеты libevent-devel и openssl-devel.

Подготовка к сборке NSD
Подготовка к сборке NSD

 

Основной конфигурационный файл NSD, /etc/nsd/nsd.conf, состоит из нескольких секций. Опишу их:

  • server: в данной секции настраиваются глобальные параметры, такие как количество используемых ядер процессора, адреса, на которых слушает сервер, путь к БД, имя пользователя, под которым сервер будет работать, максимальное количество запросов в секунду от одного источника и так далее;
  • zone: конфигурация зоны. Подобных секций, в отличие от предыдущей, может быть много. Здесь конфигурируются, к примеру, путь к файлу зоны, параметры ACL, список тех, кто может делать AXFR-запросы;
  • pattern: допустимо использовать паттерны для зон, при этом сам паттерн должен объявляться выше, чем объявляется зона. Включается он в зону с помощью параметра include-pattern: в секции конкретной зоны. Опять же подобных секций в конфиге может быть несколько;
  • key: параметры ключей DNSSEC (имя, алгоритм и сам ключ, который, впрочем, из соображений безопасности может быть вынесен в отдельный файл и включаться директивой include:);
  • remote-control: секция, описывающая параметры удаленного управления.

После настройки можно по желанию проверить как конфиг, так и файлы зон на наличие синтаксических ошибок, используя, соответственно, команды ‘nsd-checkconf’ и ‘nsd-checkzone’.

Кроме того, имеется утилита ‘nsd-control’ для управления, как локального, так и удаленного. Она позволяет добавлять и удалять зоны на лету, принудительно обновлять их, смотреть статистику.

Данный сервер, как видим, очень простой, и в нем отсутствуют некоторые расширенные параметры, относящиеся к безопасности (и не только — по некоторым данным, он игнорирует отдельные требования RFC 3597, которые нужны для нормальной работы с неизвестными и новыми ресурсными записями — RR). Однако благодаря своей простоте он требует минимума ресурсов.

Knot DNS

Данный сервер, по сравнению с ранее описанными, еще очень молод — чешская разработка 2011 года. Тем не менее он весьма быстро развивается. На данный момент доступна версия 1.5.3, в которой имеются следующие возможности (помимо полной совместимости со стандартами):

  • использование техники RCU для обновления зон;
  • модульная архитектура, появившаяся в версии 1.5.0;
  • начиная с версии 1.3, вместо связки Flex и Bison в качестве средства для написания парсера файлов зон используется Ragel; это позволило значительно ускорить процесс парсинга — для примера, обработка зоны .net (35 миллионов записей), которая ранее занимала около 1000 с, сейчас занимает около 10.

Для установки последней версии, разумеется, понадобятся исходники, но если самая свежая версия не обязательна, то можно использовать сторонние репозитории (тот же EPEL), благо версия сервера в них не сильно отстает от последней.

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

  • system — здесь конфигурируются примерно те же параметры, что в секции ‘server:’ NSD. Единственное, что стоит отметить, — так это возможность задать в целях безопасности строку версии для ответа на запрос класса CHAOS;
  • remotes — список серверов, с которыми допустим обмен зонами. Отмечу, что на момент парсинга этой опции Knot не делает разницы между первичными и вторичными серверами имен — это происходит на этапе их использования;
  • zones — содержит, во-первых, параметры, общие для всех зон, а во-вторых, сами зоны с их собственными параметрами (со ссылками на файлы зон). Из интересных опций отмечу возможность отключения запросов ANY и возможность дополнительных семантических проверок для файлов зон (по умолчанию они для увеличения производительности отключены). Также здесь можно указать и параметры для модулей;
  • log — параметры логирования. Поддерживается ведение логов в файл, в stdout/stderr и в syslog.

Кроме того, имеется возможность включать отдельные файлы директивой include.

Из модулей на данный момент доступно только два: dnstap, который позволяет логировать в бинарный формат, носящий то же имя, и synth_record, позволяющий генерировать на основе префикса и подсети прямые и обратные записи в случае отсутствия их в файле зоны. Подобная возможность полезна для IPv6-адресов, в противном случае большим провайдерам требуются просто-таки огромные файлы зон.

Хоть данный сервер и молод, выглядит он весьма многообещающе — его уже используют в зоне .CZ. Однако при текущих тенденциях есть небольшой риск, что он превратится в монстра наподобие BIND.

Unbound

Unbound является разработкой все той же NLnet Labs, что создала NSD, но в отличие от последнего он является исключительно кеширующим рекурсором. У него, как и у NSD, отличная поддержка DNSSEC (может выступать в роли валидатора для предотвращения DNS-спуфинга), весь кеш он хранит в памяти.

В отличие от NSD, он есть в репозитории EPEL, так что компилировать его не придется. Установка его более чем обычна:

# yum install unbound

Синтаксис конфигурационного файла, в общем-то, совпадает с таковым у NSD, поэтому его я тут описывать не буду, вместо этого опишу, какие настройки можно оптимизировать.

Во-первых, ‘num-threads’ рекомендуется установить равным количеству ядер. Во-вторых, все параметры, оканчивающиеся на ‘-slabs’, должны быть установлены степенями двойки, максимально близкими к ‘num-threads’. В-третьих, можно увеличить объем кеша, учитывая при этом, что общее количество памяти должно быть больше в 2,5 раза, чем все кеши, и что кеш набора ресурсных записей (‘rrset-cache-size’) должен быть вдвое больше кеша сообщений, ‘msg-cache-size’. Также можно увеличить количество открытых портов с помощью параметра ‘outgoing-range’. На загруженных серверах можно увеличить еще и буферы входящих/исходящих сокетов — ‘so-rcvbuf’ и ‘so-sndbuf’ соответственно.

Посмотрим, что у нас получится в итоге:

server:
    # Используем все процессоры
    num-threads: 8
    # Степень двойки, максимально приближенная к предыдущему параметру  
    msg-cache-slabs: 8
    rrset-cache-slabs: 8
    infra-cache-slabs: 8
    key-cache-slabs: 8
    # Кэш, rrset=msg*2
    rrset-cache-size: 500m
    msg-cache-size: 250m
    # Больше исходящих подключений
    outgoing-range: 8192
    # Увеличенные буферы сокетов — может потребоваться настройка параметров sysctl
    so-rcvbuf: 8m
    so-sndbuf: 8m
    <...>

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

YADIFA

YADIFA расшифровывается как Yet Another DNS Implementation For All и работает в зоне .EU. Разработка началась в 2009-м, но код открыли в 2012-м. По заявлениям разработчиков, потребление памяти у данного сервера самое минимальное из существующих — 135 байт на запись. Для установки нужна компиляция из исходников, которая осуществляется обычным путем.

yadifa-build

Конфиг YADIFA, yadifad.conf, состоит из следующих секций (в формате, аналогичном HTML или XML, но им не являющемся):

  • <main> — здесь у нас, как обычно, общая конфигурация, и ничего нового тут не увидим;
  • <zone> — конфигурация для конкретной зоны; здесь, помимо расположения файлов зон, описывается, к примеру, интервал валидности автоматической подписи;
  • <key> — конфигурация для конкретного ключа, параметры абсолютно идентичны таковым у NSD;
  • <acl> — списки контроля доступа; в выражениях ACL у нас могут быть адреса (и подсети), определенные ключи и сами ACL (рекурсия не поддерживается); для запрета нужно перед объектом поставить восклицательный знак;
  • <channels> и <loggers> — конфигурация логирования; первая секция определяет, какие каналы куда писать (допустимо писать в файл, в syslog и в stderr), вторая же определяет источники для каналов, которых шесть (очевидно, по количеству подсистем): database — события, связанные с изменениями зон; dnssec — например, истечение срока подписи; server — сеть, запросы; statistics — внутренняя статистика; system — управление потоками и планировка; zone — подгрузка и внутреннее представление зон.

YADIFA обещает быть достаточно неплохим сервером. Однако ее компиляция заняла чуть больше времени, чем NSD, а размер почти вдвое больше — что наводит на мысли о достаточно нехорошей тенденции к раздуванию кода.

pdnsd

Очередной кеширующий DNS-сервер, разработка которого началась более десяти лет назад, имеет интересную особенность — его кеш сохраняется на жестком диске, что позволяет использовать данный сервер на медленных интернет-соединениях (в частности, dial-up). Кроме того, в конфиге может задаваться некое подобие зон, которые в терминологии pdnsd именуются «локальными записями». Поддерживаются следующие типы записей:

  • A;
  • PTR;
  • SOA;
  • CNAME;
  • MX;
  • TXT.

Для установки на CentOS достаточно скачать пакет с официального сайта, благо он там имеется:

# wget http://members.home.nl/p.a.rombouts/pdnsd/releases/pdnsd-1.2.9a-par_sl6.i686.rpm
# yum install pdnsd-1.2.9a-par_sl6.i686.rpm

pdnsd-install

Конфиг делится на секции: global, server, rr, neg, source и include. Рассмотрим их подробнее.

Секция global, понятное дело, описывает общие параметры сервера. Здесь интересен параметр paranoid, который служит для предотвращения DNS cache poisoning атаки путем отклонения записей, которые не относятся к пространству имен конкретного DNS-сервера. Еще одна интересная опция здесь — min_ttl, указывающая, сколько запись будет храниться в кеше. При этом она переопределяет время жизни, указанное в самой записи, например если в записи стоит TTL 30 мин, а min_ttl будет равна 60m, запись будет храниться в кеше 60 минут, а не 30.

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

В секциях rr указываются локальные записи. Еще раз отмечу, что это не замена полноценному авторитативному DNS-серверу, — это просто удобное средство для указания некоторых записей для 1.0.0.127.in-adrr.arpa.

Секции neg описывают домены, на которые дается отбой. Это может быть полезным для части программ, которые запрашивают несуществующие хосты и/или записи.

В секциях source можно использовать файл с синтаксисом /etc/host, что позволяет разрешать имена даже в том случае, если ни один DNS-сервер не доступен и в кеше этих имен нет.

Наконец, в секции include (которая, как и global, должна присутствовать в единственном экземпляре), можно подключать другие файлы конфигурации. Если конкретнее, эта возможность предусмотрена только для секции rr.

Может сложиться странное впечатление о данном сервере — из-за обилия опций, касающихся нестабильного соединения, кажется, будто он предназначен для работы в достаточно специфических условиях, в то время как он всего лишь рассчитан на телефонно-модемное соединение. Скорее всего, его имеет смысл использовать в SOHP-сетях, где DNS-трафик относительно мал.

Тестирование производительности DNS-серверов

Не так давно на конференции HighLoad++ было проведено тестирование производительности популярных DNS-серверов. Мы решили дать обзор его результатов. Но сначала опишем тестовый стенд. Сервер — двухпроцессорный Xeon E5-2670, 32 Гб DDR3-1333, сеть Intel X520-DA2 10 Гбит, на генераторе была почти идентичная конфигурация, только на сей раз процессор был один. На обеих машинах стоял Gentoo 3.7.9. Из описанных в данной статье серверов были протестированы следующие:

  • Knot (1.2.0 и 1.3.0-RC5);
  • YADIFA 1.0.2;
  • NSD (3.2.15 и 4.0.0b4);
  • PowerDNS 3.3;
  • Unbound 1.4.16;
  • pdnsd 1.2.9.

По итогам тестирования можно сказать, что Knot победитель. Это не кажется удивительным, ибо сервер очень юн. В то же время YADIFA оказался самым медленным, да и нагрузку он практически не держит — быть может, из-за того, что на момент тестирования он еще не «устаканился»? Следом за Knot идет NSD — скорее всего, из-за его базы данных. PowerDNS показал себя крепким середнячком. Pdnsd же, скорее всего, и не предназначен для высоких нагрузок. А вот Unbound огорчил — вроде и разработчики те же самые, что у NSD, однако он оказался чуть ли не аутсайдером.

Заключение

Как видим, все современные реализации серверов DNS содержат примерно идентичную функциональность. Однако некоторые администраторы (из-за лени или по незнанию) конфигурируют их не совсем правильно (помилуйте, зачем разрешать трансфер зон всем подряд?) или не используют некоторые возможности — такие как DNSSEC.

А вот с производительностью дело обстоит немного иначе. Похоже, сейчас в этом смысле идет незримая гонка — это значит, что данные, приведенные выше, возможно, уже устарели и тот же YADIFA из аутсайдеров пробился в лидеры. Так что в каждом отдельном случае стоит проводить подобные тесты самостоятельно.

Теги:

4 комментария

  1. 22.01.2015 at 17:11

    Я так понимаю, вам очень нравится слово «де-факто»)

  2. 22.01.2015 at 17:34

    картинка чото с DNS не очень асоцыируется.

  3. 22.01.2015 at 19:18

    А когда у хакера будет свой DNS сервер?

  4. 23.01.2015 at 09:34

    А почему в результатах тестирования не было самого популярного bind9, быть может он самый быстрый?

Оставить мнение

Check Also

10 научно-фантастических комиксов для тех, кто не читает комиксы и не любит супергероев

В то время как фильмы по комиксам бьют все возможные рекорды кассовых сборов, сами комиксы…