Ротація ключів DKIM: як безпечно провести зміну без жодної драми

Було корисно?

У момент, коли DKIM ламається, ніхто не каже «цікаво». Люди запитують «чому рахунки йдуть у спам», «чому скидання паролів не доходять» та «чому лист CEO виглядає як фішинг». Ротація ключів DKIM — це одна з тих операцій, під час яких нічого помітного не має трапитися — але якщо допустити халтуру, все піде не так.

Це інструкція production-рівня для ротації ключів DKIM із спокійними, вимірними кроками. Ви будете подвійно підписувати, правильно виставите DNS на етапності, перевірите командами, яким можна довіряти, і переключитесь лише коли докази покажуть, що це безпечно. Якщо вам подобається драма — ідіть у театр. Якщо ви керуєте поштовими системами — майте план відкату і запасний селектор.

Що насправді означає ротація DKIM (а що ні)

Ротація DKIM — це дія з заміни криптографічного ключа, який підписує вихідну пошту. Насправді це означає:

  • Ви генеруєте новий приватний ключ на підписувачі (MTA або вихідний ретранслей).
  • Ви публікуєте відповідний публічний ключ у DNS під певним селектором.
  • Ви переключаєте підписування на новий селектор (або підписуєте обома під час переходу).
  • Ви зберігаєте старий публічний ключ доступним досить довго, щоб верифікатори могли перевіряти старі повідомлення.

Чого це не означає: вправляння в покращенні доставляння. Ротація сама по собі не робить вас більш надійними; вона зменшує ризики від компрометації ключа та операційного дрейфу. Якщо ваша пошта вже провалює SPF/DMARC вирівнювання, ротація DKIM вас не врятує. Вона може, втім, виявити, що ви жили за рахунок щасливого випадку.

Чому ротація викликає драму

Три причини:

  1. DNS — це розподілена система кешування з власною поведінкою. Ви не «змінюєте DNS», ви домовляєтесь з резолверами, якими не керуєте.
  2. Пошта асинхронна. Повідомлення можуть затримуватись, повторюватись, ставитись у чергу або доставлятись через години — і все ще потребувати старого ключа для валідації.
  3. Люди плутають домени. Видимий домен у From, домен в d= у DKIM та SMTP envelope-дім — пов’язані, але не ідентичні. Плутанина перетворює «прості» зміни на крос-командні інцидентні виклики.

Оперована порада наперед: якщо можете — робіть ротацію з подвійним підписом. Якщо не можете — все одно можна прокрутити безпечно, але треба бути уважнішим із таймінгом і зберіганням старих ключів у DNS. І ще: ніколи не робіть ротацію під час великого запуску. Ваше майбутнє «я» відправить вам листа з папки спаму.

Цікавинки та трохи історії

  • DKIM виник із злиття двох проектів. DomainKeys (Yahoo) та Identified Internet Mail (Cisco) об’єдналися в DKIM, стандартизований як RFC 4871 у 2007 році.
  • DKIM не шифрує пошту. Він підписує вибрані заголовки та тіло (або частину тіла), щоб виявити підтасовку, а не приховувати вміст.
  • Селектор — це примітив версіонування. DKIM побудований з розрахунком на ротацію: селектори існують, щоб ви могли публікувати кілька ключів одночасно.
  • Перші розгортання DKIM використовували лише RSA. RSA став домінантним; пізніше з’явився Ed25519 у новіших специфікаціях та реалізаціях, але прийняття неоднорідне.
  • 2048-бітні ключі стали «серйозним» стандартом. 1024-бітні RSA ще зустрічаються, але деякі отримувачі вважають їх слабкими або порушенням політики.
  • Валідація DKIM відбувається під час прийому. Отже, отримувачі потребують доступу до DNS вашого публічного ключа саме тоді, коли оцінюють повідомлення — не тоді, коли ви його відправляли.
  • DKIM частіше витримує пересилання краще за SPF. SPF перевіряє шлях; DKIM — вміст. Форвардери руйнують SPF регулярно; DKIM часто витримує, якщо форвардер не перезаписує підписані частини.
  • DMARC зробив DKIM операційно обов’язковим. Коли DMARC почав жорстко застосовуватись, DKIM перестав бути «приємним доповненням» і став «не викликайте мене по нічній зміні».

Ментальна модель: селектори, ключі, DNS і час

