Скажи мне свой IP, и я скажу кто ты

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

Введение

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

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

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

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

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

Все эти проекты основаны на принципе 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 разработан нидерландской организацией NLnet Labs. Разработка началась в 1999 году. К настоящему времени в продакшене используются две версии данного сервера, но в статье будет описана лишь последняя, четвертая. Основные особенности:

По состоянию на 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’ для управления, как локального, так и удаленного. Она позволяет добавлять и удалять зоны на лету, принудительно обновлять их, смотреть статистику.

Knot DNS

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

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

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

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

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

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

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

Unbound

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

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

Синтаксис конфигурационного файла, в общем-то, совпадает с таковым у 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, но им не являющемся):

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

pdnsd

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

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

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

Заключение

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

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

Взято с Xakep.ru