Как работает DNSSec

Архитектура системы DNS в чистом виде не предполагает какую-либо защиту от подмены адресов – информация передается как открытый текст, а подлинность проверяется только по 2-х байтному идентификатору запроса. Таким образом, для взлома (“отравить кэш”), нужно перебрать всего лишь 65536 вариантов. Эта проблема была осознана еще в 1990-х годах – и, с того момента, неспешным шагом добрались до первой редакции спецификации DNSSec к 1997 году. Текущий стандарт DNSSec был принят в 2005, также в 2008 Дэном Камински было продемонстрировано отравление кэша DNS в течении 10 секунд.
Принцип работы DNSSec
Принцип работы DNSSec тот же, что и у цифровой подписи. То есть закрытым ключом подписываем, открытым сверяем.
Особенность состоит в том, что DNSSec использует два типа ключей — одним подписывается зона (ZSK, zone signing key), другим подписывается набор ключей (KSK, key signing key). Сделано это из таких соображений: зона может быть достаточно большой чтобы удалось подобрать закрытый ключ, поэтому его надо менять почаще, да и сделать его можно покороче, чтобы зоны подписывались быстрее; KSK же используется для небольших объемов данных, поэтому его можно и подлиннее сделать и менять пореже. Тем более, что хэш от открытой части KSK требуется отправить в родительскую зону, что хотелось бы делать не слишком часто.
Ключ ZSK
С помощью этого ключа подписываются все наборы записей в зоне (RRSET), кроме точек делегирования. То есть, допустим у вас есть зона example.com и вы решили эту зону подписать. Сделано будет следующее:
- Создастся последовательность подписанных записей;
- Добавятся записи NSEC (об этом чуть ниже);
- Подпишутся записи SOA, набор NS для example.com, адресные и MX записи для doo, каждая NSEC RR и каждый набор DS.
- В зависимости от настроек софта также может быть подписан набор DNSKEY.
Точки делегирования, т.е. NS записи для дочерних зон, подписаны не будут.
Ключ KSK
Этим ключом подписывается набор DNSKEY записей.
Кроме того, от открытой части KSK берется хэш, который в дальнейшем отправляется в родительскую зону. В вышеприведенном примере это DS записи (Delegation Signer).
В случае с корневой зоной предполагается, что открытая часть ключа будет сообщена резолверу вручную. А чтобы при смене ключа не обновлять его каждый раз вручную, существуют механизмы его автоматического обновления, например у BIND’а есть опция managed-keys.
Очевидно, что закрытую часть KSK следует хранить как зеницу ока — во-первых иначе исчезает весь смысл DNSSec, во-вторых в случае компрометации быстро сменить KSK не получится.
Next SECure
Ну, вот подписали мы зону, но все равно кто-то посторонний может добавить в нее свою информацию и, даже неподписанная, она будет отдаваться сервером наравне с подписанной.
Чтобы такого не происходило, при подписи зоны доменные имена сортируются в алфавитном порядке, к каждому из них добавляется запись NSEC, в которой указывается какое следующее доменное имя защищено и какие записи для него присутствуют в зоне. Последняя NSEC запись указывает на SOA.
Если авторитетный сервер возвращает ответ NXDOMAIN (RCODE=3) или NODATA (RCODE=0), то в ответе обязательно должна присутствовать NSEC запись.
Недостаток NSEC очевиден — кто угодно может получить содержимое зоны просто опросив для каждого имени эту запись. В связи с этим механизм был доработан и появились записи NSEC3, в которых доменные имена хэшируются.
NSEC3 для вычисления хэша может использовать соль, помимо соли можно задать количество итераций. Стоит заметить, что увеличение количества итераций приводит к увеличению нагрузки как на резолвер, так и на авторитетный сервер, причем на последний в большей степени. Это происходит из-за того, что для возвращения NXDOMAIN, авторитетный сервер должен вычислить хэш, и не один. Процесс описан в RFC 5155.
Кроме того, NSEC3 запись имеет поле флагов, которого нет у NSEC. На данный момент определен только один флаг — OPT-OUT, благодаря которому существует возможность подписывать не всю зону (что при больших размерах может быть весьма длительным процессом), а только те доменные имена, для которых есть DS записи.
С одной стороны OPT-OUT позволяет сильно сократить время подписи, однако при его использовании, наличие у злоумышленника доступа к файлу зоны позволяет ему добавить незащищенную запись, которая в дальнейшем может доставить проблемы.
Механизм работы
Допустим мы хотим узнать адрес test.bar.example.com:
- Мы запрашиваем доменное имя у резолвера;
- Резолвер выставляет бит DO и запрашивает test.bar.example.com у корневого сервера;
- Резолвер знает, что корневая доменная зона подписана — у него указан ключ или хэш ключа для нее (так называемый trust-anchor), поэтому он запрашивает у корневого сервера DNSKEY записи для корневой зоны и сверяет полученное с имеющимся;
- Корневой сервер не знает такого доменного имени, да и вообще максимум что ему известно — на каких серверах располагается зона com, он и сообщает адреса этих серверов нашему резолверу вместе с подписанной DS записью для зоны com;
- Резолвер валидирует DS запись полученным и проверенным ZSK ключом корневой зоны;
- Теперь резолвер знает, что зона com подписана, так что он спрашивает у ее DNS сервера DNSKEY и валидирует их, после чего интересуется про bar.example.com. Естественно, что сервер зоны com про таких не знает, ему только известно, что зона example.com живет на ns.example.com и ns1.example.com, именно это он и отвечает резолверу вместе с — да-да — DS записью;
- Так резолвер выстроил цепочку доверия до example.com, где он узнает серверы имен зоны bar.example.com и ее DS;
- В конце концов резолвер итеративно узнает адреса DNS серверов, отвечающих за bar.example.com, идет к ним и наконец-то получает желаемое, валидирует всю информацию и отдает нам адресную запись, выставив в ответе бит AD.
При невозможности что-то провалидировать резолвер вернет servfail.
Оказываемые эффекты
- Исходящий трафик авторитетного DNS сервера увеличивается примерно в 4 раза;
- Размер файла зоны после подписи (без OPT-OUT) вырастает в 6-7 раз;
- Увеличение длины ключа приводит к заметному снижению qps резолвера, на авторитетный сервер влияет в меньшей степени;
- Наоборот действует увеличение кол-ва итераций при использовании NSEC3;
- DNSSec приводит к значительному увеличению DNS ответа и, следовательно, необходимо чтобы все сетевое оборудование корректно работало с DNS пакетами более 512 байт.
Изучить на практике все тонкости DNSSec вы можете на нашем авторском курсе “L2-Security. Безопасность в Linux“.