MCMail by MYCLOUD

DKIM: цифровая подпись писем, селекторы и ротация ключей

DKIM (DomainKeys Identified Mail) добавляет к каждому исходящему письму криптографическую подпись. По ней сервер получателя проверяет, что письмо действительно отправлено с разрешения вашего домена и не было изменено в пути. Расскажем, как устроены подпись и ключи, как проверить DKIM и как безопасно менять ключи.

Как работает DKIM

DKIM использует пару ключей: закрытый и открытый.

  1. Закрытый ключ хранится на почтовом сервере отправителя. Сервер вычисляет подпись по телу письма и выбранным заголовкам и добавляет заголовок DKIM-Signature.
  2. Открытый ключ публикуется в DNS домена в виде TXT-записи.
  3. Сервер получателя читает из подписи домен и селектор, запрашивает открытый ключ в DNS и проверяет подпись.

Если письмо изменили по дороге (поменяли тему, тело или подписанный заголовок), подпись не сойдётся и результат будет dkim=fail. В отличие от SPF, DKIM не зависит от IP-адреса отправляющего сервера, поэтому обычно переживает пересылку.

Селекторы и DNS-запись

Селектор — это произвольное имя, которое позволяет держать у одного домена несколько ключей одновременно: например, отдельный ключ для корпоративной почты и отдельный для сервиса рассылок. Открытый ключ публикуется по адресу <селектор>._domainkey.<домен>:

mail2026._domainkey.example.uz.  3600  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
ТегЗначение
v=DKIM1Версия, рекомендуется указывать первой
k=rsaТип ключа; RSA используется по умолчанию
p=Открытый ключ в base64; пустое значение означает, что ключ отозван
t=yНеобязательный флаг тестового режима

Имя селектора выбирается свободно. Удобно включать в него дату или порядковый номер (mail2026, s202610), чтобы при ротации было понятно, какой ключ новее.

Некоторые сервисы рассылок просят вместо TXT создать CNAME-запись: s1._domainkey.example.uz указывает на имя у сервиса, а ключом управляет сам сервис. Это нормальная практика.

Длина ключа: 2048 бит

Ключи RSA длиной 1024 бита считаются минимально допустимыми и постепенно выходят из употребления. Сегодня стандартный выбор — 2048 бит. Ключи 4096 бит не дают заметной практической выгоды, хуже помещаются в DNS и поддерживаются не всеми получателями.

Открытый ключ 2048 бит в base64 занимает около 400 символов, а одна строка в TXT-записи ограничена 255 символами. Поэтому ключ разбивают на несколько строк в кавычках внутри одной записи:

mail2026._domainkey.example.uz. IN TXT ( "v=DKIM1; k=rsa; "
    "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...первая часть..."
    "...вторая часть ключа...IDAQAB" )

Большинство веб-панелей DNS делают разбиение сами, если вставить ключ целиком. Если панель обрезает длинное значение, проверьте результат через dig — ключ должен прийти полностью.

Как проверить DKIM

Запись в DNS

dig TXT mail2026._domainkey.example.uz +short

В Windows: nslookup -type=txt mail2026._domainkey.example.uz. В ответе должна быть строка с v=DKIM1 и ключом в p=.

Заголовки письма

Отправьте письмо на внешний ящик и откройте исходный текст письма (в веб-интерфейсах это обычно «Показать оригинал» или «Исходный код письма»). Найдите подпись:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.uz;
    s=mail2026; t=1760000000; h=from:to:subject:date:message-id;
    bh=...; b=...
  • d= — домен, от имени которого поставлена подпись. Для DMARC важно, чтобы он совпадал с доменом в поле From.
  • s= — селектор, по которому ищется ключ.
  • h= — список подписанных заголовков; from подписывается обязательно.
  • c= — режим канонизации; relaxed/relaxed терпимее к мелким изменениям пробелов и регистра заголовков.
  • bh= и b= — хеш тела и сама подпись.

Результат проверки сервер получателя записывает в заголовок:

Authentication-Results: mx.recipient.example;
    dkim=pass header.d=example.uz header.s=mail2026

Почему DKIM не проходит

РезультатВероятная причина
dkim=noneПисьмо не подписано: подпись для домена не включена на сервере
dkim=permerror или «no key»Нет записи с таким селектором, опечатка в имени, ключ обрезан
dkim=fail, «body hash did not verify»Тело письма изменено после подписи: дисклеймер на шлюзе, антивирус, список рассылки
dkim=fail, «signature verification failed»Ключ в DNS не соответствует закрытому ключу на сервере

Не используйте тег l= (длина подписанного тела), даже если какая-то инструкция его предлагает. Он позволяет злоумышленнику дописать к подписанному письму свой текст без нарушения подписи.

Ротация ключей

Ключи DKIM полезно периодически менять — например, раз в 6–12 месяцев, а также сразу при подозрении на утечку закрытого ключа. Благодаря селекторам это делается без перерыва в работе:

  1. Сгенерируйте новую пару ключей и опубликуйте открытый ключ под новым селектором (mail2027), не трогая старый.
  2. Дождитесь, пока запись станет видна в DNS (с учётом TTL).
  3. Переключите подпись на сервере на новый селектор и проверьте заголовки тестового письма.
  4. Оставьте старый ключ в DNS ещё на несколько дней: письма, задержавшиеся в очередях, должны успешно проверяться.
  5. Удалите старую запись или опубликуйте её с пустым p=, что явно означает отзыв ключа.

В MCMail ключи DKIM для вашего домена генерируем и подключаем мы, а запись с открытым ключом присылаем при подключении домена. DKIM работает в связке с SPF и DMARC — только все три вместе дают получателям уверенность в ваших письмах.