DNSSEC на практике у регистратора доменов

в 5:05, , рубрики: DNS, DNSSEC, безопасность, домены, я пиарюсь, метки: , , ,

В этой статье Webnames.Ru, один из крупнейших регистраторов доменных имен в России расскажет о том, как реализовать на практике протокол безопасности DNSSEC — технологию, которая защищает уязвимые места системы доменных имен, в основе которой лежит метод цифровой подписи ответов на запросы DNS.

Историческая справка

Система доменных имён (DNS) является одной из важнейших составляющих Интернета, однако на момент её разработки вопросам безопасности было уделено недостаточно внимания. С развитием Интернета обнаружились уязвимости в системе DNS. Достоверность ответа DNS-сервера не проверяется, что позволяет подменить ответ сервера, перенаправив запрос пользователя на произвольный IP адрес. Уязвимы оказались и кэширующие DNS-серверы интернет-провайдеров из-за возможности заполнения кэша DNS-сервера данными, не исходящими от авторитетного DNS-источника (атака Каминского).

Впрочем, нельзя сказать, что о безопасности DNS вообще не задумывались до настоящего времени. Серьёзные недостатки в безопасности этой системы были выявлены ещё в 1990 году Стивом Белловином (Steve Bellovin). Исследования в этой области начались со времён публикации доклада в 1995 году, и в 1997 году IETF (Инженерная группа по развитию Интернета) опубликовала первые спецификации на эту тему (RFC 2065). Первые попытки реализации этой спецификации привели к появлению новой спецификации (RFC 2535) в 1999 году. Именно согласно спецификации IETF RFC 2535 и была запланирована реализация DNSSEC, однако у нее были очень серьёзные проблемы с распространением на весь Интернет. К 2001 году стало окончательно ясно, что эта спецификация не подходит для крупных сетей. Это, в свою очередь, вызвало появление новых спецификаций (RFC 4033, 4034 4035) с принципиальными изменениями DNSSEC (DNSSEC-bis), новая версия которой устраняет основную проблему предыдущей реализации и, хотя в новой спецификации клиентам и необходимо совершать дополнительные действия для проверки ключей, она вполне пригодна для практического применения.

К сожалению, как это обычно и случается, недостатки DNSSEC являются продолжением её достоинств. Подписание и проверка данных DNS создают дополнительные расходы, что отрицательно сказывается на производительности сети и серверов. К примеру, в среднем зона DNSSEC в 7-10 раз превышает по размеру саму систему DNS. Генерация и проверка подписей отнимает значительное время ЦПУ. Подписи и ключи занимают на порядок больше места на диске и в оперативной памяти, чем сами данные.

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

Наши дни

Стоит отметить непопулярность данной технологии в рунете. Вспомним, что в зону .SU DNSSEC внедрили в октябре 2011 г., в зону.РФ — в ноябре 2012 г., а в зону .RU — в декабре 2012 г.

Теперь попробуйте вспомнить хоть один домен, подписанный DNSSEC. Не можете? Это ожидаемо. На момент написания этой статьи из трёх регистраторов, заявивших о внедрении у себя DNSSEC, только один (и это Webnames.Ru) подписал свой основной домен. К этому можно добавить, что за всё время существования DNSSEC количество вопросов от пользователей о внедрении этой технологии можно пересчитать по пальцам одного человека.

Тогда возникает логичный вопрос: Зачем внедрять? Дело в том, что Webnames.Ru всегда был и остаётся пионером и первооткрывателем во многих вопросах DNS. Внедрение DNSSEC — наш очередной шаг вперёд. Причём не только для отечественных доменных зон, но и для многих других.

На этом предлагаю закончить с теорией и философией. Теперь рассмотрим практическое использование DNSSEC на собственных name-серверах.

Практические работы

Для того чтобы DNSSEC начал работать так, как задумано его авторами, нужны следующие компоненты:

— подписанная зона первого уровня (у нас есть отечественные .RU .SU и.РФ)
— домен в этой зоне (у нас есть webnames.ru)
— авторитарные DNS-серверы для нашего домена (имеются)
— ресолвер (кеширующий DNS-сервер)

