uCheckeruChecker
11 мин чтения

Ротация DKIM-ключей: зачем, когда и как

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


Зачем вообще менять DKIM-ключ

Короткий ответ: потому что ключи стареют. Длинный ответ состоит из трёх частей.

Криптографическое старение. Приватный ключ лежит на сервере месяцами или годами. За это время он может утечь при компрометации сервера, попасть в бэкап, который скопировали на флешку, или оказаться в логах деплоя. Чем дольше ключ живёт, тем выше вероятность, что кто-то его получит. А если приватный ключ скомпрометирован, злоумышленник может подписывать письма от имени вашего домена - и DMARC пропустит их как легитимные.

Рекомендации вендоров. Google в документации Postmaster Tools рекомендует ротировать DKIM-ключи минимум раз в год. M3AAWG (Messaging, Malware and Mobile Anti-Abuse Working Group) в своём best practices document советует каждые 6 месяцев. Некоторые крупные ESP - Mailgun, Postmark - ротируют ключи клиентов автоматически каждый квартал.

Переход на более длинные ключи. Если вы до сих пор используете 1024-битный RSA-ключ, ротация - удобный момент обновиться до 2048 бит. Google с 2023 года штрафует за короткие ключи. Кроме того, RFC 8463 добавил поддержку Ed25519 для DKIM - это алгоритм на эллиптических кривых, компактнее и быстрее RSA. Пока его поддерживают не все провайдеры, но тренд очевиден.

Когда пора менять ключ

Есть плановая ротация и экстренная. Плановая - раз в 6-12 месяцев, по расписанию. Экстренная - если произошла утечка или вы подозреваете компрометацию.

Признаки, что ключ нужно менять немедленно:

  • Сервер, где хранился приватный ключ, был скомпрометирован.
  • Вы обнаружили DKIM-подписанные письма, которые не отправляли.
  • Уволился администратор, имевший доступ к ключам, и вы не уверены, что он не сохранил копию.
  • Ключ - 1024 бит или менее, и вы видите предупреждения в DMARC-отчётах.

Для плановой ротации выберите день с минимальной нагрузкой на рассылки. Вторник-среда, первая половина дня. Не пятница, не выходные, не день перед распродажей.

Принцип: два селектора, ноль даунтайма

DKIM использует селекторы - произвольные строки, которые указывают принимающему серверу, какой публичный ключ брать из DNS. Селектор записывается в заголовке каждого подписанного письма (тег s=). Принимающий сервер достаёт ключ по адресу selector._domainkey.yourdomain.com.

Ротация строится на этом механизме. Схема:

  1. Генерируете новую пару ключей с новым селектором.
  2. Публикуете новый публичный ключ в DNS. Ждёте пропагации.
  3. Переключаете сервер на подпись новым ключом и новым селектором.
  4. Старую DNS-запись оставляете на 24-48 часов (письма в очередях ещё подписаны старым ключом).
  5. Удаляете старую DNS-запись. Уничтожаете старый приватный ключ.

Ключевой момент: старый и новый публичные ключи сосуществуют в DNS одновременно. Принимающий сервер всегда проверяет подпись по тому селектору, который указан в письме. Никакого конфликта, никакого даунтайма.

Шаг 1. Генерация нового ключа

RSA 2048 бит - текущий стандарт. Генерация через openssl:

# Генерация приватного ключа RSA 2048
openssl genrsa -out dkim_s2_private.pem 2048

# Извлечение публичного ключа
openssl rsa -in dkim_s2_private.pem -pubout -out dkim_s2_public.pem

# Публичный ключ одной строкой (для DNS-записи)
grep -v "^-" dkim_s2_public.pem | tr -d '\n'

Имя файла содержит s2 - это имя нового селектора. Если текущий селектор s1, новый будет s2. В следующий раз - s3 или снова s1 (к тому моменту старую запись вы уже удалили). Некоторые команды используют дату: dkim202604. Это удобнее - сразу видно, когда ключ создан.

Если хотите попробовать Ed25519 (RFC 8463):

# Ed25519 - компактный ключ, быстрая подпись
openssl genpkey -algorithm Ed25519 -out dkim_ed_private.pem
openssl pkey -in dkim_ed_private.pem -pubout -out dkim_ed_public.pem

Ed25519 даёт публичный ключ длиной 44 символа в base64 вместо 392 у RSA-2048. DNS-запись получается компактной, нет проблем с лимитом 255 символов на строку. Но проверяйте совместимость: Yahoo и Gmail поддерживают Ed25519, Mail.ru и некоторые корпоративные серверы на Exchange - пока нет. Безопасный подход - публиковать два ключа: RSA как основной, Ed25519 как дополнительный.

