18 Ноябрь 2016

Поддержка DNSSEC и ротация ключей цифровой подписи

Supporting DNSSEC and signing keys rotation

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

Цифровые подписи DNSSEC в целях безопасности имеют ограниченный срок действия. Увидеть его, равно как и дату подписи, можно в специально предназначенной для этого DNS-записи RRSIG.

root@beta:~ # drill -D peek.ru
...
peek.ru.        86400   IN      A       78.40.219.163
peek.ru.        86400   IN      RRSIG   A 6 2 86400 20161211171306 20161113171306 15134 peek.ru. ABZnLbVjEnQFk7sHoPH2iEX8KRygMjsRSsGzdMVy2scDrMsr8TQSCbs=
...

К примеру, текущая подпись адресной записи (тип A) для домена peek.ru заканчивает своё действие 11 декабря 2016 в 17 ч. 13 мин. 06 сек. После наступления этого срока она будет недействительной что автоматически приведёт к невозможности проверки, является ли она достоверной и не была ли подменена злоумышленником.

Для обновления сроков действия подписей достаточно будет выполнить процедуру подписывания повторно теми же ключами, которые использовались в прошлый раз.

Несмотря на то, что формальных ограничений на срок действия подписывающих ключей нет, хорошей идей с точки зрения безопасности представляется приурочить к процессу переподписи и их обновление тоже. Речь идёт, в первую очередь, о наборе Zone Signing Key (ZSK) который, как правило, имеет меньший размер и, следовательно, более низкую криптостойкость.

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

При любом обновлении ключей подписи важно обеспечивать непрерывность процесса функционирования защищённой DNSSEC зоны. Разрывы, которые могут быть связаны с переходом с одной пары ключей на другую, недопустимы. Важно учесть временные интервалы связанные с различными стадиями процесса ротации, о которых можно подробнее узнать из описывающих эти аспекты функционирования DNSSEC документов RFC6781 и RFC7583

Сам процесс замены ключей электронной подписи проходит в несколько этапов, а процедура различна для ZSK и KSK.

1. Обновление ZSK

1.1. Процесс

Стандарт RFC6781 описывает несколько схем обновления пар ZSK.

Остановимся на предварительной публикации нового ключа как на более экономичной с точки зрения размера подписанной DNSSEC зоны и, как следствие, создаваемого ею DNS-трафика. В наиболее простом варианте эта процедура обновления пары ZSK выглядит следующим образом.

  1. Генерируется новая пара ключей используя тот же алгоритм.
  2. Новый открытый ключ добавляеся в файл зоны для предварительной публикции, а зона подписывается ныне действующими комплектами ZSK и KSK и публикуется.
  3. Через некоторое время, обычно ближе к концу срока действия подписей с корректировкой на максимальный срок жизни записи зоны плюс время на обновление DNS, зона подписывается уже новой парой ZSK и оставшимся прежним KSK, после чего публикуется.
  4. Старый комплект ZSK удаляется из хранилища, в то время как его публичная часть уже была удалена из зоны автоматически при подписывании новым набором ключей.

Это метод широко используется. Например, на момент написания этой статьи его использует и зона .ru имеющая один используемый в настоящее время ZSK с id 62160 и второй предопубликованный с id 17625.