Уявляйте DKIM як чотири рухомі частини:

  • Підписувач: система, що тримає приватний ключ і додає заголовок DKIM-Signature (Postfix + OpenDKIM, хмарний ретранслей або ESP).
  • Селектор: рядок на кшталт s2026q1, який вказує, який ключ брати з DNS.
  • DNS-запис: TXT-запис на <selector>._domainkey.<domain>, що містить публічний ключ і метадані.
  • Отримувач: Gmail, Outlook та всі інші, хто робить DNS-запити й валідовує підписи під час прийому повідомлення.

Час — прихована залежність

Система має два окремі «годинники»:

  1. Поширення і кешування DNS: TTL плюс поведінка резолверів.
  2. Затримки доставки пошти: черги, повтори, graylisting, перевантаження та «той старий пристрій», що спробує ще завтра.

Ротація провалюється, коли ви видаляєте старий ключ з DNS раніше, ніж світ закінчив валідувати листи, підписані ним. Вона також провалюється, коли ви переключаєте підписувачі до того, як новий ключ стане видимим для отримувачів. Відповідь нудна: перекриття.

Цитата, бо підходить

Надія — це не стратегія. — приписується різним лідерам інженерії; часто використовується в операціях і надійності.

Жарт 1: Кешування DNS — як блискітки: здається, що ви прибрали, а потім воно з’являється в автомобілі через три тижні.

Підготовка: інвентаризація і контроль зони ураження

Перед тим як торкатися ключів, дайте відповіді на три питання з доказами:

  1. Хто підписує сьогодні? Можливо це ваші MTA. Можливо це ваш ESP. Можливо обидва (маркетинг проти транзакційних). «Обидва» поширене і не обов’язково погано — допоки ви не прокрутите один і забудете інший.
  2. Які домени та субдомени задіяні? example.com, mail.example.com, news.example.com та кастомні return-path домени можуть співіснувати. Кожен може мати окремі селектори та політики.
  3. Яка політика залежить від проходження DKIM? Жорсткі налаштування DMARC (quarantine/reject) перетворюють дрібну помилку DKIM у повний стоп.

Виберіть схему найменування селекторів, яка не старіє погано

Селектори — просто рядки. Це і сила, і хаос. Оберіть щось, що залишатиметься зрозумілим через роки і команди:

  • Добре: s2026q1, mta1-2026-01, rotate-01
  • Погано: default, dkim, test, new (бо «new» стає «old» ще до закриття тикета)

Визначте тривалість перекриття

Моя практична рекомендація:

  • Тримайте старий селектор опублікованим щонайменше 7 днів після cutover для більшості організацій.
  • Тримайте 30 днів, якщо у вас довгі поштові черги, регульовані системи або періодичні «ми відправляємо щотижневі виписки» процеси.

Отримувачі можуть валідувати старі повідомлення пізніше (затримана доставка, повторна обробка або перенос скриньки). Немає нагороди за швидке видалення старих DNS ключів. Нагорода — не отримувати виклики на ніч.

Практичні завдання з командами, виводами та рішеннями

Суть команд — не зайнятість. Це перетворення «я думаю» на «я знаю». Ці завдання написані для типової Linux-середовища з Postfix + OpenDKIM та загальної DNS-верифікації. Підлаштуйте шляхи й імена сервісів, якщо у вас інший підписувач, але зберігайте дисципліну: спостерігай, змінюй, знову спостерігай.

Завдання 1: Підтвердити, який селектор наразі підписує

Надішліть собі лист із вашої системи і перегляньте заголовки в поштовій скриньці. На Linux-поштовому сервері також можна шукати DKIM-Signature у логах, якщо ви логируєте результати milter.

cr0x@server:~$ sudo grep -R "DKIM-Signature" -n /var/log/mail.log | tail -n 3
Jan 04 09:12:11 mta1 postfix/cleanup[23111]: 4A2B9123: message-id=<...>
Jan 04 09:12:11 mta1 opendkim[1122]: 4A2B9123: DKIM-Signature field added (s=selector2025, d=example.com)
Jan 04 09:12:12 mta1 postfix/qmgr[977]: 4A2B9123: from=<noreply@example.com>, size=..., nrcpt=1 (queue active)

Що це означає: Наразі ви підписуєте селектором selector2025 для d=example.com.

Рішення: Це ваш «старий» селектор. Ви повинні зберегти його DNS-запис під час і після ротації.

Завдання 2: Перелічити всі DKIM DNS-записи, які ви зараз публікуєте

cr0x@server:~$ dig +short TXT selector2025._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkq...IDAQAB"

Що це означає: Цей селектор існує і публікує публічний ключ.