Шаг 2. Публикация в DNS

Добавьте TXT-запись для нового селектора. Старую пока не трогайте.

; Старый ключ (пока оставляем)
s1._domainkey.yourdomain.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjAN...старый_ключ..."

; Новый ключ
s2._domainkey.yourdomain.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjAN...новый_ключ..."

Проверка пропагации:

# Убедиться, что новая запись доступна
dig TXT s2._domainkey.yourdomain.com +short

# Убедиться, что старая ещё на месте
dig TXT s1._domainkey.yourdomain.com +short

Если используете Cloudflare - пропагация занимает минуты. Для других провайдеров - от 15 минут до нескольких часов в зависимости от TTL. Не переключайте сервер на новый ключ, пока dig не покажет новую запись. Иначе письма будут подписаны ключом, которого принимающий сервер ещё не видит, - и DKIM провалится.

Шаг 3. Переключение сервера

Как именно переключить - зависит от инфраструктуры.

Postfix + OpenDKIM. В конфиге OpenDKIM измените селектор и путь к ключу:

# /etc/opendkim.conf
Selector    s2
KeyFile     /etc/opendkim/keys/dkim_s2_private.pem
# Перезапуск
sudo systemctl restart opendkim
sudo systemctl restart postfix

Внешний ESP (Mailgun, SendGrid, Postmark). Большинство ESP управляют ключами через панель или API. В Mailgun это раздел «Sending → Domain settings → DKIM». В SendGrid - «Settings → Sender Authentication». Создаёте новый ключ, получаете DNS-запись, добавляете в свой DNS, верифицируете в панели ESP. Некоторые ESP ротируют ключи автоматически и предупреждают по email за неделю.

Проверка после переключения. Отправьте тестовое письмо на Gmail. Откройте «Показать оригинал». В заголовках должен быть новый селектор:

DKIM-Signature: v=1; a=rsa-sha256; d=yourdomain.com; s=s2;
    h=from:to:subject:date:message-id;
    bh=...;
    b=...
Authentication-Results: mx.google.com;
    dkim=pass header.i=@yourdomain.com header.s=s2

Видите s=s2 и dkim=pass? Ротация завершена.

Шаг 4. Удаление старого ключа

Не торопитесь. Письма, отправленные до переключения, могут лежать в retry-очередях принимающих серверов до 72 часов. Некоторые корпоративные серверы проверяют DKIM при повторной доставке. Если к тому моменту старый ключ удалён из DNS - подпись не пройдёт.

Безопасный интервал - 48-72 часа после переключения. После этого удалите TXT-запись для старого селектора из DNS. Приватный ключ - shred или аналог, не просто rm:

# Безвозвратное удаление старого приватного ключа
shred -u /etc/opendkim/keys/dkim_s1_private.pem

Автоматизация ротации

Ручная ротация раз в полгода - приемлемо. Но люди забывают. Забыл один раз - ключ живёт уже год. Забыл второй - два года. Автоматизация убирает человеческий фактор.

Минимальный скрипт для ротации (Postfix + OpenDKIM + Cloudflare DNS):

#!/bin/bash
# rotate-dkim.sh - вызывать по cron раз в 6 месяцев
DOMAIN="yourdomain.com"
NEW_SELECTOR="dkim$(date +%Y%m)"
KEY_DIR="/etc/opendkim/keys"

# 1. Генерация нового ключа
openssl genrsa -out "$KEY_DIR/${NEW_SELECTOR}_private.pem" 2048
openssl rsa -in "$KEY_DIR/${NEW_SELECTOR}_private.pem" \
  -pubout -out "$KEY_DIR/${NEW_SELECTOR}_public.pem"
chown opendkim:opendkim "$KEY_DIR/${NEW_SELECTOR}_private.pem"
chmod 600 "$KEY_DIR/${NEW_SELECTOR}_private.pem"

# 2. Публичный ключ для DNS
PUBKEY=$(grep -v "^-" "$KEY_DIR/${NEW_SELECTOR}_public.pem" | tr -d '\n')

# 3. Добавить DNS-запись через Cloudflare API
curl -s -X POST \
  "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data "{
    \"type\": \"TXT\",
    \"name\": \"${NEW_SELECTOR}._domainkey.${DOMAIN}\",
    \"content\": \"v=DKIM1; k=rsa; p=${PUBKEY}\",
    \"ttl\": 300
  }"

# 4. Подождать пропагации
sleep 120

# 5. Переключить OpenDKIM
sed -i "s/^Selector.*/Selector    ${NEW_SELECTOR}/" /etc/opendkim.conf
sed -i "s|^KeyFile.*|KeyFile     $KEY_DIR/${NEW_SELECTOR}_private.pem|" \
  /etc/opendkim.conf
