Безопасность почты SPF DKIM DMARC

Почему мои письма попадают в спам? Реальное расследование SPF, DKIM и DMARC

Вы отправляете письмо. Вы знаете, что оно легитимно — оно от вашего собственного домена, написано реальным человеком, о реальном бизнесе. И всё равно оно попадает в спам. Или ещё хуже, оно вообще никуда не попадает: без отказа, без ошибки, просто тишина, потому что какой-то принимающий сервер тихо его отбросил.

Если вы когда-либо смотрели на подтверждение «сообщение отправлено», зная при этом, каким-то образом, что сообщение никогда не будет прочитано — это для вас. Не чеклист. Пошаговое руководство, как на самом деле выяснить, что сломано, в том порядке, в котором идёт реальное расследование.

Трёхбуквенные аббревиатуры, которые никто толком не объяснял

Прежде чем что-либо отлаживать, полезно понять, что на самом деле проверяется, потому что режимы отказа имеют смысл только тогда, когда вы знаете, для чего предназначен каждый механизм.

SPF (Sender Policy Framework) отвечает на один вопрос: «Разрешено ли этому серверу отправлять почту от имени этого домена?» Это TXT-запись DNS, перечисляющая IP-адреса и сервисы, авторизованные отправлять от вашего имени. Когда приходит письмо, принимающий сервер проверяет отправителя конверта — адрес, использованный в реальной SMTP-транзакции, который не всегда совпадает с адресом «От», который вы видите — против этого списка. Если отправляющий сервер не в списке, SPF проваливается.

DKIM (DomainKeys Identified Mail) отвечает на другой вопрос: «Было ли это сообщение действительно отправлено доменом, за который оно себя выдаёт, и не было ли оно подделано?» Он работает, криптографически подписывая письмо в момент отправки закрытым ключом и публикуя соответствующий публичный ключ в DNS. Принимающий сервер забирает публичный ключ, проверяет подпись и подтверждает, что сообщение не было изменено в пути. В отличие от SPF, DKIM не заботит, какой сервер отправил почту — его заботит, действительна ли подпись.

DMARC (Domain-based Message Authentication, Reporting and Conformance) — это слой политики, сидящий поверх обоих. Он говорит принимающим серверам, что делать, когда SPF или DKIM проваливаются — отправить в карантин, отклонить сразу, или ничего не делать и просто отчитаться перед вами. DMARC также включает проверку «выравнивания»: недостаточно, чтобы SPF или DKIM прошли по отдельности — домен, против которого они проверяются, должен совпадать с тем, что реально указано в видимом заголовке «От». Это та часть, которую почти все упускают, и обычно именно она — реальная первопричина, когда SPF и DKIM по отдельности выглядят нормально, а почта всё равно не проходит.

Начните с того, что реально произошло, а не с того, что должно было произойти

Инстинкт — открыть свои DNS-записи и начать читать их сверху вниз в поисках опечатки. Пока не делайте этого — вы читаете намерение, а не результат, и они часто расходятся способами, невидимыми, пока вы не посмотрите на реальную попытку доставки.

Вместо этого возьмите реальное сообщение, которое провалилось или попало в спам, и посмотрите на его заголовки. Каждый крупный почтовый провайдер (Gmail, Outlook и т.д.) позволяет вам просмотреть «оригинальную» или «сырую» версию полученного письма, которая включает заголовок Authentication-Results — это принимающий сервер, рассказывающий вам своими словами, что именно он проверил и что произошло.

Это выглядит примерно так:

Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of bounce@yourdomain.com designates 203.0.113.5 as permitted sender)
       dkim=pass header.i=@yourdomain.com header.s=selector1
       dmarc=fail (p=REJECT sp=REJECT dis=none) header.from=yourdomain.com

Прочитайте внимательно. SPF прошёл. DKIM прошёл. DMARC всё равно провалился. Это тот самый сценарий, который большинство гайдов не объясняют, потому что он выглядит противоречиво — всё прошло, так почему же всё в итоге провалилось?

Диаграмма выравнивания DMARC

Ответ — выравнивание. SPF прошёл для bounce@yourdomain.com — это адрес конверта, часто отдельный поддомен, используемый для обработки отказов (обычен для маркетинговых платформ, транзакционных email-сервисов и всего, что использует стороннего отправителя). DKIM прошёл для yourdomain.com. Но DMARC проверяет, совпадает ли домен в видимом заголовке От — том, что реально видит получатель — с тем, что аутентифицировал SPF или DKIM. Если ваш видимый адрес От — yourdomain.com, а ваш успешный SPF был для поддомена обработки отказов, который правильно не выровнен, DMARC проваливается, даже если отдельные проверки выглядят чистыми.

Именно для этого нужен анализатор заголовков — разбирать это, не требуя от вас парсить сырые SMTP-заголовки вручную. Я построил Анализ заголовков письма в MarinaDNS именно для этого момента: вставьте сырые заголовки провалившегося сообщения, и он разложит цепочку аутентификации на отдельные результаты прохождения/провала/выравнивания, вместо того чтобы оставлять вас декодировать синтаксис Authentication-Results вручную.

Теперь проверьте, что на самом деле говорит ваш DNS, а не то, что вы думаете, что он говорит

Как только вы знаете, какая проверка провалилась, идите проверять фактически опубликованную запись — потому что есть очень хороший шанс, что она говорит не то, что вы думаете. DNS-записи для аутентификации почты печально известны тем, что их легко тонко испортить: лишний пробел, отсутствующий ~all, запись, разбитая на две TXT-записи, которые должны были быть одной, селектор DKIM, который ваш почтовый провайдер повернул и никогда не обновил в DNS.