Рішення: Якщо dig нічого не повертає — зупиніться. Ви підписуєте селектором, який не опублікований, і ротація тоді не найгостріша проблема.

Завдання 3: Перевірити фактичний TTL і чи можна його безпечно знизити

cr0x@server:~$ dig TXT selector2025._domainkey.example.com +noall +answer
selector2025._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq...IDAQAB"

Що це означає: TTL — 3600 секунд (1 година).

Рішення: Якщо TTL велетенський (наприклад 86400), знизьте його за день до cutover, щоб кеші швидше звільнились. Якщо ви не можете змінити TTL (керований DNS з обмеженнями), плануйте довший період перекриття і за можливості робіть подвійний підпис.

Завдання 4: Згенерувати нову пару ключів DKIM (приклад OpenDKIM)

cr0x@server:~$ sudo mkdir -p /etc/opendkim/keys/example.com/selector2026
cr0x@server:~$ sudo opendkim-genkey -b 2048 -D /etc/opendkim/keys/example.com/selector2026 -d example.com -s selector2026
cr0x@server:~$ sudo ls -l /etc/opendkim/keys/example.com/selector2026
total 8
-rw------- 1 root root 1704 Jan  4 10:02 selector2026.private
-rw-r--r-- 1 root root  451 Jan  4 10:02 selector2026.txt

Що це означає: У вас є приватний ключ і TXT-шаблон для DNS.

Рішення: Використовуйте 2048-бітний RSA, якщо немає сильної причини інакше. Якщо ваша платформа підтримує Ed25519 і отримувачі сумісні, можна розглядати, — але не робіть експеримент сумісності під час ротації.

Завдання 5: Перевірити права доступу до файлів ключів (приватні ключі — не спільний проєкт)

cr0x@server:~$ sudo stat -c "%n %a %U:%G" /etc/opendkim/keys/example.com/selector2026/selector2026.private
/etc/opendkim/keys/example.com/selector2026/selector2026.private 600 root:root

Що це означає: Файл читається лише root.

Рішення: Переконайтесь, що користувач OpenDKIM може його читати (часто через власність або групу). Неправильні права викликають мовчазні збої «припинення підписування».

Завдання 6: Налаштувати OpenDKIM, щоб він знав про новий ключ (KeyTable/SigningTable)

cr0x@server:~$ sudo grep -n "example.com" /etc/opendkim/KeyTable /etc/opendkim/SigningTable
/etc/opendkim/KeyTable:12:selector2025._domainkey.example.com example.com:selector2025:/etc/opendkim/keys/example.com/selector2025/selector2025.private
/etc/opendkim/SigningTable:9:*@example.com selector2025._domainkey.example.com

Що це означає: Усе вказує на selector2025.

Рішення: Додайте рядки для нового селектора. Якщо ви плануєте подвійний підпис, підхід залежить від вашого софту (деякі підтримують кілька підписів; інші — ні). Якщо подвійного підпису немає, зробіть cutover, але тримайте старий DNS опублікованим.

Завдання 7: Додати новий селектор у KeyTable

cr0x@server:~$ sudo bash -lc 'echo "selector2026._domainkey.example.com example.com:selector2026:/etc/opendkim/keys/example.com/selector2026/selector2026.private" >> /etc/opendkim/KeyTable'
cr0x@server:~$ sudo tail -n 2 /etc/opendkim/KeyTable
selector2025._domainkey.example.com example.com:selector2025:/etc/opendkim/keys/example.com/selector2025/selector2025.private
selector2026._domainkey.example.com example.com:selector2026:/etc/opendkim/keys/example.com/selector2026/selector2026.private

Що це означає: OpenDKIM тепер знає, де лежить новий приватний ключ.

Рішення: Якщо ви використовуєте KeyTable на базі БД або інший підписувач — зробіть еквівалентний крок: зареєструйте селектор і шлях до ключа.

Завдання 8: Переключити SigningTable на новий селектор (приклад cutover без подвійного підпису)

cr0x@server:~$ sudo sed -i 's/\*@example.com selector2025\._domainkey\.example\.com/*@example.com selector2026._domainkey.example.com/' /etc/opendkim/SigningTable
cr0x@server:~$ sudo grep -n "\*@example.com" /etc/opendkim/SigningTable
9:*@example.com selector2026._domainkey.example.com

Що це означає: Нова пошта буде підписуватись селектором selector2026 після перезавантаження OpenDKIM.

Рішення: Не перезавантажуйте сервіс, поки DNS не опубліковано. Підписування селектором, який ніхто не може знайти — це DKIM=fail у отримувачів.