Текущей стабильной версией Debian является Squeeze 6.0.7. Его и будем использовать в качестве базы. В качестве DNS-сервера у нас bind9.

Опустим подробности установки и настройки самого bind9. Ставится он просто:

aptitude install bind9

Компоненты для работы с DNSSEC:

aptitude install dnssec-tools libcrypt-openssl-random-perl

Все конфиги по умолчанию находятся в /etc/bind/
Здесь нас интересуют опции в named.conf.options. В них нужно добавить:

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

После этого нужно перечитать конфиги или перезагрузить bind. Тут есть два варианта: rndc reconfig или /etc/init.d/bind9 restart

Для простоты внедрения будем использовать zonesigner. Это всеобъемлющая утилита, которая подписывает зону за один проход. Есть и более сложный путь, но зачем он нужен?

Забегая вперёд скажу, что в процессе своей работы zonesigner создаёт десяток файлов и рациональнее складывать их отдельно, а не в общий каталог с зонами. Да и зоны лучше не складывать в один каталог. Это не вызывает проблем есть у вас всего несколько доменов. Но если у нас более 150 тысяч зон на каждом сервере, то надо как-то оптимизировать их хранение, иначе возникают громадные накладные расходы.

В процессе эволюции мы получили следующую иерархию зон: auto/ru/w/e/b/n/webnames.ru. Для zonesigner была создана аналогичная параллельная ветвь: dnssec/ru/w/e/b/n/webnames.ru/

Первоначальная генерация подписанной зоны выглядит так:

mkdir -p /var/named/dnssec/ru/w/e/b/n/webnames.ru/
cd /var/named/dnssec/ru/w/e/b/n/webnames.ru/
zonesigner -genkeys -usensec3 -zone webnames.ru /var/named/auto/ru/w/e/b/n/webnames.ru

На выходе получим что-то типа:

        if zonesigner appears hung, strike keys until the program completes
        (see the "Entropy" section in the man page for details)

Generating key pair.....++++++ .........................................................................++++++ 
Generating key pair..++++++ ...++++++ 
Generating key pair....+++ .........+++ 
Verifying the zone using the following algorithms: RSASHA256.
Zone signing complete:
Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                                             ZSKs: 1 active, 1 stand-by, 0 revoked

zone signed successfully

webnames.ru:
        KSK (cur) 02110  -b 2048  02/22/13      (webnames.ru-signset-00003)
        ZSK (cur) 21834  -b 1024  02/22/13      (webnames.ru-signset-00001)
        ZSK (pub) 51069  -b 1024  02/22/13      (webnames.ru-signset-00002)

zone will expire in 4 weeks, 2 days, 0 seconds
DO NOT delete the keys until this time has passed.

А теперь убедимся, что файлов создано много:

$ls -1
dsset-webnames.ru.
Kwebnames.ru.+008+02110.key
Kwebnames.ru.+008+02110.private
Kwebnames.ru.+008+21834.key
Kwebnames.ru.+008+21834.private
Kwebnames.ru.+008+51069.key
Kwebnames.ru.+008+51069.private
webnames.ru.krf

А рядом с файлом обычной зоны появился второй файл webnames.ru.signed, и он в 20 раз больше оригинала — 32669 байт против 1369. И еще 7520 байт на служебные файлы указанные выше. Т.е. мы получили в 30 раз больше информации. Правда, зона webnames.ru совсем маленькая, и такой прирост не сильно тяготит.

На всякий случай проверим новый файл зоны на ошибки:

$ donuts --level 8 webnames.ru.signed webnames.ru
0 errors found in webnames.ru.signed

«—level» — это уровень выдачи ошибок. Когда ошибок нет, то в нём особого смысла нет. Кстати, есть очень простой способ напороться на эти ошибки. Например, добавив NS запись со сторонним DNS сервером.
Добавим в зону запись bad NS ns1.gde-to-tam-daleko.ru и обновимся:

zonesigner -zone webnames.ru /var/named/auto/ru/w/e/b/n/webnames.ru

Обратите внимание, что править нужно всегда обычную зону, а подписанную DNSSEC нужно обновлять именно так.

Теперь проверим на ошибки:

$ donuts --level 8 webnames.ru.signed webnames.ru 
bad.webnames.ru:
  Warning:     Only 1 NS record(s) for bad.webnames.ru found, but at least
                       2 are suggested/required

bad.webnames.ru:
  Error:       sub-domain bad.webnames.ru is not securely delegated.  It is
                   missing a DS record.

2 errors found in webnames.ru.signed

Вот так. Это усложнение структуры стоит учитывать в своей практике. Если вдумчиво читать, то становится понятно, что именно нужно делать. Во-первых, добавить вторую NS-запись, а во-вторых, добавить DS-запись для поддомена.

Но откуда же у нас эти DS берутся? Выше у нас показан файл dsset-webnames.ru. Его содержимое таково:

webnames.ru.            IN DS 2110 8 1 4F38DB26A26DDFFB0A84052472D1AF70DAA595D7
webnames.ru.            IN DS 2110 8 2 0CC3937FE64FD4BF3B8282748F93C566870F4FCD254BCF0D91DBCF50 23D6D28C

Именно эти записи нужно передать регистратору домена, чтобы он их отправил в реестр зоны. И они же нужны для того чтобы donuts перестал выдавать ошибки для NS записей.

Процедура передачи у разных регистраторов разная. На Webnames.Ru, например, в разделе «Управление доменом» в личном кабинете есть специальный пункт «DNSSEC» где можно включить и выключить собственно поддержку DNSSEC, а также увидеть имеющиеся DS записи и, при необходимости, внести новые.

Теперь вспомним о том, что все криптографические ключи имеют срок годности. Неплохо бы автоматизировать и их замену… Для этого есть специальный демон rollerd. Но то, что для этого демона нет init-скрипта, осложняет ситуацию. Поэтому придётся его написать самостоятельно. Можно, конечно, и не писать, а обойтись «колхозными» методами, но это уже каждый решает сам. Еще одна проблема — rollerd хоть и следит за ключами и заменяет их, но не может заменить их в реестре.

Сначала определимся, за чем будем следить. Для этих целей есть rollinit. Он готовит для rollerd список зон, за ключами которых мы собираемся следить. Допустим, что этот список мы будем хранить в dnssec/. Соответственно, добавим туда нашу подписанную зону:

rollinit -zonefile /var/named/auto/ru/w/e/b/n/webnames.ru.signed -keyrec /var/named/dnssec/ru/w/e/b/n/webnames.ru/webnames.ru.krf-admin support@webnames.ru webnames.ru
>> /var/named/dnssec/rollrec

Если кто-то, читая это, уже наделал подписанных зон, то нужно их все добавить в этот же список, либо следить за ключами вручную.

После этого нужно запустить rollerd. Вот обещанный init-скрипт: /etc/init.d/rollerd

#!/bin/bash

### BEGIN INIT INFO
# Provides:          rollerd
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

PATH=/bin:/usr/bin:/sbin:/usr/sbin
DESC="DNSSEC-Tools daemon to manage DNSSEC key rollover"
NAME=rollerd
DAEMON=/usr/sbin/$NAME
SCRIPTNAME=/etc/init.d/$NAME
CONF=/var/named/dnssec/rollrec
PIDFILE=/var/run/rollerd.pid

[ -x "$DAEMON" ] || exit 0
. /lib/init/vars.sh
. /lib/lsb/init-functions
[ -f $CONF ] || exit 0

start_rollerd () {
        [ -f $PIDFILE ] && return 1
        $DAEMON -rrfile $CONF -directory /etc/bind -pidfile $PIDFILE
}

