Применение DNSSEC и TSIG для защиты транзакций DNS
Нет таких организаций, которые могли бы позволить себе пренебречь защитой DNS, ключевой службы, обеспечивающей разрешение имен компьютеров и адресов IP в Internet. Хотя Windows 2000 имеет собственную службу DNS, многие администраторы предпочитают использовать BIND, самый распространенный сервер DNS. В статье «Защита службы BIND DNS» (опубликованной в первом номере нашего журнала за 2002 г. - прим. ред.) я рассматривал узкие места в системе безопасности старых версий BIND и давал рекомендации по настройке контроля доступа в последних версиях BIND 8 (т. е. BIND 8.2.3 и более поздних) и BIND 9 (т. е. BIND 9.1.0 и более поздних) для обеспечения приемлемого уровня безопасности (прим. ред.: в настоящее время доступны версии BIND 8.3.1 и BIND 9.2.0). Однако в той статье не были затронуты два важных момента в системе безопасности: аутентификация и целостность данных. Обязательным условием безопасности является взаимодействие клиента или сервера только с доверенным сервером DNS и аутентификация принимаемой информации. Аутентификация подтверждает, что никто не перехватил и не модифицировал ответ DNS на запрос клиента при передаче по Internet.
Организация IETF, которая занимается стандартизацией протоколов в Internet, разрабатывает стандарт безопасности DNS в Internet (DNSSEC), основанный на технологиях открытых ключей и цифровой подписи. Инженерами IETF был разработан протокол Transaction Signature (TSIG) для аутентификации транзакций DNS. Для защиты транзакций DNS этот протокол использует технологию общих секретных ключей. Описание DNSSEC приведено в стандартах RFC 2535, 3008, а TSIG - в RFC 2845.
Дополнительную информацию о DNSSEC можно найти на сайте NLnet Lab по адресу: http://www.nlnetlabs.nl/dnssec.
Специалисты организации Internet Software Consortium (ISC), разрабатывающей и сопровождающей исходные коды BIND, включили поддержку DNSSEC и TSIG в BIND 8.2.3 и BIND 9.1.0, а также в их более поздние версии. Последние версии BIND 9 обеспечивают более полную поддержку DNSSEC и TSIG, чем в версии BIND 8. Обе реализации BIND выполняют функцию генерации открытых и закрытых (индивидуальных) ключей, но BIND 9.1.0 имеет более широкие возможности применения закрытых ключей для генерации цифровых подписей. Поэтому далее в статье будет рассматриваться реализация DNSSEC и TSIG в BIND 9.1.3. Версия BIND 9.1.3 на платформы Windows 2000 или Windows NT пока не перенесена, но появилась BIND 9.2.0, работающая с Windows 2000 и Win-dows NT. Версия BIND 9.1.0 поддерживается большинством систем Unix и Linux. Я не буду подробно рассказывать о BIND, так как полагаю, что читатели имеют представление об этой программе, а также о технологии цифровой подписи и способах обмена ключами.
Основы DNSSEC
Включение DNSSEC в код сервера BIND DNS обеспечивает криптографическую аутентификацию информации DNS при помощи цифровых подписей. DNSSEC использует цифровую технологию для подписи каждой записи в зоне. Если клиент DNS отправляет запрос, то DNS осуществляет поиск необходимой информации в базе, формирует и подписывает ответ, после чего отсылает его клиенту. Затем клиент DNS использует технологию цифровой подписи для подтверждения целостности принятой записи и аутентификации сервера DNS. Для реализации технологии цифровой подписи DNSSEC добавляет в DNS две новые ресурсные записи (RR): SIG и KEY. Еще одна специальная запись NXT используется DNS для ответов на запросы, для которых не было найдено подходящих записей.
Запись SIG. SIG RR содержит цифровую сигнатуру, ассоциированную с каждой записью RR (например, SOA, NS, A, PTR, MX, CNAME). DNSSEC формирует набор записей, связывая каждую оригинальную запись RR с определенной цифровой сигнатурой SIG. В Листинге 1 приведен пример несекретного файла зоны us.example.com без применения цифровой подписи. На Рисунке 1 показано, как выглядит соответствующий секретный файл зоны с цифровой подписью. Как мы видим, за каждой оригинальной записью RR следует соответствующая SIG RR. Синтаксис записи SIG имеет следующий порядок:
Класс оригинальной записи RR защищаемой при помощи_SIG Алгоритм используемый_SIG Количество составных частей в имени сервера- владельца записи (полезно при использовании групповых символов - wildcards) Первичное время TTL (позволяет задействовать кэш для ответов на запросы) Срок действия подписи Время начиная с которого подпись действительна Идентификатор ключа Домен владелец подписи Подпись
Например, метка D на Рисунке 1 указывает на SIG RR, созданную для записи класса A и определяющую IP-адрес www.us.example.com. Как видно из рисунка, чтобы подписать оригинальную запись класса A, DNSSEC использует алгоритм цифровой подписи Digital Signature Algorithm (DSA). Все алгоритмы перечислены в документе RFC 2535: число 1 соответствует RSA/Message Digest 5 (MD5), 2 соответствует Diffie-Hellman, 3 - DSA. Имя сервера - владельца записи A (т. е. www.us.example.com) - состоит из четырех частей (это www, us, example, com). Первичное TTL составляет 86 400 с. (т. е. один день), действие подписи заканчивается 3 апреля 2001 г. в 6:10:13 по Гринвичу (GMT) (т. е. 20 010 403 061 013), а начинается 4 марта 2001 г. в 6:10:13 по Гринвичу (т. е. 20 010 304 061 013). Значение идентификатора ключа (т. е. число, идентифицирующее открытый и закрытый ключи для зоны) равняется 51 297. Владельцем цифровой подписи является us.example.com, а самая последняя строка с набором символов на тарабарском языке есть цифровая подпись.
Запись KEY. В реализации DNSSEC для генерации цифровой подписи используется закрытый ключ зоны (из пары определенных для этой зоны открытого и закрытого ключей). Закрытый ключ хранится в секрете, а ресурсная запись KEY хранит открытый ключ, используемый клиентом DNS для проверки подлинности цифровых подписей, принятых от DNS-записей. Для каждой записи KEY имеется соответствующая ей SIG, родительская зона подписывает запись KEY. Например, родительская зона examp-le.com подпишет KEY для зоны us.example.com. Запись KEY имеет следующий синтаксис:
флаги протокол алгоритм открытый_ключ.
Флаги определяют тип ключа и способ его использования. Например, метка A на Рисунке 1 указывает на запись KEY для домена us.examp-le.com. Из примера следует, что ключ принадлежит зоне и используется только для идентификации. Цифра 3 соответствует протоколу DNSSEC; следующая по порядку цифра 3 указывает, что для подписи применяется алгоритм DSA. Последняя строка является открытым ключом зоны (в документе RFC 2535 даны объяснения элементов записи KEY RR). Метка B Рисунка 1 указывает на запись SIG, которая соответствует рассмотренной выше записи KEY и служит для определения имени зоны, подписывающей KEY (т. е. домен examp-le.com, который является родителем us.example.com).
Запись NXT. Записи SIG и KEY выполняют идентификацию данных, хранящихся в DNS, однако DNSSEC не обеспечивал бы полной защиты, если бы не предоставлял механизма идентификации записей, отсутствующих в текущей базе данных DNS.
В качестве примера рассмотрим Листинг 1 с записями для несекретной зоны. В том случае, если клиент запрашивает запись product.us.examp-le.com, которой в DNS не существует, сервер DNS, поддерживающий несекретную зону, возвращает клиенту запись SOA и сообщение об ошибке NXDOMAIN (искомая запись не найдена).
Если бы DNSSEC использовал для ответа на запрос о несуществующей записи такой же метод, злоумышленник предпринял бы атаку на пользователей DNS, несмотря на наличие записи SIG для SOA. Он мог бы самостоятельно отправить запрос на DNS или прослушать каналы связи и определить образцы записей SOA и SIG для домена us.examp-le.com. Предположим, что клиент запрашивает DNS-сервер об имеющейся в его зоне записи www.us.example.com, злоумышленник вклинивается в диалог клиента с DNS, и, прежде чем сервер DNS успеет ответить клиенту, сам отправляет ему перехваченные ранее записи SOA, SIG и ошибку NXDOMAIN от имени DNS. Клиент проверит цифровую подпись SOA, убедится в ее подлинности и сделает вывод, что записи www.us.examp-le.com не существует.
Для решения этой проблемы DNSSEC вводит запись NXT RR, указывающую на имена, не найденные внутри определенного интервала имен DNS. (Например, если клиенту известно, что имена расположены в интервале от 1 до 4, текущей записью является 1, а следующей - 4, то клиент делает вывод об отсутствии записей 2 и 3.)
В подписанной зоне DNSSEC расставляет набор записей в определенном порядке (имя зоны, далее запись wildcard (*), хотя ее может и не быть, и все остальные записи располагаются по алфавиту), и добавляет NXT для каждой записи. NXT имеет следующий синтаксис:
Владелец следующей записи типы записей в текущем наборе.
Например, на Рисунке 1 меткой C выделен фрагмент, в котором принадлежащая ns1.us.example.com запись NXT определяет www.us.example.com в качестве владельца следующей записи, а также, что ns1.us.example.com содержит записи типов A, SIG, NXT. Анализируя запись NXT, клиент может определить, что между ns1.us.example.com и www.us.example.com нет других записей. Последняя в зоне запись NXT всегда указывает на первую запись в зоне (т. е. имя зоны). DNSSEC подписывает каждую NXT при помощи связанной с ней SIG, а синтаксис записи NXT не позволяет злоумышленникам обманывать клиентов, представляя существующую ресурсную запись как отсутствующую.
Применение DNSSEC в BIND
Для использования DNSSEC в сервере BIND 9.1.3 необходимо установить в нем секретную зону. Этот процесс состоит из четырех шагов: генерация ключей, создание набора ключей, подписывание набора ключей дочерней зоны, подписывание зоны.
Генерация ключей. Секретная зона обязана иметь хотя бы одну пару открытого и закрытого ключей, назы-ваемых ключами зоны. Закрытый ключ используется для подписи зоны. Клиенты DNS проверяют подлинность цифровой подписи при помощи открытого ключа, составляющего пару закрытому. Если родительская зона (например, example.com) делегирует дочерней зоне (например, us.example.com) полномочия по безопасности, то индивидуальные ключи родителя можно использовать для подписи ключей дочерней зоны. Если родительская зона имеет множество пар ключей, то подписывать родительскую и дочернюю зоны можно различными ключами.
За генерацию ключей на сервере BIND 9.1.3 отвечает команда dnssec-keygen (для получения справки следует ввести ее без параметров). Например, для генерации пары ключей для дочерней зоны us.example.com, рассматриваемой в Листинге 1, необходимо ввести команду:
dnssec-keygen -a DSA -b 1024 -n ZONE us.example.com.
Параметр -a указывает на алгоритм цифровой подписи, который будет использоваться генерируемыми ключами. В соответствии с документом RFC 2535 поддержка алгоритма DSA является обязательной. Это требуется для обеспечения взаимодействия между различными версиями DNSSEC. Дополнительно BIND 9.1.3 поддерживает алгоритмы Диффи-Хеллмана, проверку сообщений с хeшированием по ключам HMAC-MD5, RSA и RSA/MD5. Параметр -b служит для указания длины ключа (в этом примере 1024 бит). Переключатель -n определяет тип имени ключа и может принимать значения zone, host, entity, user. Последним параметром в примере является имя ключа, которое должно совпадать с именем зоны, если указанный тип имени zone.
Дополнительно команда dnssec-keygen позволяет указать протокол, который будут поддерживать сгенерированные ключи. По умолчанию выбран DNSSEC. Команда dnssec-keygen автоматически сохраняет созданные ключи в двух файлах, размещаемых в текущем каталоге; имена файлов определяются параметрами команды. При выполнении рассмотренной выше команды открытый ключ сохраняется в файле Kus.example.com.+003+51297.key, а закрытый ключ в файле Kus.example.com.+003 +51297.private. Первая группа символов 003 указывает на используемый алгоритм (в этом примере DSA, представленный в DNSSEC цифрой 3). Вторая группа символов (51 297 в этом примере) определяет идентификатор ключа (входит в состав записи SIG) и служит отличительным признаком для пар ключей. Файл с закрытым ключом должен быть защищен и спрятан, а имя файла открытого ключа следует поместить в несекретный файл дочерней зоны, как показано в Листинге 1, метка A.
Создание ключевого набора. Прежде чем родительская зона сможет подписывать открытый ключ дочерней зоны, необходимо создать ключевой набор, содержащий открытый ключ дочерней зоны, который родительская зона сможет распознать и подписать. Ключевой набор создается при помощи команды dnssec-makekeyset. Например, команда
dnssec-makekeyset -t 7200 -e 20011231235959 Kus.example.com.+003+51297
создает набор для дочерней зоны us.example.com. Переключатеь -t определяет значение TTL для SIG и KEY. В примере значение TTL составляет 7200 с; значение по умолчанию - 3600 с. Параметр -e определяет время окончания срока действия цифровой подписи родительской зоны. Из примера следует, что срок действия подписи заканчивается 31 декабря 2001 г., в 23:59:59 (т. е. 20 011 231 235 959); по умолчанию подпись становится действительна в течение 30 дней. В рассмотренном примере команда использует установки по умолчанию, т. е. началом срока действия подписи является текущее время. Для изменения установки по умолчанию следует использовать параметр -s. Команда сохраняет ключевой набор в файле keyset-zone. в текущем каталоге (последним символом в имени файла является точка). Рассмотренная выше команда создает файл с именем keyset-us.example.com.. (!!!Внимание, здесь должно быть две точки, не удалять!!!)
Подписывание ключевого набора дочерней зоны. Далее ключевой набор дочерней зоны подписывается родительской зоной. Для этого используется команда dnssec-signkeyset. Например, для того, чтобы родительская зона example.com подписала набор дочерней зоны us.example.com, следует ввести команду
dnssec-signkeyset keyset-us.example.com. Kexample.com.+003+47063
По умолчанию эта команда использует время действия подписи (начала и окончания срока действия), указанное при создании ключевого набора дочерней зоны, однако значения по умолчанию могут быть изменены при помощи параметров -s и -e. Последним параметром является идентификатор ключа родительской зоны. Результат команды сохраняется в файле signedkey-zone. в текущем каталоге (имя файла должно заканчиваться символом точка). В нашем случае файл получит имя signedkey-us.example.com.. (!!!Внимание, здесь должно быть две точки, не удалять!!!) Родительская зона должна секретно передать этот файл дочерней зоне. Файл следует хранить в том же каталоге, что и ключи дочерней зоны.
Подписывание зоны. Теперь рассмотрим, как при помощи команды dnssec-signzone подписывается дочерняя зона. Для подписи несекретной дочерней зоны us.example.com, приведенной в Листинге 1, используется команда
dnssec-signzone -o us.example.com /usr/local/etc/db.us.example
Параметр -o служит для указания имени зоны (т. е. us.example.com). Вторым параметром является полный путь файла зоны (т. е. /usr/local/etc/db.us.example). В результате выполнения этой команды создается файл /usr/local/etc/db.us.example.signed. Чтобы заставить DNS-сервер BIND 9.1.3 загружать секретный файл зоны, следует включить имя файла подписанной зоны в принадлежащий зоне us.example.com файл named.conf (дополнительную информацию о конфигурировании named.conf можно найти в моей статье «Защита службы BIND DNS»). После внесения любых изменений в файл необходимо вновь подписать зону.
DNSSEC обеспечивает надежную передачу данных DNS. Во врезке «Безопасный обмен данными» приведены примеры передачи информации для защищенной при помощи DNSSEC зоны, показанной на Рисунке 1.
Применение TSIG в BIND
Реализация DNSSEC в BIND обладает прекрасными характеристиками, но для эффективного ее применения требуется инфраструктура открытого ключа PKI в Internet и клиенты, поддерживающие возможности DNSSEC. Однако операционные системы Windows не поддерживают DNSSEC, а Internet пока не имеет инфраструктуры PKI. В ожидании, пока DNSSEC получит большее распространение в Internet, можно использовать TSIG для аутентификации транзакций DNS между двумя компьютерами.
При использовании TSIG два компьютера (т. е. два сервера DNS или сервер DNS и клиент DNS) используют общий секретный ключ и алгоритм MD для проверки подлинности сообщений DNS. В отличие от DNSSEC, для функционирования TSIG не нужны заранее подписанные файлы зоны. Перед отправкой сообщений TSIG-компьютер генерирует подпись для каждого пакета. Подпись действительна только для данного пакета. Технология общего секретного ключа TSIG предполагает, что множество компьютеров использует один и тот же секретный ключ. Отправитель применяет этот ключ для преобразования открытого текста в зашифрованный, а получатель - для его расшифровки и преобразования в исходный текст. Специфика использования этой технологии состоит в сложности первоначальной передачи пользователям секретных ключей, поскольку найти абсолютно надежный канал связи нелегко. Данная технология чаще используется для шифрования и обмена данными между двумя пользователями. Это решение масштабируется плохо, и первоначальная пересылка секретного ключа становится проблемой. Технология DNSSEC использует пару ключей и свободна от недостатков TSIG.
TSIG позволяет проводить аутентификацию таких сообщений DNS, как запросы и ответы, динамические обновления и передача данных зоны. Например, можно использовать TSIG для защиты коммуникаций между DNS-серверами организации и DNS провайдера Internet или партнера по бизнесу. Сервер BIND, поддерживающий динамическую зону DNS (DDNS), может использовать TSIG для аутентификации динамических обновлений клиентов, DHCP и других серверов, применяющих TSIG. Это более защищенный тип идентификации для динамических изменений, чем идентификация на основе адреса IP. TSIG может использоваться для аутентификации при передаче информации зоны от первичного DNS- сервера к вторичным. BIND 8.2.4 и 9.1.3, главным образом, поддерживают TSIG для коммуникации между серверами. Поставляемая с этими версиями BIND программа динамического обновления Nsupdate тоже поддерживает TSIG при помощи варианта с секретным ключом.
Предположим, что TSIG используется для защиты соединений между двумя компьютерами host1 и host2. Сначала следует создать секретный ключ для компьютеров. Для этого используется команда dnssec-keygen
dnssec-keygen -a HMAC-MD5 -b 128 -n HOST host1-host2.
Как отмечалось выше, параметр -a определяет используемый алгоритм цифровой подписи для создаваемого ключа. RFC 2845 определяет алгоритм HMAC-MD5 в качестве обязательного для любой реализации TSIG, это необходимо для обеспечения взаимодействия между различными версиями TSIG. Например, BIND поддерживает для TSIG только HMAC-MD5. Максимальная длина ключа для HMAC-MD5 составляет 512 бит (в примере используется длина 128 бит). Имя ключа в примере host1-host2. (точка в конце является частью имени). Выходной файл закрытого ключа содержит вновь созданный ключ. Например, указанная выше команда создает файл закрытого ключа Khost1-host2.+157+59290.private. Внимание: строка в этом файле содержит секретный ключ, который следует тайно передать двум компьютерам. (Прим. ред.: для передачи секретного ключа требуется защищенный канал связи, а для создания защищенного канала необходим секретный ключ.)
Если оба компьютера, host1 и host2, являются серверами BIND, то в файлы named.conf следует добавить секцию описания ключа, как показано в Листинге 2. Для защиты ключа требуется ограничить доступ к named.conf на чтение так, чтобы только привилегированный пользователь мог прочитать файл.
Лучше всего поместить секцию описания ключа в отдельный файл, защитить его и включить ссылку на него в named.conf. В этом случае ограничивать доступ к named.conf не нужно.
Чтобы разрешить компьютеру host1 (IP-адрес 192.168.1.10) использовать ключ и TSIG при отправке сообщения для host2 (IP-адрес 192.168.2.10), следует добавить секцию описания сервера в файл named.conf , как показано в Листинге 3. Подобная же секция добавляется и в файл named.conf ком-пьютера host2 (см. Листинг 4).
Если host2 обновляет динамическую зону, размещенную на host1, то запросы сервера host2 могут быть аутентифицированы при помощи ключа TSIG. Для этого следует добавить в файл named.conf сервера host1 секцию разрешения обновлений, как показано в Листинге 5.
Взгляд в будущее
DNS является базовой службой в Internet. Всем программам, использующим службы Web, DNS необходима для разрешения имен. Безопасность работы этих Web-служб невозможна без защиты службы DNS. Хотя DNSSEC еще не очень широко используется при работе с Internet, но набор разнообразных инструментов безопасности BIND, в том числе DNSSEC и TSIG, может помочь защитить службу DNS. В настоящее время агентство DARPA ведет работу над проектом Fault-Tolerant Mesh of Trust Applied to DNSSEC (FMESHD) по внедрению DNSSEC в Internet. Два фундаментальных изменения в RFC 2535 были добавлены в результате эксплуатации DNSSEC на испытательном полигоне при участии представителей заинтересованных организаций (дополнительная информация об этом проекте размещена по адресу: http://fmeshd.nge.isi.edu). Можно использовать DNSSEC внутри локальной сети организации, в этом случае нет нужды заключать какие-либо соглашения с другими организациями.
Если компьютеры не поддерживают DNSSEC, то транзакции между ними можно защитить при помощи TSIG и нескольких других IETF-протоколов, расширяющих возможности TSIG. В документе IETF RFC 2930 описывается ресурсная запись Secret Key Establishment for DNS (TKEY), которая помогает автоматизировать генерацию секретных ключей TSIG и обмен такими ключами. В документе IETF RFC 2931 описывается DNS Request and Transaction Signatures или SIG(0), использующая открытые ключи для аутентификации запросов и транзакций DNS. В версиях BIND 9.1.0-9.1.3 уже были реализованы функции TKEY и SIG(0) с ограниченными возможностями, но они не были документированы.
К моменту написания этой статьи служба DNS системы Windows 2000 не поддерживала DNSSEC, но обеспечивала частичную поддержку TSIG. Служба DNS Windows 2000 поддерживает секретные динамические обновления в службе каталога AD интегрированной динамической зоны DDNS. Реализация сервера Microsoft Windows 2000 DNS основана на черновом варианте стандарта IETF «GSS Algorithm for TSIG (GSS-TSIG)». Информацию об этом стандарте можно найти по адресу: http://search.ietf.org/internet-drafts/draft-ietf-dnsext-gss-tsig-05.txt. GSS расширяет возможности TSIG при помощи службы Generic Security Service API (описание GSS-API дано в документе IETF RFC 2078).
Тао Чжоу - редактор журнала Windows & .NET Magazine и инженер, работающий в сфере Internet. Имеет сертификаты MCSE и Master CNE. С ним можно связаться по адресу: taoz@ix.netcom.com.
Безопасный обмен данными
Если клиент DNS запрашивает информацию о записи www.us.example.com у сервера DNS, поддерживающего секретную зону us.example.com при помощи DNSSEC, то сервер отправляет клиенту подлинную запись типа А для www.us.example.com вместе с соответствующей SIG RR и ключом зоны KEY RR с его SIG RR. Если клиент поддерживает DNSSEC, то сначала он проверяет срок действия подписи при помощи записи SIG, относящейся к записи A. Если время начала действия подписи имеет большее значение, чем текущее время, то клиент отвергает запись A RR. Если проверка выполнена успешно, то клиент использует открытый ключ и алгоритм, указанный в KEY RR, для проверки цифровой подписи в записи SIG, относящейся к A RR.
После этого клиент проверяет сигнатуру открытого ключа зоны us.example.com (которая используется для проверки целостности A RR). Открытый ключ us.example.com подписывался родительской зоной example.com, поэтому клиент запрашивает открытый ключ example.com (если только у него нет этого ключа в кэше). Если клиент доверяет открытому ключу example.com, то проверка открытого ключа us.example.com проходит успешно, а это значит, что ответ на DNS-запрос действительно получен от us.example.com.
Проверка владельца открытого ключа может выполняться рекурсивно до тех пор, пока не будет найден доверенный владелец. В DNSSEC таким владельцем подписи может быть корневая зона Internet, расположенная на корневых серверах DNS. Таким образом, локальный компьютер, поддерживающий DNSSEC, должен содержать хотя бы один доверенный ключ. Если клиент доверяет только корневой зоне, этот ключ может быть открытым ключом корневой зоны.
Представим себе, что клиент посылает подписанной зоне us.example.com запрос о несуществующей записи product.us.example.com. Зона us.example.com не содержит такой записи, поэтому вместо искомой записи сервер DNS отправляет клиенту запись ns1.us.acme.com, которая в алфавитном порядке размещается перед запрошенной несуществующей записью. Запись NXT в ns1.us.example.com указывает, что следующей записью является www.us.example.com. Из этого клиент может заключить, что между ns1.us.example.com и www.us.example.com нет других записей, следовательно, записи product.us.example.com не существует.