Распространённые паттерны отказов, примерно в порядке того, как часто они реально встречаются:

SPF-запись превышает лимит запросов. SPF допускает максимум 10 DNS-запросов при вычислении — каждый механизм include: считается, и они вложены. Если вы используете Google Workspace, Mailchimp и транзакционный сервис вроде SendGrid всё в одной SPF-записи, каждый со своими вложенными include, легко пропустить, что вы превысили 10, даже не заметив. Когда это происходит, большинство валидаторов не проваливаются изящно — они возвращают permerror, и принимающие серверы часто трактуют это как прямой провал, а не «дать преимущество сомнения».

Несколько SPF-записей вместо одной объединённой. Спецификация явно говорит, что у домена должна быть ровно одна SPF TXT-запись. Если предыдущий провайдер добавил одну, а новая была добавлена позже без удаления старой, теперь у вас их две, и по RFC 7208 это автоматическая постоянная ошибка — весь механизм ломается, молча, пока кто-нибудь не заметит.

Несовпадение селектора DKIM. Каждая подпись DKIM указывает selector (видимый в тегах d= и s= подписи), сообщающий принимающему серверу, какая конкретная TXT-запись DNS хранит публичный ключ — потому что у домена может быть несколько активных ключей DKIM одновременно для разных сервисов. Если ваш почтовый провайдер повернул ключи, а DNS не был обновлён новым селектором, или если вы используете два сервиса (скажем, Google Workspace для обычной почты и маркетинговую платформу для кампаний) и опубликован только один селектор, несовпадающие подписи проваливаются, даже если DKIM технически настроен.

Политика DMARC установлена на p=reject до того, как выравнивание реально было подтверждено как работающее. Это та, что превращает небольшой пробел в аутентификации в полную потерю почты. Режим отчётности DMARC (p=none) существует специально для того, чтобы вы могли наблюдать агрегированные отчёты и подтвердить, что каждый легитимный источник отправки правильно выравнивается, прежде чем говорить принимающим серверам отклонять всё, что не выравнивается. Прыжок сразу к p=reject — часто сделанный, потому что аудит безопасности отметил домен за отсутствие строгого DMARC — без прохождения через p=none, а затем p=quarantine сначала, является самой распространённой причиной «мы не можем понять, почему некоторые письма просто исчезают».

Именно это MarinaDNS's Проверка авторизации почты построена для того, чтобы ловить — она забирает живые записи для домена и отмечает именно эти паттерны (счёт запросов, дублирующиеся записи, отсутствующее выравнивание), а не просто подтверждает, что запись существует.

Как читать агрегированный отчёт DMARC, не желая закрыть вкладку

Если DMARC настроен на отправку отчётов (тег rua= в политике), вы уже получаете данные, нужные для правильного исправления — они просто доставляются в виде сжатого XML-файла раз в день от каждого крупного почтового получателя, получившего сообщение, претендующее на то, что оно от вашего домена. Никому не нравится открывать это вручную, и именно это нежелание — причина, по которой так много доменов годами работают с DMARC в режиме только отчётности, и никто на самом деле не читает отчёты.

Структура, очищенная от XML-шума, в основном такова:

  • Какой IP отправил почту, претендующую на то, что она от вас
  • Прошёл ли SPF, и был ли он выровнен
  • Прошёл ли DKIM, и был ли он выровнен
  • Сколько сообщений соответствовало этому паттерну

Полезный ход — группировать по исходному IP и спрашивать для каждого: узнаю ли я этот сервер? Если да, и он проваливает выравнивание, это пробел в конфигурации на легитимном сервисе, который стоит исправить. Если это IP, который вы не узнаёте, отправляющий почту, которая проваливает и SPF, и DKIM, это кто-то пытается подделать ваш домен — и именно для этого существует DMARC. Видеть последовательные отказы выравнивания только с незнакомых IP, наряду с последовательными успехами от ваших известных сервисов отправки, на самом деле является здоровым состоянием перед переходом к принудительному применению — это означает, что легитимная почта выравнивается, а отказы — это попытки спуфинга, а не неправильная конфигурация.

Что на самом деле это исправляет, в порядке выполнения

Как только вы знаете, какой слой проваливается и почему, исправление обычно механическое:

  1. Объедините в одну SPF-запись. Если у вас их две, объедините их в одну TXT-запись со всеми необходимыми механизмами include:.
  2. Уплостите или сократите SPF include, если вы близки к лимиту в 10 запросов. Некоторые сервисы предлагают «уплощённые» SPF-фрагменты, которые разрешаются в статические IP вместо вложенных include специально, чтобы избежать этого.
  3. Подтвердите, что селектор DKIM каждого отправляющего сервиса действительно опубликован в DNS, а не только настроен на стороне отправляющей платформы — это два отдельных шага, и часто один делается без другого.
  4. Установите DMARC на p=none сначала, если вы ещё не там, наблюдайте за отчётами как минимум полный цикл отправки (включая ежемесячные рассылки или пакетные задания, а не только ежедневную транзакционную почту), затем перейдите к p=quarantine, и только переходите к p=reject, как только отчёты покажут постоянное выравнивание от каждого легитимного источника.

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

Если вы сейчас в середине диагностики, самый быстрый путь: заберите сырые заголовки провалившегося сообщения в анализатор, чтобы увидеть, какой именно слой провалился и была ли это проблема выравнивания, затем проверьте живые DNS-записи с проверкой, чтобы увидеть, действительно ли опубликованное совпадает с тем, что вы намеревались. Девять раз из десяти разрыв между этими двумя вещами и есть вся проблема.

Инструменты из этого руководства

← Статьи