Автоматическое обновление ZSK ключей в подписаной DNSSEC зоне

Давным-давно я прочитал книгу Крикета Ли и Пола Альбитца «DNS и BIND, 5-е издание». Хоть и старенькая книженция (на русскому издавалась в 2008-ом году), но там очень хорошо расписана работа DNS в общем и DNS-сервера BIND в частности. Чего мне сильно не хавтало в этой книге — описания работы DNSSEC.

DNSSEC позволяет убедиться в достоверности ответа DNS-сервера и крайне необходим для других технологий, например для SPF, DKIM, Dane и др.

После изучения man-ов и статей в интернете была поставлена цель — реализация автоматического подписания зон на DNS-сервере Bind с ежемесячной автоматической сменой ZSK-ключей.

Для примера создаём файл простой зоны:

$TTL 3d
@		IN	SOA	server1.example.com.	hostmaster.example.com. (
			1	;Serial
			1d	;Refresh
			12h	;Retry
			1w	;Expire
			3h	;Neg. cashe TTL
			)

			NS	server1.example.com.
			NS	server2.example.com.
			MX	10 mail.example.com.
@			A	xxx.xxx.xxx.xxx
server1		A	xxx.xxx.xxx.xxx
server2		A	yyy.yyy.yyy.yyy
mail		A	zzz.zzz.zzz.zzz

Проверим созданную зону:

$ named-checkzone example.com example.com.db
zone example.com/IN: loaded serial 1
OK

Т.к. зона будет изменяемая — помещаем её в директорию dynamic DNS-сервера:

# cp example.com.db /usr/local/etc/namedb/dynamic/

Создаём папку, где будут храниться сгенерированные ключи и делаем владельцем пользователя, под которым запускается DNS-сервер:

# mkdir -p /usr/local/etc/namedb/keys/example.com/
# chown -R bind:bind /usr/local/etc/namedb/keys

Теперь необходимо сгенерировать KSK и ZSK ключи. Генерация будет осуществляться с помощью dnssec-keygen. Все параметры данной команды можно посмотреть по команде man dnssec-keygen. Используемые здесь параметры командной строки будут в комментариях в скрипате, выложенного ближе к концу статьи.

# cd /usr/local/etc/namedb/keys/example.com/
# dnssec-keygen -a RSASHA512 -b 2048 -f KSK -3 -r /dev/urandom -n ZONE example.com
Generating key pair........................................................................+++ ...............................................................................+++  
Kexample.com.+010+47367
# dnssec-keygen -P +0d -A +1d -R +30d -I +31d -D +32d -a RSASHA512 -b 1024 -3 -r /dev/urandom -n ZONE example.com
Generating key pair...............................................++++++ ...++++++
Kexample.com.+010+57140
# chown bind:bind *

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

# dnssec-dsfromkey Kexample.com.+010+47367
example.com. IN DS 47367 10 1 A89876190D53CE0AE596A35ECE44AA7FF792CFC3
example.com. IN DS 47367 10 2 7D7DF80450D1CC5055149B269178B3B3B7B2F83A9CB0A3785A842EA8DB03D550

Далее приписываем зону в named.conf:

zone "example.com" {
	type master;
	file "/usr/local/etc/namedb/dynamic/example.com.db";
	key-directory "/usr/local/etc/namedb/keys/example.com/";
	inline-signing yes;
	auto-dnssec maintain;
};

Перезапускаем DNS-сервер:

# service named restart

Проверяем:

$ dig +dnssec server1.example.com
; <<>> DiG 9.12.1-P2 <<>> +dnssec server1.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51343

;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; COOKIE: 9677a7929986714103fede805b17c62d6e0315812a4149d2 (good)
;; QUESTION SECTION:
;server1.example.com.           IN      A

