Корневой ключ DNSSEC меняют иначе, чем любой другой ключ зоны. У него нет родителя, поэтому привычная процедура замены KSKKey Signing Key — ключ, которым подписывается набор ключей зоны через DS-запись у родителя к нему неприменима. Разберём, чем корневой ключ отличается, как устроена машина состояний ключей в BIND, как unbound автоматически обновляет доверенные ключи по RFC 5011 и что показывают измерения готовности резолвероврекурсивный сервер, который по запросу клиента находит нужные данные в DNS к приёму нового ключа.
Почему корневой ключ — отдельная задача
Обычный KSK меняют по схеме из RFC 6781, требующей взаимодействия с родителем и замены DS-записи. Корневой ключ отличается тем, что у него нет родителя. Вместо DS новый ключ аутентифицируется тем, что старый KSK подписывает новый. После этого нужен длительный период, чтобы валидирующие клиенты успели получить и довериться входящему ключу.
RFC 5011 задаёт время удержания при добавлении: 30 дней или время истечения исходного TTL первого DNSKEY RRSet, содержавшего новый ключ, — что больше. Новый KSK добавляется в DNSKEY RRSet корневой зоны, чтобы резолверы автоматически узнали о нём при получении этой записи, и должны добавить его в локальный кэш доверенных ключей после непрерывного наблюдения в течение 30 дней.
В keymgr для KSK время удаления вычисляется с учётом задержки распространения у родителя:
ksk_remove = retire + dns_kasp_dsttl(kasp) +
dns_kasp_parentpropagationdelay(kasp) +
dns_kasp_retiresafety(kasp);Роли ключей и цели состояний в keymgr
keymgr различает роли ключей по двум булевым признакам: если установлены оба признака KSK и ZSK — это CSKCombined Signing Key — ключ, который одновременно подписывает и набор ключей, и данные зоны; только KSK — KSK; только ZSK — ZSK; иначе роль не определена.
Цели состояний обрабатываются отдельно. Цель «скрыт» означает, что ключ должен быть убран из зоны: состояния RUMOUREDключ появился, но ещё не разошёлся по кэшам и OMNIPRESENTключ разошёлся по кэшам переводятся в UNRETENTIVEключ ещё может оставаться в кэшах, а HIDDENключ отсутствует и UNRETENTIVE остаются скрытыми. Цель «повсеместный» означает, что ключ должен быть введён в зону: состояния RUMOURED и OMNIPRESENT становятся OMNIPRESENT, а HIDDEN и UNRETENTIVE — RUMOURED.
Связь с отсутствием родителя у корня видна из описания KSK-ролловера: корневой ключ отличается тем, что у него нет родителя, а новый ключ аутентифицируется подписью старого KSK над новым. То есть для корня нет публикации DS у родителя, поэтому смена ключа аутентифицируется подписью, а не через DS.
Модель состояний ключа
Состояния ключа — это не привычные имена вида generate/published/ready/active/retired/removed/hidden, а HIDDEN, RUMOURED, OMNIPRESENT, UNRETENTIVE и NA.
Состояние вычисляется из метаданных. Если время активации наступило, цель становится «повсеместный», а состояние подписи RRSIG — «повсеместный» или «о котором ходят слухи» в зависимости от того, прошёл ли интервал активации плюс задержка подписи. Если время публикации наступило, состояние DNSKEY становится «повсеместным» или «о котором ходят слухи» в зависимости от времени публикации плюс TTL ключа. При наступившем времени деактивации цель становится «скрытой», а состояние подписи — «скрытым» или «неудерживаемым». При наступившем времени удаления состояние DNSKEY — «скрытое» или «неудерживаемое», состояние подписи — «скрытое», цель — «скрытая».
При переводе ключа в отставку устанавливаются цель «скрыт» и время деактивации в текущий момент. При изменении времени жизни ключа время деактивации становится равным активации плюс срок жизни, после чего обновляется время удаления; если срок жизни равен нулю, время деактивации, удаления и синхронного удаления снимаются.
Как вычисляются моменты времени для активного ключа
Для активного ключа keymgr сначала получает время активации и публикации; если их нет, ставит оба в текущий момент. Затем берёт срок жизни; если его нет, записывает переданный. Время предпубликации вычисляется как TTL ключа плюс запас на публикацию и задержка распространения зоны.
Время отставки берётся из времени деактивации. Если его нет и срок жизни равен нулю, функция возвращает 0 — successorследующий ключ, который вводится на смену текущему не нужен. Если время деактивации отсутствует, но срок жизни больше нуля, время отставки становится равным активации плюс срок жизни, после чего обновляется время удаления. Если предпубликация больше времени отставки, возвращается текущий момент, иначе — разница между отставкой и предпубликацией.
Зависимости между ключами
Проверка зависимостей основана на отношении прямой зависимости: у одного ключа поле successor равно идентификатору другого, а у второго поле predecessorключ, который сменяется другим в цепочке смены ключей равно идентификатору первого. Функция поиска зависимости ищет в наборе ключей такой ключ, для которого текущий является прямым successor'ом, и если его состояние не совпадает с состоянием текущего по скрытым состояниям, возвращает истину и записывает идентификатор зависимости.
Отношение successor'а требует, чтобы у ключа не было других ключей, зависящих от него, и чтобы у второго ключа была хотя бы одна зависимость, причём первый должен зависеть от второго. Ключ не может быть переведён в новое состояние, пока другой ключ не завершит свою фазу, потому что это нарушило бы цепочку зависимостей successor/predecessor или оставило бы зону без необходимых записей DS, DNSKEY или RRSIG.
Разрешение перехода: политика и DNSSEC-безопасность
Проверка политики возвращает истину сразу, если следующее состояние не RUMOURED, потому что локальная политика добавляет дополнительный барьер только для переходов в это состояние. Для типа DNSKEY ограничений нет. Для подписи набора ключей переход разрешён, только если состояние DNSKEY не HIDDEN. Для DS — только если DNSKEY OMNIPRESENT. Для подписи зоны разрешение зависит от состояния DNSKEY или от наличия нового ключа для алгоритма.
DNSSEC-безопасность проверяется через три правила: наличие DS, наличие DNSKEY и наличие RRSIG. Переход запрещается, если при переходе в UNRETENTIVE ни текущее, ни следующее состояние не даёт DS, DNSKEY или RRSIG. Иначе переход разрешается, когда каждое из трёх правил либо не выполнялось до перехода, либо выполняется после.
Ожидание не требуется для переходов в RUMOURED или UNRETENTIVE: в обоих случаях время перехода сразу устанавливается в текущий момент.
Формула retire interval
Для перехода в состояние retired вычисляется время как время последнего изменения состояния подписи плюс максимальный TTL всех подписей зоны плюс задержка распространения зоны. Если у ключа есть предшественник или преемник, к этому времени добавляются задержка подписи и запас на отставку.
Для DS-записей интервал вычисляется иначе: время публикации или удаления DS в родительской зоне плюс TTL DS плюс задержка распространения у родителя, а при наличии предшественника или преемника добавляется запас на отставку.
Перед тем как пометить ключ retired, keymgr проверяет, что переход разрешён политикой, что он DNSSEC-безопасен и что наступило время перехода.
Что происходит, если активный ключ недоступен
Если активный ключ не найден, keymgr перебирает список DNSKEY и ищет совпадение с конфигурацией ключа политики. При совпадении он логирует, что DNSKEY офлайн, устанавливает флаг запрета ролловера и делает этот ключ активным. Затем вызывается процедура ролловера, и если флаг запрета установлен, keymgr логирует предупреждение о том, что DNSKEY офлайн и ролловер не может быть начат, после чего возвращает успех.
Если активный ключ отсутствует и совпадений в списке DNSKEY нет, keymgr логирует отладочное сообщение об отсутствии активного ключа и продолжает процедуру ролловера, создавая новый ключ при необходимости.
Генерация successor и обработка коллизий
keymgr определяет необходимость successor так: если активный ключ есть, вычисляется время предпубликации, и если оно равно нулю или больше текущего момента, возвращается успех без создания нового ключа, а время следующего шага обновляется значением предпубликации. Если предпубликация уже наступила, проверяется наличие существующего successor — при наличии возврат без действий; иначе логируется необходимость successor и, если не установлен флаг запрета ролловера, создаётся новый ключ.
При генерации выполняется цикл, в котором проверяется коллизия по диапазону tag сначала в одном списке ключей, затем в двух других. При обнаружении конфликта логируется предупреждение о коллизии идентификатора, ключ освобождается, и цикл повторяется до отсутствия конфликта. После успешной генерации устанавливаются срок жизни, признаки KSK/ZSK и каталог, а затем новый ключ связывается с активным через поля predecessor и successor: активный ключ получает цель «скрыт», а новый — «повсеместный».
Ограничение: один ключ за раз
Функция обработки checkdsпроверка публикации или удаления DS-записи у родителя для ключа подписи зоны перебирает набор ключей, отбирает ключи с признаком KSK и, если находит второй подходящий KSK, возвращает ошибку «слишком много ключей» с комментарием, что checkds выполняется только для одного ключа за раз. Аналогично в процедуре ролловера перебор отбирает ключ по идентификатору и алгоритму, и при обнаружении второго совпадения возвращается та же ошибка. Если ни один ключ не найден, обе функции возвращают ошибку отсутствия совпадения. Никакие счётчики или эпохи в этих проверках не участвуют: ограничение — это единственная переменная-указатель, которая при повторном совпадении приводит к ошибке.
Хранение состояния и обновление подсказок
keymgr хранит состояние ключей в самом файле ключа: после изменения состояний он обновляет подсказки и записывает ключ, после чего сбрасывает флаг изменения. При обработке checkds он устанавливает время публикации или удаления DS, при необходимости меняет состояние DS на «о котором ходят слухи» или «неудерживаемое», затем сохраняет состояние и подсказки в файл.
В основном цикле для каждого ZSK состояния вычисляются по временным меткам и задержкам, время следующего шага обновляется как минимальное будущее изменение, а при изменении состояния записываются новое состояние и время. Если ключ помечен изменённым, он сохраняется на диск вместе с обновлёнными подсказками.
При инициализации состояния и времена устанавливаются только если их ещё нет, а цель — только если её ещё нет. При рассинхронизации состояния на диске keymgr при следующем запуске инициализирует отсутствующие состояния из временных меток и политики, а не перезаписывает уже существующие.
Создание ключей, когда их не хватает
keymgr перебирает все ключевые конфигурации политики и для каждой ищет в наборе подходящий ключ. Если найден, обновляет срок жизни и, при необходимости, помечает его как активный. Если активный ключ не найден, он проверяет список DNSKEY на наличие офлайн-ключа, соответствующего политике, и при совпадении выставляет флаг запрета ролловера и использует этот ключ как активный.
Затем вызывается процедура ролловера, которая при наличии активного ключа вычисляет время предпубликации; если оно равно нулю или ещё не наступило, ролловер откладывается. Если ролловер разрешён, ищется неиспользуемый ключ-кандидат в наборе, и если он найден, используется как новый; иначе новый ключ остаётся пустым и вызывается генерация. Созданный ключ добавляется в список новых, а после обхода всех конфигураций политики новые ключи добавляются в набор.
Обработка отозванного ключа
В unbound отозванный ключ обрабатывается событием RevBit: если якорь находится в состоянии VALID или MISSING и у него выставлен флаг revoked, якорь переводится в состояние REVOKED и меняется идентификатор ключа на «после отзыва». Это соответствует норме RFC 5011: ключ считается отозванным, когда резолвер видит его в самоподписанном RRSet с установленным битом REVOKEфлаг DNSKEY, помечающий ключ как отозванный, а отзыв немедленный и постоянный при получении валидного отзыва.
Удаление из набора якорей не мгновенно: в состоянии REVOKED, если ключ больше не виден, срабатывает проверка времени удержания удаления, и только по его истечении якорь переводится в REMOVED. Если же ключ всё ещё присутствует, таймер удержания сбрасывается. RFC 5011 описывает это как событие RemTime: отозванный ключ отсутствовал в DNSKEY RRSet достаточно долго, чтобы быть удалённым из набора доверия.
Публикация DNSKEY и CDS/CDNSKEY
Публикация DNSKEY строит запись и добавляет её в diff. Если у ключа задано время предпубликации и TTL больше него, активация откладывается установкой времени активации в текущий момент плюс TTL. Сначала публикуются ключи из командной строки, а TTL берётся из уже опубликованного ключа зоны либо, если такого нет, из наименьшего ненулевого TTL ключей репозитория. Новые ключи без совпадения добавляются в список и публикуются, если их источник не зона и задана подсказка или принудительная публикация.
Для CDS/CDNSKEY запись CDS строится для каждого digest и добавляется, если её ещё нет; CDNSKEY добавляется, если задан флаг генерации и записи нет. Удаление CDS/DNSKEY для удалённых ключей выполняется безусловно: для каждого ключа перебираются все digest и вызывается удаление CDS, а CDNSKEY удаляется, если он присутствует.
Проверка целостности NSEC/NSEC3 в zoneverify
Проверка NSEC-цепочек ищет NSEC-набор в узле; если запись отсутствует, ставится результат «отказ». Затем берётся первая запись и проверяется, что поле next совпадает с ожидаемым именем — иначе «отказ». Далее строится эталонная запись и сравнивается битовая карта типов — при несовпадении «отказ». Наконец, если после первой записи есть ещё записи, ставится «отказ»; иначе «успех».
Соответствие NSEC3PARAM проверяется так: для каждого NSEC3-набора декодируется hashlabel в owner, и запись учитывается только если длина next совпадает с длиной декодированного хэша и запись соответствует параметрам. Параметр считается пригодным, если флаги равны нулю, число итераций не превышает максимум и хэш поддерживается. Если нет ни NSEC-набора, ни пригодного NSEC3PARAM, возвращается «отказ».
DS-формат trust anchors в zoneverify
Когда у keynode есть DS-формат trust anchors, это означает, что DNSKEY-формата у него нет, поэтому проверка может ограничиться сопоставлением DS и затем остановиться. Для каждого DS-ключа сначала сравниваются key tag и алгоритм; при несовпадении элемент пропускается. При совпадении из ключевых данных строится новый DS с digest проверяемого DS, и если записи совпадают, у набора ключей и подписей выставляется доверие «secure», а признак хорошего ключа — истина, после чего цикл прерывается. После цикла DS-набор отсоединяется и управление переходит на очистку. С DNSKEY RRset это связано через набор ключей: именно ему и подписям присваивается доверие при успешном DS-совпадении, а проверка DNSKEY позже перебирает этот набор.
Таблица состояний RFC 5011 в unbound
Функция обновления состояния якоря реализует переходы таблицы RFC 5011. Событие NewKey переводит STARTначальное состояние, в котором ключ ещё не рассматривается как кандидат в доверенные в ADDPENDсостояние ожидания: ключ уже замечен, но время удержания добавления ещё не истекло. Событие AddTime переводит ADDPEND в VALIDсостояние действующего доверенного ключа, которому резолвер доверяет. Событие KeyRem переводит ADDPEND в START и VALID в MISSINGсостояние, в котором доверенный ключ пропал из DNSKEY RRset. Событие KeyPres переводит MISSING в VALID. Событие RevBit переводит VALID или MISSING в REVOKEDсостояние отозванного ключа, который признан недействительным для всех целей, кроме проверки отзыва. Событие RemTime переводит REVOKED в REMOVEDсостояние, в котором ключ удалён из набора доверенных.
Add hold-down time и планирование probe
Add hold-down time вычисляется через проверку времени удержания с параметром добавления, и при превышении и состоянии ADDPEND якорь переводится в VALID только если счётчик ожиданий не меньше минимума, после чего счётчик сбрасывается.
Планирование следующего зондирования берёт интервал запроса; при запрете малого времени удержания он поднимается минимум до 3600 секунд, иначе при нуле становится 1. Затем к текущему времени добавляется случайная добавка от 0 до одной десятой интервала, так что момент попадает в диапазон 90–100% от интервала.
Файл trust anchor распознаёт только строки заголовка last_queried, last_success, next_probe_time, query_failed, query_interval и retry_time; строк для add_holddown или active refresh там нет. По RFC 5011 add hold-down time равен 30 дням или времени истечения исходного TTL первого DNSKEY RRSet, содержавшего новый ключ, — что больше, а queryInterval равен максимуму из одного часа и минимума из 15 дней, половины исходного TTL и половины интервала истечения подписи.
Пропажа ключа и удаление trust point
Когда ключ пропадает из DNSKEY RRSet, он переходит в состояние MISSING, и для него проверяется, истёк ли срок сохранения пропавшего ключа. Если срок истёк и есть хотя бы один валидный KSK, ключ помечается как REMOVED. Если срок сохранения равен нулю, ключ сохраняется навсегда. Trust point удаляется целиком, когда после изменений не остаётся ни DS, ни DNSKEY — это происходит в двух местах: после обработки отозванных ключей и после обработки таблицы состояний, если изменения были и ключей не осталось.
REVOKE-бит и fingerprint
Когда в DNSKEY RRSet у ключа выставлен REVOKE-бит, unbound в состоянии VALID или MISSING переводит якорь в REVOKED и меняет идентификатор ключа. Это соответствует RFC 5011: DNSKEY с установленным REVOKE-битом имеет другой fingerprintотпечаток ключа — уникальное значение, по которому ключ сопоставляется с DS-записями и сохранёнными доверенными ключами, чем без него, поэтому отозванный ключ перестаёт совпадать с прежним отпечатком и DS-записями. В состоянии REVOKED, если ключ больше не виден, по истечении времени удержания удаления он переводится в REMOVED; если же ключ снова виден, таймер сбрасывается. Согласно RFC, при REVOKE-бите и наличии подписи DNSKEY от этого ключа резолвер должен считать ключ постоянно недействительным для всех целей, кроме проверки отзыва.
Планирование probe и обработка ответа
Следующее время проверки вычисляется так: берётся переданный интервал, при выключенном разрешении малого времени удержания он поднимается минимум до 3600 секунд, иначе при нуле делается 1; затем добавляется случайная добавка от 0 до одной десятой интервала. Функция установки следующего зондирования удаляет точку доверия из дерева, присваивает время по интервалу запроса и вставляет обратно, а если минимальное время ожидания изменилось, переставляет таймер. Функция обработки очереди берёт первую точку из дерева, и если её время уже наступило, удаляет её, пересчитывает время по интервалу повтора и вставляет обратно.
Обработчик ответа не разбирает код ответа, буфер, статус безопасности и причину — все эти параметры помечены как неиспользуемые; он лишь логирует ответ и вызывает сброс таймера, который под блокировкой читает ближайшее время и переставляет таймер. Состояние trust point обновляется не в обработчике ответа, а через функцию обновления состояния.
Выбор следующего подписывающего ключа в validator
Когда проверка подписи текущим ключом завершается неуспешно, validator вызывает выбор следующего подписывающего ключа. Если функция вернула успех, гарантируется, что ключ не пуст, и проверка с новым ключом снова ставится в очередь. Если функция вернула «не найдено», гарантируется, что ключ пуст, и тогда проверка завершается. При любой другой ошибке результат устанавливается в код ошибки, и если превышен лимит отказов, ключ принудительно обнуляется, после чего вызывается обработка отказа проверки.
Отсутствие trust anchor для корня
Когда имя является корнем и доверенный ключ отсутствует, validator прекращает проверку: если флаг попытки проверки установлен, пишется отладочное сообщение «корневой ключ не прошёл проверку», иначе — «нет доверенного корневого ключа», после чего возвращается результат «нет валидной подписи». Ветка с поиском DS-набора для корня не выполняется, поскольку DS в корне не существует.
Временные ошибки и счётчик отказов
Временные ошибки обрабатываются отдельной ветвью: при ошибке «подпись из будущего» или «подпись истекла» выставляется соответствующий EDE-код, после чего обработка прерывается — счётчик отказов не трогается. В комментарии прямо сказано, что временные ошибки не учитываются в лимите отказов. Все прочие ошибки попадают в общую ветвь, где сначала проверяется превышение лимита, и если он превышен, результат заменяется на «квотуОшибка ISC_R_QUOTA, которой заменяется результат проверки подписи, когда превышен лимит отказов.»; иначе вызывается обработка отказа, увеличивающая счётчик. Таким образом, временные ошибки не увеличивают лимит, потому что для них не вызывается обработка отказа и не проверяется превышение лимита.
Pending и trusted RRset
Когда RRset имеет состояние pending и одновременно является trusted, validator пытается проверить, не был ли этот RRset самоподписан данным DNSKEY. Для этого строится ключ; если алгоритм не поддерживается, проверка этого ключа пропускается без учёта в счётчике неудач, а при прочих ошибках создания ключа учитывается неудача и при превышении лимита возвращается «квота». Затем выполняется проверка подписи; при успешной проверке ключ с флагом REVOKE признаётся скомпрометировавшим самоподпись, и view перестаёт ему доверять. Временные ошибки не засчитываются как неудачи, а прочие ошибки увеличивают счётчик и могут привести к «квоте». Если же RRset не pending, но его доверие не ниже «secure», ключ с меткой revoked также удаляется из доверенных.
Сборка rrsets trust anchors в val_anchor
Для каждого trust anchor функция сборки создаёт структуру rrset: выделяет ключ, копирует имя и класс, устанавливает тип DS или DNSKEY и заполняет данные, перебирая список ключей и отбирая элементы нужного типа; данные переиспользуются, TTL ставится 0, а доверие — «ultimate». Функция сборки вызывает сборку отдельно для DS и для DNSKEY, сохраняя результаты. Функция сборки rrsets обходит дерево якорей, пропускает точки с autotrust или без DS и DNSKEY, собирает rrsets, проверяет поддержку алгоритмов и удаляет точку, если все DS и DNSKEY неподдерживаемы.
Autotrust обрабатывается последним, чтобы видеть якоря, заполненные другими способами, и сообщать об ошибках двойной конфигурации для имени. После этого вызывается сборка rrsets, поскольку она может удалить ненужные якоря.
Чтение файлов trust anchors в формате BIND9
Файл в формате named.conf читается так: он открывается, затем в цикле ищется ключевое слово trusted-keys, всё остальное игнорируется. После нахождения ожидается открывающая скобка, затем разбирается содержимое до точки с запятой, после чего ожидается точка с запятой. Специальными символами в BIND-конфигах считаются только открывающая и закрывающая фигурные скобки, кавычка и точка с запятой. Разбор разбивает файл на токены: спецсимволы идут отдельно, пробелы сворачиваются в один пробел или таб, переводы строк заменяются на пробел, а комментарии пропускаются. Внутри разбора кавычки переключают режим: открывающая кавычка включает режим цитирования и выключает комментарии, а закрывающая при ненулевом счётчике и активном цитировании вставляет строку «DNSKEY» и возвращает комментарии. Insecure points обрабатываются так: перебираются узлы дерева и возвращается первый, у которого есть DS или DNSKEY, то есть не являющийся insecure point.
Добавление RR к trust anchor
Добавление нового RR выполняет функция, которая сначала проверяет, что тип RR равен DS или DNSKEY, иначе возвращает ошибку. Затем она ищет существующий trust anchor, а если его нет — создаёт новый. Если данные равны NULL, запись не сохраняется, но trust anchor создаётся и возвращается. Дубликаты удаляются: перед добавлением проверяется совпадение по типу, длине и содержимому, и при совпадении новый ключ не добавляется. Новый ключ создаётся и вставляется в начало списка, при этом счётчик DS или DNSKEY увеличивается в зависимости от типа. Ограничение на структуру: в файле при флаге единственности допускается несколько ключей, но они должны иметь одно и то же имя домена.
Схемы rollover по RFC 6781
RFC 6781 описывает для ZSK-ролловеров две схемы: Pre-Publish и Double-Signature. Pre-Publish состоит из четырёх стадий, при этом зона не подписывается дважды, но новый ключ заранее публикуется и доступен для криптоанализа; минимальная длительность фазы предварительной публикации — время распространения данных плюс TTL набора ключей. Double-Signature состоит из трёх стадий, но во время ролловера число подписей в зоне удваивается, что может быть неприемлемо для очень больших зон.
Для KSK-ролловера применяется Double-Signature, при этом размер зоны не важен, так как KSK подписывает только набор ключей; ролловер KSK требует взаимодействия с родителем и ожидания TTL DS. Компромисс Pre-Publish — четыре стадии и больше родительской работы при KSK, но без удвоения подписей; компромисс Double-Signature — три стадии, но удвоение подписей.
Согласование signature validity, re-sign period и TTL
RFC 6781 рекомендует, чтобы максимальный TTL зоны был меньше периода действительности подписи, а TTL был как минимум в несколько раз меньше периода действительности подписи, чтобы избежать пиков нагрузки на авторитетные серверы. Публикация подписи должна заканчиваться как минимум за один максимальный TTL зоны, предпочтительно за несколько дней, до конца периода действительности подписи.
Период повторной подписи — это частота, с которой выполняется проход подписи по зоне, а период обновления — это окно, в котором подписи, близкие к истечению, пересоздаются. Период повторной подписи должен быть меньше периода обновления, чтобы данные зоны подписывались своевременно. Эти значения должны быть согласованы, потому что в худшем случае подписи, истекающие первыми, находятся на расстоянии периода обновления минус период повторной подписи от истечения, и это время определяет, сколько времени есть на устранение операционных проблем.
Security lameness и период действия подписи DS
Security lameness — это состояние, когда у родителя есть DS RR, указывающий на несуществующий DNSKEY RR. Оно может временно возникать при схеме Double-DS rollover, но нельзя допускать, чтобы все DS RR указывали на несуществующий DNSKEY, иначе зона ребёнка будет помечена проверяющими клиентами как Bogusсостояние, при котором проверяющий резолвер не может подтвердить подлинность данных зоны и считает её недостоверной. После того как зона стала security lame, исправление, например удаление DS RR, требует времени на распространение через DNS.
Для периода действия подписи DS: короткий срок минимизирует уязвимость при компрометации KSK ребёнка, но слишком короткий риск того, что зона будет помечена Bogus при ошибке конфигурации подписывающего; рекомендуется абсолютный минимум в несколько дней, а компромисс между политикой родителя и минимизацией ущерба — от недели до нескольких месяцев. При хранении ключей или хешей: реестр не может рассчитывать на генерацию DS из сырого DNSKEY, поэтому реестровые системы должны уметь хранить DS RR, даже если они также хранят DNSKEY; интерфейс должен позволять загрузку DS RR с неизвестными хеш-алгоритмами, а не только DNSKEY.
Emergency key rollover при компрометации KSK
При компрометации KSK RFC 6781 указывает, что злоумышленник может использовать ключ, пока существует действительная цепочка доверия. Цепочка доверия остаётся целой, пока действительна подпись над скомпрометированным ключом в цепочке, пока DS RR в родительской зоне указывает на скомпрометированный ключ, подписывающий DNSKEY RRset, и пока скомпрометированный ключ закреплён в резолвере как доверенная точка.
Администратор зоны решает, разорвать ли цепочку доверия: при разрыве данные в кэшах, подписанные этим ключом, не могут быть проверены, а при обычном ролловере владелец вредоносного ключа может продолжать подменять данные. При компрометации KSK доверенную точку или родительскую DS-запись следует заменить как можно скорее; разрыв цепочки происходит, когда скомпрометированный KSK удаляется из дочерней зоны, пока родитель всё ещё имеет DS-запись, указывающую на него.
Если цепочку нужно сохранить, применяется процедура: ввести новый KSK, понизить TTL для DNSKEY, подписать набор ключей с коротким сроком действия, загрузить DS нового ключа родителю, дождаться появления DS и истечения TTL старых DS, затем удалить скомпрометированный DNSKEY и переподписать набор ключей. Если цепочку разрывают, есть два метода: заменить KSK и переподписать набор ключей, отправив DS нового ключа родителю (до появления нового DS зона остаётся уязвимой к подмене), либо удалить DS RR из родительской зоны, сделав дочернюю зону Insecure, а после истечения DS из кэшей удалить ключи и подписи, ввести новые и отправить новый DS родителю.
Размеры ключей и алгоритмы
RFC 6781 указывает три типа алгоритмов подписи для DNSSEC: RSA, DSA и GOST, при этом DSA ограничен максимальным размером ключа 1024 бита и примерно в десять раз медленнее проверяется, чем RSA. Рекомендуется использовать RSA/SHA-256 как предпочтительный алгоритм и RSA/SHA-1 как альтернативу,
Где смотреть в коде
- keymgr.c: keymgr_keyrole
- autotrust.c: probe_answer_cb
- autotrust.c: autr_process_prime
- keymgr.c: dns_kasp_getname
- val_anchor.c: LDNS_WIREPARSE_OFFSET