root@beta:~ # drill -D dnskey ru
...
;; ANSWER SECTION:
ru.     331991  IN      DNSKEY  256 3 8 AwEAAcXlVduzE/IlcYAZbY74MP9Q7siVDfNg8avNCTPskuXUsrWL9xKmBLt2NAI/jExR2Yh5CvMTuVXmN9J7RppJVu7JnCzyP6A9K0AAhCNM4NGh39EdBE9A1Vz4OFJy2TQ/miNdPo/E22hyKx9EkYo3HbAmwrANuuM3K+Yms6CUpQkF ;{id = 62160 (zsk), size = 1024b}
ru.     331991  IN      DNSKEY  256 3 8 AwEAAchyCZcyx15dvmiom9AAYmrfYkPiHXHyZnSvCcOus4U4y4Kt/ofSrNFxWIq0ZhwzdKBkS+SBFDMa/6u4RcmL3UBGIkdNRupg/ZOheBkCa6ze2+HIwnDpRei5eak8KYIqf+T0zxzHHhDCTKm8wUS9anNTRcrzk2wfe2RoSw3UIXzr ;{id = 17625 (zsk), size = 1024b}
ru.     331991  IN      DNSKEY  257 3 8 AwEAAYkpXn6XJ6XZMyo4FqHSTwFdX8D7yHJJz5vli6QzcnAdlOtw5Olk6NjimJAJMVpc1kymvSvnZZJEMgYIDgXn0EFNwuCgNNmoHcPhbxHG+1Ke0/SkRX/7cXbUxFgc2emkzCRvQKLCdInP3g/0j53iHxJZRSCmvNmolk7ktXh+XE+r5SAUOupurQzwC/0dwGMepWRL7d3SJCaFUMxr+1+Hm6GaXC1AXP9Bre6LiHJhvtoPsjLTu+uSqEpPhWsioONg7+mMqlX6rL9C4Wax3qouaHRhzld8w/W0LcGb+kaswNhib5XxYiouVL4xsu9o+/NIZ1wBqd8VB/EHozNWa6tUdFk= ;{id = 28642 (ksk), size = 2048b}
ru.     331991  IN      RRSIG   DNSKEY 8 1 345600 20161130000000 20161110000000 28642 ru. N1+xhSCLVgbsfbeYmGPqdSMsT5K8xeHO6Y0URq3azjqOm4Y/62HOS8BUgk71gsc05StWPS82he2yQ1CgyKfWidE57Ew7CSGHfNuwe0aMHmb/7Neoa+eWIT/xKtRj/rXJu3mKIr3p9jGFrxh2EKagG5gPQGYETVuFTpuIm/srSLE/V1p3zCzMZCKCt/sOxWe7faHIGl2X3yy8InQs3eEciHp6nN/a1qbhIDY6zDTUKNJHn+wzHi/zi49ldu6S3XThNybAAempumNuvOPzreX8W8zMAGyjYVLSoGFqVGgXlarQk8WEizCWNbHpU5QdC9RNVacYC5nC/26YeDHfhYQiug==
...

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

Однако, как уже было упомянуто выше, важно учесть временные рамки на осуществление всех этапов процесса с тем, чтобы цифровые подписи, которые будут выполнены с использованием новой пары ключей, стали видимы по всей структуре DNS-серверов, поддерживающих данную зону. При этом, помимо срока окончания действия старых подписей, надо учесть сумму временных интервалов, включающих в себя максимальный срок жизни записей TTL, время периодичности запросов вторичных серверов на обновление зоны (значение refresh в записи SOA) и сам процесс её передачи и применения на них.

Например, для нашего домена peek.ru максимальный TTL составляет 86400, а интервал обновления 14400 секунд.

root@beta:/usr/local/etc/nsd # head -8 zones/peek.ru/peek.ru.zone
$ORIGIN peek.ru.
$TTL 86400
@       IN SOA  beta.peek.ru. hostmaster.peek.ru. (
                2016111300      ; serial
                10800           ; refresh
                1800            ; retry
                604800          ; expire
                14400   )       ; minimum

С учётом срока действия цифровой подписи RRSIG, который по умолчанию при использовании утилиты ldns-signzone составлят 28 дней (или 2419200 секунд), замена подписей должна быть произведена не позднее чем через 2419200 - 86400 - 14400 = 2318400 секунд. Но по мнению автора лучше перестраховаться и заложить более продолжительный интервал учтя, к примеру, максимальный срок действия зоны на вторичных серверах (значение expire SOA). В данном случае он составляет 604800 секунд (или 7 дней) и заведомо перекрывает нужный временной запас. Поэтому, зададимся интервалом действительности для нужд ротации наших цифровых подписей в 2419200 - 604800 = 1814400 секунд или 21 день.