;; ANSWER SECTION:
server1.example.com.    259200  IN      A       10.1.1.13
server1.example.com.    259200  IN      RRSIG   A 10 3 259200 20180706111346 20180606102916 47367 example.com. CbEEWwpviFsep6H67yNPsKeDCi+W3PTdE0IwaTI6XbvgUzClDLw8yyBT qKD39qZTb+1wfK18DqmGn/FCZec8bVJGXOmAo9FYb33+Oj8/tMWd3WpB YnzkbtKgKBZQL+TGHpD8UcPmwA1wvVNYn7Rd2tS7INxKMhH8n1fqFBjQ YI6ZNF87YgyQpAXK0213eLu+LYxAFUAkT4Kh5pVnUETn8znlujerlb6S tY+WEiW0800ocWV/DEuZaBBeQxkrJZxQraRhXf7kczNLE7xjOqQ16SpO DZHh/LjlS3UCDhsiJUbDZtCQfUX2Zn6rjgke5FjjxKmnM10Fe4IRRATx LN0rfw==
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: ср июня 06 14:31:57 +03 2018
;; MSG SIZE  rcvd: 391

Также можно проверить, работает ли NSEC3:

$ dig nsec3param +dnssec example.com

; <<>> DiG 9.12.1-P2 <<>> nsec3param +dnssec example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55844
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; COOKIE: d72daff3d6ab97ca475861e15b17c750682f6793f621a150 (good)
;; QUESTION SECTION:
;example.com.                   IN      NSEC3PARAM

;; ANSWER SECTION:
example.com.            0       IN      NSEC3PARAM 1 0 10 FD9875E450BD768A
example.com.            0       IN      RRSIG   NSEC3PARAM 10 2 0 20180706104444 20180606102916 47367 example.com. dJzf+uDBQaj+BEhB/g8VkeXFkgCipTnmCCpzH8cBU+dx4mksc0rJJgg5 rU/6QH4vT7Oac5P0f3g2kKlAGVqDEWWkmna7BX0uceK9yr9zZP7D1sX8 Oj/svb7GWcpT1oNxcCghMtoAfMxJVjF4OWGk5g4bQpgY8M4xgPJkE0bB B+ID1YqyL2RYOgp+1tfGB3ebHAGJ0CqvasMAePGC4jH1F8bm7CRjovS9 BMA/xg931Gl5D/ppVMwfN6HpNO+04O5zU91F3N02lVd7n5SU6AkcU+8D dWHeqYeCWHQFRrfcTxQM58
WTRCDvDD3RHbshtnkQZq2q4CWZAsRHwDKC TQnSJw==
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: ср июня 06 14:36:48 +03 2018
;; MSG SIZE  rcvd: 392

Зона подписана, сервер работает, хэши открытого ключа KSK переданы вышестоящему DNS-серверу. Осталось автоматизировать ежемесячную смену ZSK-ключа. Для этого я написал скрипт на sh с комментариями.

#!/bin/sh
# Прописываем пути, где находятся исполняемые бинарники
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

# Данный скрипт создаёт ключ ZSK для реализации DNSSEC

# Пропишем в переменную $named путь к конфигам dns-сервера
named=/usr/local/etc/namedb

# Зайдём в папку, где будут ключи
cd $named/keys/$1/

# Сгенерируем ключь для подписи набора ключей
# Генерация будет осуществляться с помощью dnssec-keygen. Все параметры данной команды можно посмотреть
# по команде man dnssec-keygen. Описаны здесь только некоторые параметры
# -a определяет криптографический алгоритм
# -f указывает генератору для каких целей создаётся ключь
# -b определяет длину ключа для тех алгоритмов, которые того требуют (например алгоритм на элептических кривых
#    не требует длины ключа)
# -n определяет владельца ключа, в данном случае владельцем будет зона
# -P дата публикации ключа, он будет в зоне, но им не будут подписываться
# -А дата акактивации ключа, он будет в зоне и им будут подписываться
# -R дата устаревания ключа, он будет в зоне и им будут подписываться
# -I после этой даты ключ ещё в зоне, но им уже ничего не подписывается
# -D после этой даты ключ удаляется
dnssec-keygen -P +0d -A +1d -R +30d -I +31d -D +32d -a RSASHA512 -b 1024 -3 -r /dev/urandom -n ZONE $1

chown bind:bind K$1*
# Подпишем зону
rndc sign $1

Осталось поместить запуск скрипта в crontab:

# crontab -l
…
0       9       7      *       *       /path/to/your/scriptdir/dnssec_keygen.sh example.com
…

Добавить комментарий