stop_rollerd () {
        if [ -s $PIDFILE ]; then
                PID=`cat $PIDFILE`
                kill $PID && rm -f $PIDFILE
                sleep 3
                [ -d "/proc/$PID" ] && return 1
                return 0
        fi
        PID=`ps xa | grep -v grep | grep $DAEMON | awk '{print $1}'`
        [ -z "$PID" ] && return 0
        kill $PID
        sleep 3
        [ -d "/proc/$PID" ] && return 1
        return 0
}

case "$1" in
        start)
                log_daemon_msg "Starting $DESC" "$NAME";
                start_rollerd;
                log_end_msg $?;
                ;;
        stop|force-stop)
                log_daemon_msg "Stopping $DESC" "$NAME";
                stop_rollerd;
                log_end_msg $?;
                ;;
        restart)
                log_daemon_msg "Restarting $DESC" "$NAME";
                stop_rollerd;
                start_rollerd;
                log_end_msg $?;
                ;;
        *)
                echo "Usage: $0 ";
                exit 1;
                ;;
        esac;

exit 0;

Готовим его к запуску, автозапуску и запускаем.

chmod 755 /etc/init.d/rollerd
update-rc.d rollerd defaults
/etc/init.d/rollerd start

При помощи почтового демона можно автоматизировать и полную ротацию ключей. Мы для этого используем sendmail. Поэтому при помощи smrsh можно сделать почти всё что угодно. Делается это довольно просто. В /etc/mail/sendmail.mc добавляем следующие строки перед первым MAILER’ом:

FEATURE(`virtusertable', `hash /etc/mail/virtusertable')dnl
VIRTUSER_DOMAIN_FILE(`/etc/mail/local-host-names')dnl

В /etc/mail/virtusertable добавляем:
dnssec@localhost dnssec

Таким образом мы создали виртуальный почтовый ящик dnssec@localhost и отправили всю входящую почту на системного юзера dnssec.

В /etc/aliases добавляем:
dnssec: "|/etc/mail/smrsh/dnssec"

Так мы всю входящую почту юзеру dnssec отправили через пайп (т.е. в его STDIN) в скрипт /etc/mail/smrsh/dnssec

А уж в скрипте /etc/mail/smrsh/dnssec мы можем делать всё что хотим.
Стоит отметить, что скриптом это называется условно. Это может быть и бинарник.

Теперь перезапустим sendmail, и все изменения вступят в силу:
/etc/init.d/sendmail restart

При этом не забудьте, что при использовании smrsh нужно переинициировать /var/named/dnssec/rollrec с адресом dnssec@localhost. Т.е. примерно так:

rollinit -zonefile /var/named/auto/ru/w/e/b/n/webnames.ru.signed
-keyrec /var/named/dnssec/ru/w/e/b/n/webnames.ru/webnames.ru.krf
-admin dnssec@localhost webnames.ru >> /var/named/dnssec/rollrec

Сам скрипт /etc/mail/smrsh/dnssec приводить не имеет смысла, поэтому ограничимся обёрткой на bash без функционала.
Само письмо выглядит примерно так:

From: root
To: dnssec@localhost
Subject: assistance needed with KSK rollover of zone webnames.ru

The zone "webnames.ru" is in the middle of KSK rollover. In order for rollover
to continue, its keyset must be transferred to its parent.

Парсить его можно, например, так:

#!/bin/bash

while read L; do
    if [ "${L:0:9}" == "Subject: " ]; then
        for W in $L ; do echo -n '' ; done
        echo "Domain $W"
    fi
done

Т.е. после разбора поля Subject по словам получим в результате имя домена (в переменной W) для которого нужно послать обновлённые DS записи в реестр.

Теперь настроим последний компонент DNSSEC — ресолвер, он же кеширующий DNS-сервер. И здесь всё тоже очень просто. Если взять тот же bind9, то в тот же самый файл /etc/bind/named.conf.options нужно добавить те же опции и перезагрузить bind:

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

/etc/init.d/bind9 restart

Теперь на рабочем компьютере нужно прописать в качестве DNS-сервера наш ресолвер и наслаждаться DNSSEC’ом.

Вот и всё.

Автор: webnames

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js