Исходя их этих параметров, зона будет иметь два набора ZSK, выпущенных не позднее 21 дня назад созданные с интервалом между ними не менее 7 дней — более старый (назначим ему номер 1) будет использоваться для подписи совместно с KSK, а новый (номер 2) дожидаться своей очереди будучи предопубликованным. Как только первая пара ключей превысит планку в 21 день, будет сгенерирован новый ZSK (номер 3), при этом он будет также предопубликован в зоне. Туда же для постпубликации будет добавлен и старый набор номер 1, а зона уже будет подписана парой ZSK под номером 2. Далее старый ZSK под номером 1 будет дожидаться срока своего окончания действия в 28 дней по достижении которого он будет перемещён в архив, а с оставшимися цикл повторится. Таким образом, в работающей более 21 дня с момента её подписания DNSSEC зоне всегда будет опубликовано 4 публичных ключа — KSK, а также трио из действующего, предопубликованного нового и прекращающего действие старого ZSK.

1.2. Автоматизация

Инструментарий для автоматизации процессов обновления ключей DNSSEC существует. В частности можно отметить OpenDNSSEC от тех же авторов, что и популярные DNS-серверы Unbound и NSD. Однако этот инструментарий предназначен, в первую очередь, для крупных провайдеров поддерживающих большое, исчисляемое многими десятками и сотнями тысяч, количество зон и предъявляющих серьёзные требования к производительности и надёжности хранения данных. Для последнего, в свою очередь, требуется развёртывание специального защищённого хранилища или системы управления базами данных. Всё это делает применение OpenDNSSEC вряд ли оправданым, если вы поддерживаете не столь большое число защищённых при помощи DNSSEC доменных зон.

При относительно небольшом объёме данных сама файловая система способна предоставить все те данные, которые необходимы для обеспечения процесса ротации ключей DNSSEC. Хорошим примером такого подхода является официальный клиент certbot центра сертификации Let's Encrypt, работу с которым автор описывал в ряде статей. Воспользуемся аналогичным методом и напишем на базе уже знакомого пакета утилит ldns систему автоматизации ротации ZSK c учётом изложенной выше схемы ротации.

Средств shell для этих нужд вполне достаточно, поэтому ограничимся ими.

root@beta:/usr/local/etc/nsd # cat dnszskrotate.sh
#!/bin/sh

# Rotate ZSK key pair for DNSSEC zone
# v.20161118 (c)2016 by Max Kostikov http://kostikov.co e-mail: max@kostikov.co
#
# cat /etc/crontab | grep dnszskrotate
# 0 5 * * * root /usr/local/etc/nsd/dnszskrotate.sh >/dev/null 2>&1

# Warning!
# Require ldns toolset
# Uses dnsnewserial.sh and dnssignzone.sh scripts placed in NSD root

## Settings (see also dnssignzone.sh)
# locations
nsddir="/usr/local/etc/nsd"             # path to NSD root
zonedir="$nsddir/zones"                 # path to zones directories
arcdir="$nsddir/archive"                # path to archive storage
log="$nsddir/var/log/dnsrotate.log"     # path to log file

# timings in seconds
arcage="2419200"                        # keys age to archive (28D)
oldage="1814400"                        # keys age to start rotation (21D)
keygap="604800"                         # interval beetween keys (7D)

## Write to log function
logwrite ()
{
        echo "`date '+%Y-%m-%d %H:%M:%S'` $1" >> $log
}

logwrite "Starting ZSK pair rotation"

## Initial checks
# create main archive directory if doesn't exist
if [ ! -d $arcdir ]
then
        mkdir $arcdir
        logwrite "  Creating main archive directory $arcdir"
fi