Завдання 9: Витягнути значення TXT, яке потрібно опублікувати в DNS

cr0x@server:~$ sudo cat /etc/opendkim/keys/example.com/selector2026/selector2026.txt
selector2026._domainkey IN TXT ( "v=DKIM1; k=rsa; "
  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp....IDAQAB" )  ; ----- DKIM key selector2026 for example.com

Що це означає: Значення після p= — це те, що використовуватимуть отримувачі.

Рішення: Публікуйте його точно. Ніяких зайвих лапок у DNS UI, ніяких перенесень рядків у середині ключа, жодних пропущених крапок з комою. DNS-інструменти різні; перевірте після публікації.

Завдання 10: Опублікувати новий DKIM-запис, а потім перевірити з кількох резолверів

cr0x@server:~$ dig +noall +answer TXT selector2026._domainkey.example.com
selector2026._domainkey.example.com. 300 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp....IDAQAB"

Що це означає: Запис існує, TTL — 300 секунд (5 хвилин).

Рішення: Якщо TTL не той, що ви планували — виправте зараз, поки ніхто не залежить від нього. Також опитайте відомий публічний резолвер, щоб зменшити ризик «мій корпоративний DNS мені бреше».

cr0x@server:~$ dig @1.1.1.1 +short TXT selector2026._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp....IDAQAB"

Що це означає: Публічний резолвер бачить запис.

Рішення: Не робіть cutover, поки принаймні два незалежні резолвери не повертають новий ключ послідовно.

Завдання 11: Чисто перезавантажити OpenDKIM і підтвердити, що помилок немає

cr0x@server:~$ sudo systemctl reload opendkim
cr0x@server:~$ sudo systemctl status opendkim --no-pager -l
● opendkim.service - OpenDKIM Milter
     Loaded: loaded (/lib/systemd/system/opendkim.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2026-01-04 09:00:03 UTC; 1h 8min ago
       Docs: man:opendkim(8)
   Main PID: 1122 (opendkim)
     Status: "Running"

Що це означає: Сервіс запущено. Це необхідна, але не достатня умова.

Рішення: Негайно перевірте логи на помилки завантаження ключа; OpenDKIM може працювати, але не підписувати.

Завдання 12: Підтвердити, що OpenDKIM використовує новий селектор у логах

cr0x@server:~$ sudo tail -n 20 /var/log/mail.log | grep -E "opendkim|DKIM-Signature" | tail -n 5
Jan 04 10:12:07 mta1 opendkim[1122]: 6C9FD123: DKIM-Signature field added (s=selector2026, d=example.com)
Jan 04 10:12:07 mta1 postfix/qmgr[977]: 6C9FD123: from=<noreply@example.com>, size=..., nrcpt=1 (queue active)

Що це означає: Пошта тепер підписується селектором selector2026.

Рішення: Перейдіть до зовнішньої верифікації (заголовки Gmail або тестова скринька) перед тим, як оголосити перемогу.

Завдання 13: Перевірити, що DKIM проходить у отриманому повідомленні (перегляд заголовків)

У Gmail або Outlook перегляньте оригінал листа. Шукайте результати автентифікації.

cr0x@server:~$ python3 - <<'PY'
import re,sys
msg=open('/tmp/raw.eml','r',errors='ignore').read()
m=re.search(r'Authentication-Results:.*', msg, re.I)
print(m.group(0) if m else "no Authentication-Results header found")
PY
Authentication-Results: mx.google.com; dkim=pass header.i=@example.com header.s=selector2026 header.b=AbCdEf...

Що це означає: DKIM проходить і селектор правильний.

Рішення: Якщо DKIM=fail — зупиніться і відлагодьте, перш ніж виводити з експлуатації старий ключ.

Завдання 14: Слідкувати за подальшим використанням старого селектора (щоб знати, коли його безпечно вивести)

cr0x@server:~$ sudo grep -R "s=selector2025" -n /var/log/mail.log | tail -n 5
Jan 03 23:48:51 mta1 opendkim[1122]: 1F0A9123: DKIM-Signature field added (s=selector2025, d=example.com)

Що це означає: Останній спостережуваний лист, підписаний старим селектором, був вчора.

Рішення: Якщо це все ще з’являється після cutover, у вас є інший підписувач, другий MTA або часткова розгортка. Не видаляйте старий DNS, поки не переконаєтесь, що всі підписувачі переключені.

Завдання 15: Переконатися, що DMARC-альянс не постраждає від ротації

cr0x@server:~$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; rua=mailto:dmarc-agg@example.com; adkim=s; aspf=s"

Що це означає: DMARC у режимі жорсткого вирівнювання (adkim=s). Це означає, що d= у DKIM має точно збігатись із доменом у From.

Рішення: Переконайтесь, що ваш підписувач використовує d=example.com (не піддомен), якщо From — @example.com. Ротація — чудовий час ненавмисно змінити d= і спричинити невдачі DMARC.

Завдання 16: Виявити пошкоджене форматування DNS (лапки, крапки з комою та розбиті рядки)

cr0x@server:~$ dig +short TXT selector2026._domainkey.example.com | tr -d '"' | grep -E "v=DKIM1;|p="
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp....IDAQAB

Що це означає: Ви бачите v=DKIM1 і p= чисто в поверненому TXT.

Рішення: Якщо у виводі є зайві дужки, розірвані фрагменти або відсутній p=, виправте DNS. Деякі консолі автоматично обгортають довгі TXT-записи неправильно, якщо вставляти з пробілами.

Жарт 2: Ротація ключів DKIM без моніторингу — як міняти парашути в повітрі, бо етикетка здалася старою.

Чеклісти / покроковий план (ротація без драми)

План A: Краща практика (подвійне підписування селекторів)

Якщо ваш стек підписування підтримує додавання двох заголовків DKIM-Signature (старий і новий селектори), робіть це. Це дає потрібний рівень «ледачої надійності»: отримувачі можуть перевіряти будь-який ключ, поки кеші та запізнення не наздоженуть.

  1. Оберіть новий селектор із зрозумілою схемою іменування (наприклад, s2026q1).
  2. Знизьте TTL для поточних DKIM-записів за 24 години до зміни (наприклад до 300 секунд), якщо ваш процес DNS це дозволяє.
  3. Згенеруйте нову пару ключів на підписувачі, збережіть приватний ключ безпечно, виставте права і зареєструйте в конфігу підписувача.
  4. Опублікуйте новий публічний ключ у DNS під новим селектором. Перевірте через кілька резолверів.
  5. Увімкніть подвійне підписування: підписуйте кожне повідомлення обома селекторами принаймні 48 годин (часто довше в великих організаціях).
  6. Вимірюйте: переконайтесь, що отримувачі послідовно повідомляють DKIM=pass з новим селектором.
  7. Припиніть підписування старим селектором, коли будете впевнені, але тримайте його DNS-запис опублікованим.
  8. Виведіть старий DNS-ключ тільки після періоду перекриття і після доказів, що жодна система ним більше не користується.

План B: Cutover без подвійного підписування (все ще безпечно, але менше відпускає помилки)

  1. Оберіть селектор і згенеруйте ключі.
  2. Опублікуйте новий селектор у DNS спочатку. Перевірте зовні вашої мережі.
  3. Почекайте принаймні одне вікно TTL (і реалістично — більше), щоб кеші підхопили зміни.
  4. Переключіть підписування на новий селектор і перезавантажте підписувач.
  5. Перевірте проходження DKIM через реальні заголовки поштових скриньок (Gmail/Outlook) і логи.
  6. Тримайте старий селектор у DNS протягом періоду перекриття.

План відкату (напишіть його раніше ніж він знадобиться)

Відкати мають бути нудними. Якщо ви імпровізуєте — ви вже втрачаєте час.

  • Тригер відкату: різкий сплеск помилок DKIM; з’являються DMARC-фейли; запити ключа повертають NXDOMAIN періодично; великі отримувачі показують «bad signature».
  • Дії при відкаті: переключіть SigningTable назад на старий селектор і перезавантажте підписувач; тримайте обидва DNS-записи опублікованими.
  • Перевірка відкату: підтвердіть, що логи показують підписування старим селектором; підтвердіть DKIM=pass у зовнішній скриньці.

Важливо: відкат можливий тільки якщо ви не видалили старий DNS-запис (і зберегли приватний ключ доступним). Вас здивує, як часто люди «прибирають» зарані.

Правила вікна змін (моя тверда думка)

  • Робіть це в середині тижня у години, коли є люди на місці. Ротації у п’ятницю — це хобі, не практика.
  • Не поєднуйте це з іншими змінами. Ротація ключів плюс зміни маршрутизації вихідної пошти — шлях у пекло «декілька правдоподібних причин».
  • Повідомте зацікавлені сторони, які володіють потоками відправників. Маркетингові платформи, CRM, системи заявок і внутрішні додатки. Ви змінюєте їхню репутаційну складову; вони заслуговують на сповіщення.

Швидкий план діагностики

Коли доставлення падає після ротації, потрібен швидкий, впорядкований шлях. Не мозковий штурм.

Перше: визначте, чи DKIM ламається через DNS чи підписування

  1. Перевірте одне реальне отримане повідомлення (Gmail/Outlook заголовки): знайдіть Authentication-Results і дивіться, чи там dkim=pass або dkim=fail, а також який селектор у header.s.
  2. Якщо воно падає — запитайте DNS для цього селектора з публічного резолвера і з вашого сервера. Якщо DNS нічого не повертає або відповіді різні — проблема в поширенні/кешуванні.
  3. Якщо DNS виглядає нормально — перегляньте логи підписувача на предмет «key not found», «permission denied» або «no signature added». Це ваша підписувальна траса.

Друге: перевірити вплив на DMARC вирівнювання

  1. Підтвердьте, що d= у DKIM збігається з видимим доменом From, особливо якщо DMARC у режимі строгого вирівнювання (adkim=s).
  2. Переконайтесь, що жоден новий вихідний шлях не переписує From або не додає іншу DKIM-підпис, яка плутає отримувачів.

Третє: ідентифікувати частковий cutover і плутанину з мульти-підписувачами

  1. Пошукайте у логах обидва селектори. Якщо обидва все ще з’являються через кілька днів — у вас більше одного підписувача.
  2. Перевірте маркетингові ESP або хмарні ретранслей, які підписують від вашого імені. Вони можуть мати власну конфігурацію DKIM і селектори.
  3. Шукайте повідомлення з кількома заголовками DKIM-Signature і дивіться, які з них проходять/падають. Невдала підпис може бути допустимою, якщо інша проходить, але правила DMARC важливі.

Боттлнек, якого ви шукаєте

Більшість інцидентів під час ротації DKIM — це або:

  • Відсутній або пошкоджений DNS-запис для нового селектора.
  • Неправильно налаштований підписувач (все ще підписує старим селектором, неправильний домен, хибний шлях до ключа, права).
  • Непомічений підписувач (одиниця бізнесу, яка не отримала повідомлення).

Типові помилки: симптом → корінь → виправлення

1) Симптом: DKIM раптово падає для всієї пошти після cutover

Корінь: Ви переключили підписування на новий селектор раніше, ніж опублікували новий DNS-запис (або раніше, ніж кеші побачили зміни).

Виправлення: Опублікуйте запис, перевірте через публічні резолвери, потім або дочекайтесь закінчення TTL, або відкатіть підписування на старий селектор, поки DNS не стане видимим.

2) Симптом: DKIM іноді проходить, іноді падає

