Тільки починаєте з DMARC? Почніть з основ →
Коли ротація DKIM ламає пошту, криптографія майже ніколи не винна. Винен DNS: новий ключ опублікували під старим селектором, поки резолвери ще тримали в кеші старий; DNS-панель не прийняла запис на 410 символів; підписування перемкнули раніше, ніж запис почав резолвитися; або про селектор якогось постачальника ніхто не згадав, а він досі на 1024 бітах.
Саме для цього й існують селектори. За RFC 6376, вони дають змогу регулярно замінювати публічні ключі без перерв у роботі. Нижче — як це робиться для ключів, якими керуєте ви, а далі — для Google Workspace, Microsoft 365 і сторонніх відправників. Як селектор перетворюється на ім'я в DNS, пояснює стаття «Що таке DKIM».
Чому від 1024-бітних ключів час відмовлятися
RFC 8301, розділ 3.2 задає і нижню межу, і ціль: відправники зобов'язані (MUST) використовувати RSA-ключі щонайменше на 1024 біти, а ключі щонайменше на 2048 біт їм слід (SHOULD) використовувати. Ключ на 1024 біти досі проходить перевірку. Але це мінімум, а не рекомендація.
Той самий RFC забороняє SHA-1: rsa-sha1 не можна використовувати ні для підпису, ні для перевірки. Сервер, який досі підписує 1024-бітним ключем, може виявитися настільки старим, що й досі підписує через SHA-1, тож заразом перевірте тег a=. Там має бути a=rsa-sha256.
Розмір ключа видно із самого запису. Публічний RSA-ключ на 1024 біти в base64 починається з MIGfMA0 і має 216 символів. Ключ на 2048 біт починається з MIIBIjAN і має 392 символи. Перевірка DKIM оцінює розмір ключа для будь-якого селектора, який ви вкажете.
Спершу — перелік усіх селекторів
Отримати з DNS список селекторів домену неможливо. Зате зведені звіти показують ті, що використовуються: RFC 9990 робить селектор обов'язковим елементом кожного результату DKIM — це селектор, за яким ішла перевірка (тег s= у підписі).
Візьміть звіти за 30 днів і випишіть для кожного джерела пару «домен підпису — селектор»:
<dkim>
<domain>example.com</domain>
<selector>mail</selector>
<result>pass</result>
</dkim>
Джерел виявиться більше, ніж ви пам'ятаєте: маркетинг, служба підтримки, виставлення рахунків, релей сканера. Кожне джерело — окрема ротація з окремим відповідальним. Решту XML розбирає стаття про те, як читати зведені звіти DMARC.
Ротація ключа, яким керуєте ви
Ідеться про сервери підписування, які ви тримаєте самі: OpenDKIM, rspamd, MTA з вбудованим підписуванням. Графік відповідає рекомендаціям M3AAWG щодо ротації ключів DKIM.
День 0: новий ключ під новим селектором
Не використовуйте стару назву селектора повторно. RFC 6376 пише про це прямо: повторно використовувати селектори для нових ключів не варто, краще призначати новим ключам нові селектори. Практична причина — кеш: резолвери віддають старий ключ, доки не мине його TTL, і до того часу листи, підписані новим ключем, не проходять перевірку.
M3AAWG радить назви, з яких видно потік пошти, дату й розмір ключа, наприклад sales-201309-1024. Підійде щось на кшталт s202610. Згенеруйте пару ключів:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out s202610.private.pem
openssl pkey -in s202610.private.pem -pubout -outform DER | openssl base64 -A
Проблема 255 символів
v=DKIM1; k=rsa; p= разом із 2048-бітним ключем — це близько 410 символів. Один TXT-рядок у DNS може мати до 256 символів разом з октетом довжини (RFC 1035, розділ 3.3), тобто 255 символів даних. Тому запис публікують як два або більше рядків в одному TXT-записі:
s202610._domainkey.example.com. 3600 IN TXT (
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
"...QIDAQAB" )
Згідно з RFC 6376, розділ 3.6.2.2, отримувач зобов'язаний склеїти рядки перед використанням, без жодних пробілів між ними. Якщо DNS-панель не розбиває довгі значення сама, інструкція Google з усунення проблем описує ручний спосіб: розбийте ключ на рядки в лапках і введіть їх один за одним.
Перевірте запис через два публічні резолвери:
dig +short TXT s202610._domainkey.example.com @1.1.1.1
dig +short TXT s202610._domainkey.example.com @8.8.8.8
Рядки в лапках після склеювання мають дати саме той ключ, який ви згенерували: без пробілу на стику, без зайвих лапок, без обрізаних символів.
Тут важливий порядок. Якщо перемкнути підписування раніше, ніж з'явиться запис, кожен отримувач, що запитає селектор, закешує відповідь «такого імені не існує». RFC 2308, розділ 5 визначає час такого кешування як менше з двох значень — поля MINIMUM у SOA і TTL самого SOA, тож підписи ще якийсь час не проходитимуть перевірку після публікації.
Дні 1–2: перемкніть підписування
Щойно обидва резолвери повернуть запис, переведіть підписування на новий ключ: в OpenDKIM це рядок у KeyTable, у rspamd — селектор і шлях до ключа в dkim_signing.conf. Надішліть лист на зовнішню скриньку й перегляньте заголовки. У DKIM-Signature мають бути s=s202610 і a=rsa-sha256, а в Authentication-Results — dkim=pass.
Дні 2–30: старий ключ не чіпайте
Листи, підписані старим ключем, ще в дорозі. Черги відправлення кілька днів поспіль повторюють спроби доставити відкладені листи: Postfix за замовчуванням здається через п'ять днів (maximal_queue_lifetime). RFC 6376, розділ 5.2 до того ж попереджає, що сторона, яка перевіряє підпис, може відкласти перевірку — аж до моменту, коли лист прочитає кінцевий одержувач. M3AAWG радить тримати старий публічний ключ у DNS без змін від семи до 30 днів.
Потім відкличте старий ключ
Коли цей період мине, замініть старий запис порожнім ключем:
mail._domainkey.example.com. 3600 IN TXT "v=DKIM1; p="
RFC 6376, розділ 3.6.1 визначає: порожнє значення означає, що цей публічний ключ відкликано. RFC дозволяє й просто видалити запис. M3AAWG віддає перевагу порожньому ключу й пише прямо: не видаляйте запис селектора. Відкликаний селектор повідомляє отримувачам, що ключ виведено з ужитку свідомо.
Через тиждень у звітах для цього джерела має лишитися тільки новий селектор.
M3AAWG також рекомендує заздалегідь публікувати в DNS наступний публічний ключ: тоді екстрена ротація після витоку ключа зводиться до зміни на сервері підписування, без очікування DNS. Наступну планову ротацію поставте в календар: за рекомендацією M3AAWG ключі варто змінювати щонайменше раз на пів року.
Якщо не хочете вести DNS-частину вручну, керований DKIM від DDMARC на тарифі Professional генерує пару ключів і віддає публічний ключ зі своєї зони через один запис CNAME. Ротація тоді створює новий селектор, а вам лишається замінити цей CNAME. Приватний ключ ви, як і раніше, встановлюєте на свій сервер підписування.
Google Workspace
У консолі адміністратора відкрийте Apps > Google Workspace > Gmail > Authenticate email, натисніть Generate New Record і виберіть довжину ключа 2048 біт. В інструкції Google з налаштування сказано: якщо домен уже використовує ключ DKIM із префіксом google, у цьому полі треба ввести інший префікс. Під час ротації саме так і є. Візьміть новий префікс, наприклад google2026, — тоді новий запис стане поруч із google._domainkey, а не замість нього.
Опублікуйте запис і переконайтеся, що він резолвиться (за словами Google, може минути до 48 годин, перш ніж автентифікація DKIM запрацює), а потім натисніть Start authentication. Залиште google._domainkey опублікованим на той самий період перекриття і лише потім відкличте. Як налаштувати перший ключ, описано в інструкції для Google Workspace.
Microsoft 365
Microsoft 365 використовує два записи CNAME, selector1._domainkey і selector2._domainkey (див. інструкцію з налаштування), а під час ротації змінюються ключі за ними, тож ваш DNS лишається без змін. Перехід на 2048 біт має дві пастки. У документації Microsoft про DKIM зазначено, що новий приватний ключ починає підписувати листи лише через чотири дні (96 годин). А довідка до Rotate-DkimSigningConfig уточнює, що -KeySize 2048 оновлює лише неактивний селектор, тож після ротації команду треба запустити ще раз — для другого:
Rotate-DkimSigningConfig -Identity example.com -KeySize 2048
# after RotateOnDate passes, for the other selector
Rotate-DkimSigningConfig -Identity example.com -KeySize 2048
Get-DkimSigningConfig -Identity example.com | Format-List Selector1KeySize,Selector2KeySize,RotateOnDate,SelectorAfterRotateOnDate
Закладіть вісім днів. New-DkimSigningConfig досі за замовчуванням створює ключі на 1024 біти, тож перевірте Selector1KeySize і Selector2KeySize, перш ніж вважати, що якийсь селектор уже на 2048.
Сторонні відправники
M3AAWG покладає цю роботу на вас: запит на ротацію має надходити від власника організаційного домену. Як усе відбувається далі, залежить від схеми.
Делегування через CNAME. Ви публікуєте записи CNAME, що вказують на постачальника, і він може змінювати ключі за ними без жодних змін у вашому DNS. У прикладі M3AAWG таких записів три: третя сторона підписує одним чинним ключем, поки інші проходять ротацію. Запитайте постачальника, як часто він змінює ключі, і перевірте розмір ключа, який віддає ціль CNAME. Не видаляйте CNAME, що здається зайвим: там може бути наступний ключ.
TXT-запис, який опублікували ви. Колись постачальник дав вам публічний ключ, і той досі лежить у вашій зоні з тим розміром, який мав тоді. Саме такі селектори роками лишаються на 1024 бітах. Щоб змінити такий ключ, попросіть у постачальника нову пару ключів під новим селектором і пройдіть разом із ним ту саму послідовність: опублікувати, перемкнути, зачекати, відкликати.
Ed25519 — поруч із RSA, а не замість нього
RFC 8463 зобов'язує сторону, що перевіряє підпис, підтримувати Ed25519-SHA256, а ключі завдовжки 44 символи вміщаються в один TXT-рядок. Але навіть розділ цього RFC про перехід передбачає, що відправники додають кілька підписів зі старим і новим алгоритмами, кожен під своїм селектором. Microsoft 365 підписує лише RSA-ключами: у довідці до командлета прямо зазначено, що ключі Ed25519 не підтримуються. Спершу перейдіть на RSA 2048, а підпис Ed25519 додайте поруч там, де ваш сервер підписування це підтримує.