# Start zones directories scan
for i in `find $zonedir/*.* -type d`
do
        dom=`basename $i`               # current domain name

        # is zone DNSSEC ?
        if [ `ls $i/*.key | wc -l` -gt 0 ]
        then
                logwrite "  $dom zone in work"
        ## 1. Make cleanup
                # create archive subdirectory if don't exist
                if [ ! -d $arcdir/$dom ]
                then
                        mkdir $arcdir/$dom
                        logwrite "    Creating archive directory for $dom zone"
                fi

                # get into current zone location
                cd $i

                # find oldest expired keys...
                exp=`find *.key -mtime +${arcage}s -exec grep -il '256 3' {} \; | xargs ls -t | head -1`
                if [ -n "$exp" ]
                then
                        keyfs=`basename $exp .key`
                        logwrite "    Moving ZSK pair $keyfs to archive"
                        # ...and move it to archive
                        mv $keyfs.* $arcdir/$dom/
                fi

        ## 2. Generate new keys
                # find actual keys
                cur=`find *.key -mtime -${oldage}s -exec grep -il '256 3' {} \;`
                # it must exist at least two actual keys
                if [ `echo $cur | wc -w` -lt 2 ]
                then
                        # check interval beetween keys
                        chk=`find *.key -mtime -${keygap}s -exec grep -il '256 3' {} \;`
                        # if there is no fresh keys do main procedure
                        if [ -z "$chk" ]
                        then
                                # create new keys pair
                                alg=`echo $cur | cut -d + -f 2 | sed 's/^0*//'`
                                                # detect algorithm
                                new=`ldns-keygen -a $alg $dom`
                                logwrite "    New ZSK pair $new was created"

        ## 3. Adding new ZSK to zone
                                # delete previous prepublished DNSKEY
                                sed -i.bak "/DNSKEY/d" $dom.zone

                                # prepublish new key
                                cat $new.key >> $dom.zone
                                logwrite "    Public key $new added to zone"

        ## 4. Adding old ZSK to zone
                                old=`find *.key \! -newer $new.key -exec grep -il '256 3' {} \; | xargs ls -t | sed -n 3p`
                                if [ -n "$old" ]
                                then
                                        cat $old >> $dom.zone
                                        logwrite "    Old public key `basename $old .key` added to zone"
                                fi

                                # generating new zone serial
                                logwrite "    Serial in $dom zone changed to `$nsddir/dnsnewserial.sh $i/$dom.zone`"

        ## 5. Signing zone
                                logwrite "    Zone was signed using `$nsddir/dnssignzone.sh $i/$dom.zone` keys"
                        fi
                fi
                logwrite "  $dom zone processed"
        else
                logwrite "  $dom zone skipped"
        fi
done

## Infrom DNS server about changes
if [ -n "$new" ]
then
        logwrite "  DNS server zones reloaded `nsd-control reload`"
fi

logwrite "ZSK pair rotation finished"

Данный скрипт dnszksrotate.sh по умолчанию сканирует каталог с зонами DNS-сервера и производит все необходимые действия процесса ротации ZSK. Если в подкаталоге отсутствуют файлы с расширением .key, которые соответствуют публичным ключам DNSSEC зоны, дальнейшая обработка не производится.

Часть требуемого для работы функционала вынесено в два внешних скрипты с тем, чтобы в случае модификации зоны при помощи других средств автоматизации у последних была возможность также подписать её с помощью DNSSEC.

Первый из них — dnsnewserial.sh служит для автоматического изменения серийного номера зоны, который выводится как подтверждение успешного завершения его работы.

root@beta:/usr/local/etc/nsd # cat dnsnewserial.sh
#!/bin/sh

# Change DNS zone serial in YYYYMMDDNN format
# v.20161112 (c)2016 by Max Kostikov http://kostikov.co e-mail: max@kostikov.co
#
# Usage: dnsnewserial.sh /path/to/zone/file
#
# Warning!
# Serial must be placed in separate string with text "serial" as comment.