Корінь: Розділення DNS (multiple authoritative answers під час поширення) або деякі отримувачі потрапляють на кеш з NXDOMAIN.

Виправлення: Переконайтесь, що провайдер DNS віддає один консистентний запис; підтвердіть, що всі авторитетні NS віддають однаковий контент; подовжте перекриття; не видаляйте старий ключ надто рано.

3) Симптом: заголовок DKIM відсутній зовсім

Корінь: Milter не запущений, Postfix не підключений до нього, або OpenDKIM не може прочитати приватний ключ через права/SELinux.

Виправлення: Перевірте статус сервісів і логи; валідуйте Postfix smtpd_milters; виправте власника ключа і контексти SELinux, якщо потрібно.

4) Симптом: DKIM показує «bad signature», хоча DNS правильний

Корінь: Щось модифікує повідомлення після підписування (вставка футера, обгортання рядків, фільтри вмісту) або невідповідність канонізації.

Виправлення: Переконайтесь, що підписування відбувається якомога пізніше в пайплайні; уникайте модифікацій після підпису; перевірте налаштування канонізації.

5) Симптом: DKIM проходить, але DMARC падає

Корінь: d= у DKIM не вирівнюється з доменом From (особливо при строгому вирівнюванні).

Виправлення: Підписуйте від домену From або свідомо змінюйте політику DMARC. Не «виправляйте» це ослабленням DMARC, якщо не готові прийняти безпекові наслідки.