systemctl restart opendkim
systemctl restart postfix

echo "DKIM rotated to selector: ${NEW_SELECTOR}"

Скрипт намеренно упрощён - в продакшене добавьте проверку dig перед переключением, алерты в Slack/Telegram при ошибках, логирование. Удаление старого ключа из DNS - отдельный скрипт, запускаемый через 72 часа.

Для CI/CD: храните приватные ключи в секретах (Vault, AWS Secrets Manager, GitHub Secrets - не в репозитории). Terraform и Pulumi умеют управлять DNS-записями, интегрируются с пайплайном, и ротация становится частью инфраструктурного кода.

Ошибки, которые ломают ротацию

  • Удалили старую DNS-запись до переключения сервера. Сервер подписывает селектором s1, а записи для s1 уже нет. Все письма проваливают DKIM. Если действует p=reject в DMARC - они отклоняются. Это самая частая ошибка при ручной ротации.
  • Переключили сервер до пропагации DNS. Новая запись ещё не видна принимающим серверам. DKIM тоже провалится. Особенно коварно с DNS-провайдерами, где TTL выставлен в 3600 секунд или выше.
  • Забыли про субдомены. Если маркетинговые рассылки идут с mail.yourdomain.com, а транзакционные - с notify.yourdomain.com, у каждого свой DKIM-ключ. Ротировать нужно все.
  • Один селектор для нескольких доменов. Если у вас три домена и все подписываются ключом с селектором s1, при ротации нужно обновить DNS всех трёх доменов одновременно. Лучше использовать разные селекторы для разных доменов.
  • Не уничтожили старый приватный ключ. Ротация без уничтожения - полумера. Компрометация старого ключа не поможет подписывать новые письма, но если злоумышленник перехватит письмо в транзите, он сможет подделать подпись задним числом.

Мониторинг после ротации

Первые 24 часа после переключения - критические. Следите за:

  • DMARC-отчётами. Если настроен rua=, агрегированные отчёты покажут, проходят ли письма DKIM с новым селектором. Парсеры (dmarcian, Postmark DMARC, DMARC Analyzer) визуализируют это.
  • Bounce rate. Резкий рост hard bounce после ротации - сигнал, что что-то пошло не так.
  • Логами сервера. OpenDKIM пишет в syslog. Ищите строки с DKIM-Signature и проверяйте, что подпись создаётся без ошибок.
# Проверить логи OpenDKIM за последний час
journalctl -u opendkim --since "1 hour ago" | grep -i "error\|fail"

Чеклист ротации

Для тех, кто любит списки:

  1. Сгенерировать новую пару ключей (RSA-2048 или Ed25519).
  2. Выбрать новый селектор (s2, dkim202604).
  3. Опубликовать новый публичный ключ в DNS.
  4. Проверить dig TXT newSelector._domainkey.yourdomain.com.
  5. Переключить сервер / ESP на новый селектор и ключ.
  6. Отправить тестовое письмо. Проверить заголовки: dkim=pass.
  7. Подождать 48-72 часа.
  8. Удалить старую DNS-запись.
  9. Уничтожить старый приватный ключ (shred -u).
  10. Записать дату ротации. Поставить напоминание на следующую (через 6 месяцев).

Как ротация влияет на доставляемость

Прямого влияния на inbox placement нет. Почтовые провайдеры не дают бонусов за частую ротацию. Но влияние косвенное и существенное.

Скомпрометированный ключ - это фишинговые письма с вашей подписью. Получатели нажимают «спам». Репутация домена падает. Доставляемость легитимных писем снижается. Восстановление репутации после такого инцидента занимает недели, иногда месяцы. Ротация - это профилактика. Дешевле менять замок раз в полгода, чем разбираться с последствиями взлома.

Но DKIM - только один слой защиты. Подпись подтверждает подлинность, но не гарантирует качество. Подписанное письмо, отправленное на несуществующий адрес, - всё равно bounce. Подписанное письмо в спам-ловушку - всё равно удар по репутации. Аутентификация и гигиена базы работают в связке.

Ключи ротируются, база стареет

Вы настроили DKIM, ротируете ключи, DMARC на reject. Техническая часть в порядке. Осталось убедиться, что адреса, на которые вы отправляете, ещё живы. За год база теряет до 25% валидных адресов. Проверьте свою.

Загрузите список в uChecker - увидите невалидные адреса, спам-ловушки и рискованные контакты за минуты. 30 бесплатных проверок для старта.

DKIM ротациясмена DKIM ключабезопасность emailкриптографияротация ключейemail аутентификацияDNS записи