# check parameters
if [ $# -ne 1 ]
then
        echo "Provide /path/to/zone/file as arguments!"
        exit 1
fi

# is zone file exist?
if [ ! -f $1 ]
then
        echo "Zone file $1 not found!"
        exit 1
fi

# get current serial
curser=`grep "serial" $1 | tr -cd "[:digit:]"`

if [ -z "$curser" ]
then
        echo "Serial not found in $1 file!"
        exit 1
fi

newser=`date '+%Y%m%d'`

if [ `expr $curser : $newser` = 8 ]     # if today serial already changed
then
        newser=`expr $curser + 1`       # increment it
else
        newser=${newser}00              # else assing new
fi

# write new serial to zone file
sed -i.bak "s/.*serial/         $newser \; serial/" $1

# print new serial as confirmation
echo $newser

Второй же, dnssigzone.sh, собственно, предназначен для самого процесса подписания и при успехе выводит наименование ключей, с помощью которых зона была подписана (обратите внимание на переменную sigopt, определяющую дополнительные параметры подписи зоны).

root@beta:/usr/local/etc/nsd # cat dnssignzone.sh
#!/bin/sh

# Sign DNS zone using DNSSEC keys
# v.20161112 (c)2016 by Max Kostikov http://kostikov.co e-mail: max@kostikov.co
#
# Usage: dnssignzone.sh /path/to/zone/file

# Warning!
# Requires ldns toolset
# Keys must be placed in the same directory
# Please adjust setting depending your keys rollover policy

# Check arguments
if [ $# -ne 1 ]
then
        echo "Provide /path/to/zone/file as argument!"
        exit 1
fi

## Prepare parameters
zonedir=`dirname $1`                    # path to zone dir

# Zone is DNSSEC
if [ `ls $zonedir/*.key | wc -l` == 0 ]
then
        echo "Zone have not any keys!"
        exit 1
fi

## Settings
# timings in seconds
oldage="1814400"                        # max keys working age

# signing options
sigopt="-n -t 10 -s `head -c 512 /dev/random | shasum | cut -b 1-16`"
                                        # zone signing options

## Get actual keys list
ZSK=`find $zonedir/*.key -mtime -${oldage}s -exec grep -il '256 3' {} \; | xargs ls -tr | head -1 | sed 's/\.key$//'`
                                        # get oldest existing ZSK
KSK=`find $zonedir/*.key -exec egrep -il '(257|385) 3' {} \; | sed 's/\.key$//'`
                                        # get all existing KSK

if [ -z "$ZSK" -o -z "$KSK" ]
then
        echo "Full keys set not found in $zonedir !"
        exit 1
fi

## Signing zone
ldns-signzone $sigopt $1 $ZSK $KSK

## Print keys names as confirmation
echo "$ZSK $KSK" | sed 's|'$zonedir'/||g'

Все три скрипта помещены в рабочий каталог NSD /usr/local/etc/nsd, а файл протокола сохраняется в подкаталог var/log.

root@beta:/usr/local/etc/nsd # ll dns*.sh
-rwxr-xr-x  1 root  wheel   951 12 нояб. 18:20 dnsnewserial.sh*
-rwxr-xr-x  1 root  wheel  1176 12 нояб. 18:01 dnssignzone.sh*
-rwxr-xr-x  1 root  wheel  3144 12 нояб. 14:51 dnszskrotate.sh*

Запустим основной скрипт и пронаблюдаем его работу.

root@beta:/usr/local/etc/nsd # /bin/sh dnszskrotate.sh
root@beta:/usr/local/etc/nsd # cat var/log/dnsrotate.log
2016-11-18 15:00:00 Starting ZSK pair rotation
2016-11-18 15:00:00   Creating main archive directory /usr/local/etc/nsd/archive
2016-11-18 15:00:00   kostikov.co zone skipped
2016-11-18 15:00:03   peek.ru zone in work
2016-11-18 15:00:03     Creating archive directory for peek.ru zone
2016-11-18 15:00:04     New ZSK pair Kpeek.ru.+006+05023 was created
2016-11-18 15:00:04     New public key Kpeek.ru.+006+05023 added to zone
2016-11-18 15:00:04     Serial in peek.ru zone changed to 2016111300
2016-11-18 15:00:04     Zone was signed using Kpeek.ru.+006+15134 Kpeek.ru.+006+44711 keys
2016-11-18 15:00:04   peek.ru zone processed
2016-11-18 15:00:04   DNS server zones reloaded ok
2016-11-18 15:00:04 ZSK pair rotation finished

Как видно, для домена peek.ru был создан новый набор ключей с id 5023 который был добавлен к зоне для предварительной публикации. Сама же зона была подписана старым набором ключей. В результате после обновления DNS-серверов можно увидеть уже три опубликованных публичных ключа.

root@beta:/usr/local/etc/nsd # drill -D dnskey peek.ru
...
;; ANSWER SECTION:
peek.ru.        78564   IN      DNSKEY  256 3 6 AKC+93W0nJaaY4fHq/q5J8oQrPMpwOoHIhM9ZJBq8kmlVJn0pcaBA4YaeUU04tDgK2kJNBZKUvlh4Ei6oOZTdu8BA9S8XPOzKaKzyFq56Ih3XyR1fTXO7kaN8TIMa4c0h/34E+pMBwQdPXX5YOo6E2BLhpDar9jiuK9WOVR3fa710shy18WcZVpjCtLFV21OucN7aM8KTYH4rG6/qAzagLt0Y9BuuvDEjo9ctka2fWXtYV14zQ82y4TLokF226IOmg8EphfP0ftzgTEe0oTVVhKUQH5M ;{id = 15134 (zsk), size = 512b}
peek.ru.        78564   IN      DNSKEY  256 3 6 CIUe1or+UL6GH0aur4I0Q0KeB4gt6plpYPJLhYae/DwAZPB1RoHzzQQ76FWo7+gc0y/tHBm3aO+8Nell0xa0oiLBxSG6jAHxWt2DEUDdKxRHZk9fpACVgu/nToqs7h/JzPE78MWwR/W7Yk+zeoLuS3ZxK+Xkyvzt7FvIfAm8viauYj1dTmtLoFW6SK9r6mjQyANp5R+kBEQPwmE5KYn0gMFLDAeT7NpuwHxkuObQogObHdMjlC9NYVVAWEizqO9cqvaMR16OBGsKB8BX3cgPDe2wpo9TIWOqiHasOtQfEHkQjOd4FWMdrvhH/y/GtSPyyVYMzuSfrNkpHZWqtGFVrQPHJzpIZZCkBizTGx32gCaFwV8X/1vJ3iAVGlDUzOejvC4UC+YXt6IxzM4IaQbiUC5p8P/+Q77L1PYk5Q2Q3+RPGvn6rbUy7muUA4U8h1Kgit1x5InL5/nOJJ7wqgE1v8lIOddE8/2c1fpJYTr5y7SOL/gJGYVuXx4Rdn2NJpD4w2Cm5vdBIX9d0k/QXtFOSSzTPh1c ;{id = 5023 (zsk), size = 1024b}
peek.ru.        78564   IN      DNSKEY  257 3 6 CNrq1NXCn3vhN1gU1Dn8bYqy5039k+lUe7rPphwZ/rWtAdOXfbF0G8CqRONQKLdp5C4tiBUXwS2PrtdXErXmJM5/bKeBmO3QbHYR0dn8Vhpy1cNWIe/o0aTC/xKQVukXna4TletNODmWF9dPP1jmVRFjthy/U9638tr68tJjpUKwcdmywBbNkIoZNoOCqzZAy1AXRF89vqb5T5onu6OsQqAosm6D6ia1SaqDXLjVfbVHxkMO/yqVOf1T5A7ChmeY+Sf75inywfsHUga70y1SWsp5rXqBrWZcy6Mb4PTxTagWZC1xOBi7VoZXZ7m1jqBsNHzfxRV677/+m8zK7yXkqGFhENaGXi509s20nIYS7c+T9t7p4DRVQgPw6qKjRNQcacGehqM9mfEqazA2FhgnECUlL7Tg/EFHRMVytzA6dURmIZzm3ztcOVEdKNCGCQfUkLAH10aTkZJhilcAgqs68cZRDglm9Dy3PTIxgLcq40N+6krABlfbAaDGaLvrhPGq6cDXWhB45Ff/SS1G5KVxXjnAmajq ;{id = 44711 (ksk), size = 1024b}
peek.ru.        78564   IN      RRSIG   DNSKEY 6 2 86400 20161213040006 20161115040006 44711 peek.ru. AL3+fzC9oTkrDUw/EBChBslxOYYyxpexkmP8vD6d2KRwK9ZUi0fHAys=
...

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

DNSSEC ZSK rotate shell script workflow

Под "0 day" на диаграмме подразумевается первоначальная ручная настройка DNSSEC для конкретной зоны.

Осталось лишь добавить скрипт dnszskrotate.sh в cron для запуска и наслаждаться результатом не забывая, впрочем, на первых порах поглядывать в лог-файл для контроля корректности функционирования системы ротации.

root@beta:/usr/local/etc/nsd # grep "dnszskrotate" /etc/crontab
0       5       *       *       *       root    /usr/local/etc/nsd/dnszskrotate.sh >/dev/null 2>&1

2. Обновление KSK

Механизм обновления пары KSK отличается от уже описанного случая с ротацией ZSK. Здесь оптимальным вариантом для обеспечения неразрывности процесса функционирования DNSSEC зоны будет двойная подпись. В данном случае нет нужды беспокоится о сильном увеличении размера хранимых данных ввиду того, что KSK формирует только одну RRSIG подпись c помощью каждой пары KSK — для записей типа DNSKEY.

Для этого сначала генерируется новая пара KSK.

root@beta:/usr/local/etc/nsd # cd zones/peek.ru/
root@beta:/usr/local/etc/nsd/zones/peek.ru # ldns-keygen -a DSA-NSEC3-SHA1 -b 1024 -k peek.ru
Kpeek.ru.+006+56951
root@beta:/usr/local/etc/nsd/zones/peek.ru # ll
total 56
-rw-r--r--  1 root  nsd       65 18 нояб. 15:00 Kpeek.ru.+006+05023.ds
-rw-r--r--  1 root  nsd      601 18 нояб. 15:00 Kpeek.ru.+006+05023.key
-rw-r--r--  1 root  nsd      694 18 нояб. 15:00 Kpeek.ru.+006+05023.private
-rw-r--r--  1 root  nsd       66 11 нояб. 10:06 Kpeek.ru.+006+15134.ds
-rw-r--r--  1 root  nsd      345 11 нояб. 10:06 Kpeek.ru.+006+15134.key
-rw-r--r--  1 root  nsd      442 11 нояб. 10:06 Kpeek.ru.+006+15134.private
-rw-r--r--  1 root  nsd       66 11 нояб. 10:06 Kpeek.ru.+006+44711.ds
-rw-r--r--  1 root  nsd      602 11 нояб. 10:06 Kpeek.ru.+006+44711.key
-rw-r--r--  1 root  nsd      694 11 нояб. 10:06 Kpeek.ru.+006+44711.private
-rw-r--r--  1 root  nsd       66 18 нояб. 17:31 Kpeek.ru.+006+56951.ds
-rw-r--r--  1 root  nsd      602 18 нояб. 17:31 Kpeek.ru.+006+56951.key
-rw-r--r--  1 root  nsd      694 18 нояб. 17:31 Kpeek.ru.+006+56951.private
-rw-r--r--  1 root  wheel   5991 18 нояб. 15:00 peek.ru.zone
-rw-r--r--  1 root  wheel   5991 18 нояб. 15:00 peek.ru.zone.bak
-rw-r--r--  1 root  nsd    19245 18 нояб. 15:00 peek.ru.zone.signed

После этого зона подписывается используя ныне действующий набор ZSK и сразу оба KSK.

root@beta:/usr/local/etc/nsd/zones/peek.ru # head -c 512 /dev/random | shasum | cut -b 1-16
e2c6800918d7c525
root@beta:/usr/local/etc/nsd/zones/peek.ru # ldns-signzone -n -t 10 -s e2c6800918d7c525 peek.ru.zone Kpeek.ru.+006+15134 Kpeek.ru.+006+44711 Kpeek.ru.+006+56951

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

root@beta:/usr/local/etc/nsd/zones/peek.ru # cd ../..
root@beta:/usr/local/etc/nsd # /bin/sh dnssignzone.sh zones/peek.ru/peek.ru.zone
Kpeek.ru.+006+15134 Kpeek.ru.+006+44711 Kpeek.ru.+006+56951

Теперь следует передать отпечаток нового KSK в виде записи DS (и записи DNSKEY для доменов .ru и .su) регистратору домена. Напомню, что он находится в файле с расширением .ds.

root@beta:/usr/local/etc/nsd # cat zones/peek.ru/Kpeek.ru.+006+56951.ds
peek.ru.        IN      DS      56951 6 1 5359df2affabeb226a44902041166348b1f51007

Одновременно может быть опубликовано больше одного отпечатка KSK.

Перезагрузив зону и выждав необходимое до окончания обновления DNS-серверов время исходя из тех же рамок, как это было описано для случая с ZSK, можно перейти к этапу отзыва старого ключа.

Согласно требованиям стандарта RFC5011 заменяемый KSK должен получить специальный атрибут отзыва revoke в его публикуемой ресурсной записи DNSKEY. Для это воспользуемся специальной утилитой ldns-revoke.

root@beta:/usr/local/etc/nsd/zones/peek.ru # ldns-revoke Kpeek.ru.+006+44711.key
DNSKEY revoked
root@beta:/usr/local/etc/nsd/zones/peek.ru # cat Kpeek.ru.+006+44711.key
peek.ru.        3600    IN      DNSKEY  385 3 6 CNrq1NXCn3vhN1gU1Dn8bYqy5039k+lUe7rPphwZ/rWtAdOXfbF0G8CqRONQKLdp5C4tiBUXwS2PrtdXErXmJM5/bKeBmO3QbHYR0dn8Vhpy1cNWIe/o0aTC/xKQVukXna4TletNODmWF9dPP1jmVRFjthy/U9638tr68tJjpUKwcdmywBbNkIoZNoOCqzZAy1AXRF89vqb5T5onu6OsQqAosm6D6ia1SaqDXLjVfbVHxkMO/yqVOf1T5A7ChmeY+Sf75inywfsHUga70y1SWsp5rXqBrWZcy6Mb4PTxTagWZC1xOBi7VoZXZ7m1jqBsNHzfxRV677/+m8zK7yXkqGFhENaGXi509s20nIYS7c+T9t7p4DRVQgPw6qKjRNQcacGehqM9mfEqazA2FhgnECUlL7Tg/EFHRMVytzA6dURmIZzm3ztcOVEdKNCGCQfUkLAH10aTkZJhilcAgqs68cZRDglm9Dy3PTIxgLcq40N+6krABlfbAaDGaLvrhPGq6cDXWhB45Ff/SS1G5KVxXjnAmajq ;{id = 44711 (ksk), size = 1024b}

Обратите внимание, что код записи изменился со стандартного значения 257 на 385 — это признак отозванной подписи.

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

После чего старый набор KSK с id 44711 можно переместить в архив, удалив его отпечаток у регистратора домена и переподписав зону уже используя новый KSK в паре с ныне используемым ZSK.

root@beta:/usr/local/etc/nsd # mv zone/peek.ru/Kpeek.ru.+006+44711.* archive/peek.ru/
root@beta:/usr/local/etc/nsd # /bin/sh dnssignzone.sh zones/peek.ru/peek.ru.zone
Kpeek.ru.+006+15134 Kpeek.ru.+006+56951

Стандарт не устанавливает обязательств и рекомендаций по периодичности обновления пар KSK, поэтому их ротация осуществляется по усмотрению владельца зоны. Кроме того, этот процесс, как мы только что убедились, требует этапа взаимодействия с регистратором домена, что при отстутствии у него API по обновлению параметров DNSSEC делает эту процедуру сложно автоматизируемой.

3. PROFIT !

Статья была полезной? Тогда прошу не стесняться и поддерживать деньгами через PayPal или Яндекс.Деньги.


dev  DNS  security  shell  DNSSEC