6) Симптом: Деякі відправники все ще використовують старий селектор через тижні

Корінь: Другий вихідний стрім (ESP, SaaS, регіональний MTA) не оновлено.

Виправлення: Зробіть інвентаризацію всіх джерел відправки; шукайте у DMARC aggregate звітах (якщо вони є) і в логах; оновіть кожен підписувач; тримайте старий ключ у DNS до останньої міграції.

7) Симптом: Отримувачі повідомляють «key too short» або вважають пошту підозрілою

Корінь: Ви згенерували 1024-бітний RSA ключ (або отримувач має політику, що відкидає такі ключі).

Виправлення: Перейдіть на 2048-бітний RSA; перепублікуйте; зробіть cutover знову. Якщо ви вже робите ротацію — не додавайте слабкий ключ заради швидкості.

8) Симптом: DNS TXT-запис виглядає обрізаним

Корінь: Копіпаст або DNS UI розбив і вставив пробіли чи втратив фрагменти; деякі провайдери вимагають спеціальних правил для багаторядкових рядків.

Виправлення: Переведіть запис у коректний багаторядковий формат провайдера; підтвердьте, що повернутий p= є суцільним при отриманні.

Три корпоративні міні-історії з фронту

Міні-історія 1: Інцидент через неправильне припущення

Вони прокрутили DKIM у четвер вранці. Тикет був акуратний: новий ключ, новий селектор, оновити підписувач. Інженер зробив очевидну перевірку: dig з його ноутбука показував новий TXT-запис. Вони переключили підписування. Все виглядало добре п’ять хвилин.

Потім почали надходити скріни від підтримки: «Ваш лист заблоковано». Транзакційна пошта до великого поштового провайдера почала потрапляти в спам або провалювати DMARC. На чергового спрацювало, що DKIM падав у цього провайдера, але в невеликій тестовій скриньці проходив. Заплутано. Така халепа їсть годину.

Неправильне припущення було простим: «Якщо мій резолвер бачить — то й усі бачать». Їхній корпоративний DNS був налаштований форвардити запити до швидкого резолвера, який уже підхопив новий запис. Великий поштовий провайдер тим часом потрапляв на інший шлях кешування і часом бачив NXDOMAIN для нового селектора. Це не була містична «повільна пропагація»; це була нормальна розподілена поведінка кешів, посилена добою TTL, який був 24 години до вчорашнього дня.

Виправлення не було героїчним. Вони відкатили підписування на старий селектор, залишили новий опублікованим, почекали повний день, потім знову зробили cutover. Урок: перевірка має включати публічні резолвери й авторитетні перевірки, а не лише «той DNS, який мій ноутбук використовує сьогодні».

Міні-історія 2: Оптимізація, що дала протилежний ефект

Інша компанія хотіла «чистий DNS». Їхня безпекова команда наполягла на агресивному видаленні старих DKIM-ключів: ротація щотижня, видаляти одразу після cutover, тримати зону мінімальною. На слайді це звучало круто.

Але це зіграло проти них банально. У їхній вихідній пошті були системи, що ставили в чергу повідомлення на години (пакетні відправки, відкладені нотифікації, повтори при обмеженні провайдера). Частина повідомлень була підписана старим ключем і доставилась пізніше, вже після того як DNS-запис старого селектора видалили. Отримувачі не могли їх валідувати. Деякі провайдери сприймали це гірше, ніж відсутність підпису, бо виглядало як підтасовка.

У них не було сигналу «DKIM падає, бо ви видалили ключ зарані». Був дашборд «доставлення знизилось», що еквівалентно пожежній сигналізації, яка спрацьовує коли кухня вже в полум’ї.

Вони змінили політику: тримати старі селектори в DNS тижнями, а не днями. Також ввели версіонування селекторів по кварталах і обмежили частоту ротацій до реального ризику. Чистіший DNS не покращив доставлення. Він нікого не зробив щасливішим.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

Одна організація мала звичку, що виглядала надмірною, поки не стала рятівною: вони вели «інвентар поштової автентифікації» — файл зі списком кожної системи, що відсилає пошту, якого домену використовує From, з яким селектором підписує, і хто її власник. Це було не гламурно. Це оновлювалося руками. Це було правильно.

Коли планували ротацію на основному домені, вони використали інвентар для поетапної зміни: два on-prem MTA, один хмарний ретранслей і SaaS-система для заявок, яка підписувала від імені делегованого субдомену. Вони ротаціювали кожен потік свідомо і тримали старі ключі опублікованими місяць.

Посередині виявилось, що один регіональний MTA все ще підписував старим селектором. Не через некомпетентність — регіон мав інший вікно технічного обслуговування і окремий пайплайн управління конфігом. Інвентар зробив це видимим. Вони не видалили старий селектор. Інциденту не було. Ніхто нічого не помітив. Оце і є мета.

Також у них був заздалегідь написаний фрагмент відкату в системі управління конфігом: одна зміна, щоб повернути селектор і розгорнути. Його так і не використали. Саме можливість його використати зберегла спокій під час ротації.

Питання й відповіді

1) Як часто нам слід ротаціювати ключі DKIM?

Ротація відповідно до рівня ризику: зазвичай від кварталу до року. Ротацію виконуйте негайно, якщо підозрюєте компрометацію ключа, підписувач було скомпрометовано або приватний ключ опинився поза вашим контролем.

2) Чи можна повторно використати той самий селектор і просто змінити ключ у DNS?

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

3) Як довго зберігати старий публічний ключ DKIM у DNS?

Щонайменше 7 днів після того, як ви припинили ним підписувати; 30 днів — безпечніше в підприємствах. Якщо у вас довгі черги або періодичні пакетні відправки — тримайте довше. Раннє видалення не дає переваг і може нашкодити пізніше доставленим листам.

4) Який TTL варто використовувати для DKIM TXT-записів?

Поширені значення — від 300 до 3600 секунд. Для ротації зниження TTL за день до зміни допомагає. Після ротації можна підняти TTL трохи, якщо хочете менше DNS-запитів, але не женіться за дрібними оптимізаціями.

5) Який розмір ключа слід використовувати?

Використовуйте 2048-бітний RSA, якщо у вас немає валідованої альтернативи і підтвердженої сумісності з отримувачами. 1024-бітні ключі дедалі частіше вважають слабкими або неприйнятними політикою.

6) Якщо DKIM проходить, чи потрібен нам все ще SPF?

Так. SPF і DKIM дають різні гарантії. DMARC дозволяє або вирівняний DKIM, або SPF задовольняти політику. Маючи обидва — ви стійкіші до пересилань, ретраїв і дивних шляхів відправки.

7) Чому DKIM падає лиш для пересланих повідомлень?

Форвардери іноді модифікують тіло або заголовки (додають футери, переписують subject, змінюють MIME-границі). Якщо вони торкаються підписаних частин — підпис зламається. Рішення: мінімізувати модифікації після підпису і використовувати DMARC-дружні механізми пересилання, коли можливо.

8) Чи можна провести ротацію без простоїв, якщо ми використовуємо сторонній ESP?

Зазвичай так, але контроль виглядає інакше: ви генеруєте/публікуєте DNS-ключі і налаштовуєте, який селектор використовує ESP. Правило перекриття таке саме: спочатку опублікуйте новий селектор, перевірте, потім перемикайте. Тримайте старий селектор опублікованим після.

9) Який найнадійніший спосіб тестувати перед тим, як переключити продакшн-трафік?

Використайте виділений субдомен або невеликий піднабір потоків, якщо підписувач підтримує політики на рівні відправника чи домену. Опублікуйте новий селектор, підписуйте тестову пошту і валідуйте в кількох великих провайдерів скриньок.

10) Чи плутають отримувачі кілька DKIM-підписів?

Ні, кілька підписів — звична річ. Отримувачі можуть валідувати будь-яку з них. Важливо, щоб хоча б одна вирівняна DKIM-підпис проходила для DMARC (залежно від політики і режиму вирівнювання).

Висновок: наступні кроки на цей тиждень

Якщо хочете, щоб ротація DKIM була непомітною, ставтесь до неї як до будь-якої іншої production-зміни: підготуйте, верифікуйте зовні, перекривайте довше, ніж інтуїція підказує, і не видаляйте речі зарані.

  • Задокументуйте інвентар відправників: кожна система, кожен домен у From, кожен селектор DKIM.
  • Оберіть схему селекторів, що переживе організаційні зміни (схема по кварталах або роках підходить).
  • Зробіть прогін на некритичному субдомені, щоб перевірити інструменти DNS і поведінку перезавантаження підписувача.
  • Додайте два монітори: (1) «DKIM присутній» у зразках вихідної пошти, (2) «рівень проходження DKIM» через отримані заголовки або доступну телеметрію.
  • Заплануйте ротацію з перекриттям: опублікуйте новий ключ, перевірте на публічних резолверах, потім переключіть підписування, тримайте старий ключ у DNS ще тижнями.

Ваша мета — не довести, що ви вмієте ротацію ключів. Ваша мета — щоб ніхто не помітив, що ви це зробили.

← Попередня
Proxmox LVM-thin «вичерпано простір даних»: звільнити місце без видалення віртуальних машин
Наступна →
ZFS L2ARC на SATA SSD: коли це має сенс

Залишити коментар