MAATRIX / Блог / Почта с вашего адреса, которую вы не отправляли: разбор по DMARC

Почта с вашего адреса, которую вы не отправляли: разбор по DMARC

MAATRIX

Клиент пишет: «получили от вас письмо с новыми реквизитами для оплаты счёта» — а вы такого письма не отправляли. Первая реакция — «нас взломали», паника, смена всех паролей подряд. На практике в большинстве таких случаев инфраструктуру вообще не трогали: это спуфинг, подделка поля From, для которой не нужен доступ ни к вашему серверу, ни к почтовому ящику. Разница между спуфингом и реальной компрометацией видна не по ощущениям, а по конкретным данным — DMARC-отчётам и заголовкам того самого письма, и разобраться в них можно за один вечер, не поднимая ложную тревогу и не пропустив настоящую.

Спуфинг и компрометация — разные атаки с разным ответом

Спуфинг — это когда в SMTP-заголовке From стоит ваш адрес, но письмо ушло с чужого сервера, к которому у вас нет и никогда не было отношения. Технически это тривиально: протокол SMTP исторически не проверяет, имеет ли отправитель право писать From: buhgalteria@example.com — это обычное текстовое поле, как подпись на бумажном письме. Без дополнительной защиты любой может отправить письмо с любым From, и принимающий сервер примет его, если больше ничего не насторожит фильтры.

Компрометация — принципиально другая ситуация: у атакующего есть реальный доступ к вашей инфраструктуре — пароль от почтового ящика, ключ SMTP AUTH, либо сам сервер захвачен. Письмо в этом случае действительно уходит с вашего IP, зачастую проходит все проверки подлинности, потому что формально всё легитимно — просто отправляет его не тот, кто должен.

Ответ на эти два сценария не пересекается почти нигде. При спуфинге менять пароли и переустанавливать сервер бессмысленно — там нечего чистить, проблема решается настройкой аутентификации почты и работой с получателями. При компрометации, наоборот, донастройка SPF без остановки утечки ничего не даст — атакующий продолжит слать письма с реального, честно авторизованного источника. Перепутать эти два случая и начать не с того — обычная ошибка, которая либо тратит время на ненужный аудит сервера, либо оставляет реальную дыру открытой, пока вы правите TXT-записи.

Без SPF/DKIM/DMARC отличить одно от другого почти невозможно

Если у домена нет опубликованных SPF и DKIM и нет политики DMARC, то ни принимающий сервер, ни вы сами не можете формально проверить, имел ли отправитель право писать письма от имени домена. Заголовок From в таком случае — просто текст, который никто не валидирует, и любой разбор превращается в гадание по косвенным признакам: стилю письма, IP из логов, если конкретно этот случай попал к вам в логи (а если письмо ушло не через вашу инфраструктуру, в ваших логах его вообще нет).

Минимальный рабочий набор — это все три механизма вместе:

; SPF — какие серверы вправе слать почту от имени домена
example.com.            IN TXT "v=spf1 mx include:_spf.google.com -all"

; DKIM — криптографическая подпись письма приватным ключом с вашего сервера
default._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSq..."

; DMARC — политика и адрес для отчётов
_dmarc.example.com.     IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; fo=1"

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

dig txt _dmarc.example.com +short
dig txt example.com +short
dig txt default._domainkey.example.com +short

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Что видно в aggregate-отчёте (RUA) — полная картина, а не один инцидент

Aggregate-отчёт DMARC, который крупные почтовые провайдеры (Google, Microsoft, Яндекс, Mail.ru) присылают раз в сутки на адрес из rua=, — это не про конкретную жалобу клиента, а про все источники, отправившие почту с вашим доменом в From за отчётный период. Туда попадает буквально всё: ваш собственный почтовый сервер, транзакционные сервисы, CRM с автоматическими письмами — и, если он существует, сторонний источник, пытающийся писать от вашего имени. Общий формат и практика парсинга XML разобраны в статье про отчёты DMARC и работу с XML; здесь сфокусируемся именно на том, как в этих записях отличаются спуфинг и компрометация.

Запись из отчёта о попытке спуфинга обычно выглядит так — незнакомый IP, обе проверки провалены:

<record>
  <row>
    <source_ip>198.51.100.77</source_ip>
    <count>340</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>fail</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>example.com</header_from>
  </identifiers>
</record>

source_ip не входит ни в один известный вам сервис, count — резкий разовый всплеск, обе проверки — fail. При политике p=none такое письмо всё равно доходит до получателя (disposition=none), поэтому жалоба клиента и отчёт появляются примерно одновременно.

Запись, указывающая на реальную компрометацию, выглядит иначе — знакомый IP, обе проверки пройдены:

<record>
  <row>
    <source_ip>203.0.113.10</source_ip>
    <count>58</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>pass</dkim>
      <spf>pass</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>example.com</header_from>
  </identifiers>
</record>

source_ip совпадает с вашим собственным сервером или пулом отправки, spf и dkimpass, потому что письмо технически абсолютно легитимно с точки зрения аутентификации: оно реально ушло с вашей инфраструктуры и подписано вашим настоящим ключом. Проблема не в протоколах — она в том, кто именно инициировал отправку через эту инфраструктуру. Отдельно стоит смотреть на count: если обычный фон отправки с этого IP — несколько десятков писем в сутки, а тут внезапно несколько тысяч ночью, это соответствует картине из статьи про сервер, который начал рассылать спам ночью — только там диагностика идёт от очереди Postfix изнутри сервера, а здесь — от DMARC-отчёта снаружи, но признак один и тот же: легитимная с точки зрения аутентификации почта, которую вы не посылали.

Практический разбор: заголовки конкретного письма

Отчёты приходят с задержкой до суток, а решение часто нужно быстрее — тогда разбирают не агрегированный отчёт, а конкретное письмо, которое прислал получатель. Попросите переслать письмо как вложение (в Gmail — «Переслать как вложение», в Outlook — «Дополнительные действия → Переслать как вложение»), обычная пересылка искажает или обрезает часть заголовков.

В заголовке Authentication-Results от принимающего сервера — сжатая версия того же самого решения, которое пойдёт в DMARC-отчёт. Спуфинг:

Authentication-Results: mx.google.com;
       dkim=fail (body hash did not verify) header.i=@example.com;
       spf=fail (google.com: domain of buhgalteria@example.com does not designate
                  198.51.100.77 as permitted sender) smtp.mailfrom=example.com;
       dmarc=fail (p=NONE sp=NONE dis=none) header.from=example.com

Компрометация:

Authentication-Results: mx.google.com;
       dkim=pass header.i=@example.com header.s=default;
       spf=pass (google.com: domain of buhgalteria@example.com designates
                  203.0.113.10 as permitted sender) smtp.mailfrom=example.com;
       dmarc=pass (p=REJECT sp=REJECT dis=none) header.from=example.com

Разница в одной строке dkim=: pass с правильным header.i и селектором (header.s=default) означает, что письмо подписано вашим настоящим приватным ключом на вашей настоящей инфраструктуре — подделать эту подпись без доступа к серверу или ключу невозможно. Если видите dkim=pass и spf=pass одновременно на письме, которое вы точно не отправляли, — это не подделка, это ваша инфраструктура, использованная не вами. Дальше стоит пройти по цепочке Received: снизу вверх — самый нижний (самый старый по времени) заголовок ближе всего к реальному источнику — и сверить IP и hostname с тем, что вы знаете о собственных серверах и провайдерах рассылки.

Отдельная оговорка, которую DMARC не решает вообще: атакующий может зарегистрировать похожий домен — с кириллической буквой вместо латинской или с добавкой вроде example-support.com — и настроить для него свои SPF/DKIM/DMARC как положено. Тогда header.from отличается от вашего домена, все проверки честно проходят pass, а получатель на глаз разницы не заметит. Это уже не про вашу DMARC-запись, а про мониторинг похожих регистраций — отдельная задача, которую одними DNS-записями не закрыть.

Таблица: чек-лист различий

ПризнакСпуфингКомпрометация
source_ip в отчёте / ReceivedЧужой, не связан с вашей инфраструктуройВаш сервер, ваш SMTP-провайдер, ваш обычный пул отправки
spf= в Authentication-Resultsfail или softfailpass
dkim= в Authentication-Resultsfail или none (подписи нет вовсе)pass с вашим доменом и селектором
Домен в header.fromИногда чуть отличается (тайпсквоттинг) — проверяйте посимвольноСовпадает с вашим точно
Объём и паттернЧасто разовый всплеск с одного IPМожет маскироваться под обычный трафик или идти волнами через AUTH
Что нужно менятьDNS-записи (SPF/DKIM/DMARC), коммуникация с получателямиПароли, ключи, ревизия доступа, инцидент-реагирование на сервере
Насколько срочноНеприятно, но не критично для ваших системКритично — атакующий имеет реальный доступ прямо сейчас

Что делать в каждом случае

Если это спуфинг — доступа к вашей инфраструктуре ни у кого нет, и лечение находится полностью в зоне DNS и коммуникации:

  1. Проверьте и донастройте SPF/DKIM, если отчёты за пару недель показывают fail у легитимных источников — иначе ужесточение DMARC заденет и их.
  2. Постепенно поднимайте политику DMARC с p=none через p=quarantine; pct=10…100 до p=reject, ориентируясь на данные из отчётов, а не на календарь. Слишком быстрый переход без наблюдения обрывает легитимную почту — разбор такого случая с CRM в статье поставили DMARC на reject и отрезали письма от CRM.
  3. Сообщите пострадавшим клиентам, что это известная попытка подделки, а не взлом, с просьбой перепроверять реквизиты голосом или в CRM, а не по письму — это управление доверием, и именно оно чаще всего снимает репутационный ущерб.
  4. Если письма идут с похожего, но не идентичного домена (тайпсквоттинг) — DMARC не поможет; здесь работает только мониторинг похожих регистраций и, при системном злоупотреблении брендом, обращение к регистратору.

Если это компрометация — атакующий имеет реальный доступ, и это требует немедленного реагирования, а не только правки DNS:

  1. Сразу смените пароль скомпрометированного ящика или учётной записи SMTP AUTH, отзовите активные сессии, проверьте правила пересылки и сторонние OAuth-приложения с доступом к ящику — они часто остаются незамеченными после смены пароля.
  2. Проверьте логи почтового сервера на аномальную активность по sasl_username и посторонние процессы — набор команд для этой диагностики разобран в статье сервер начал рассылать спам ночью.
  3. Если есть основания думать, что скомпрометирован сам приватный ключ DKIM, а не только пароль почтового ящика, — сгенерируйте новый селектор, опубликуйте новую DKIM-запись и выведите старый ключ из ротации. Как выглядит несовпадение селектора при ошибке конфигурации (а не компрометации), разобрано в статье DKIM подписывал ключом, которого нет в DNS.
  4. Оцените масштаб: один слитый пароль без следов проникновения дальше (посторонние SSH-ключи, новые пользователи) закрывается точечно. Если признаки шире — это уже полноценный инцидент с аудитом всего сервера, а не только почты.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Клиент прислал только скриншот письма, а не само письмо — можно ли по нему определить причину?

Практически нет. Скриншот не содержит служебных заголовков Authentication-Results и Received, по которым делается весь разбор. Попросите переслать письмо именно как вложение (не обычной пересылкой, которая переписывает заголовки) — без этого остаётся только гадать по тексту и стилю письма.

У нас уже DMARC на p=reject, но жалобы всё равно приходят — как так?

Два варианта: либо это письмо с похожего, но не идентичного домена (тайпсквоттинг), на который ваша DMARC-запись не распространяется вообще, либо перед вами реальная компрометация — потому что письмо, отправленное с вашей настоящей инфраструктуры и подписанное вашим настоящим ключом, пройдёт p=reject точно так же, как любое ваше легитимное письмо. Строгая политика защищает от подделки заголовка, а не от кражи доступа.

Нужно ли сразу переводить DMARC на p=reject, чтобы быстрее отсечь спуферов?

Не сразу и не без данных. Резкий переход без пары недель наблюдения на p=none/p=quarantine почти гарантированно зацепит забытый легитимный источник — транзакционный сервис, CRM, форму на сайте — и вы получите новую проблему вместо старой. Двигайтесь по данным из отчётов, а не по желанию закрыть вопрос побыстрее.

DMARC — гарантия, что от домена больше никто не напишет?

Нет. p=reject резко снижает шанс подделки именно вашего точного домена у получателей, чьи серверы применяют политику (применяют не все), но не защищает от похожих доменов и не мешает атаке, если у злоумышленника уже есть настоящий доступ к вашей инфраструктуре.

Сколько по времени занимает такой разбор одного инцидента?

Если DMARC и DKIM уже настроены и отчёты копятся — чтение одного заголовка и сверка с последним отчётом занимает 10-15 минут. Если инфраструктура аутентификации не настроена вовсе, придётся сначала разбираться по косвенным признакам в Received, и это медленнее и менее надёжно — ещё один аргумент настроить SPF/DKIM/DMARC заранее, а не в момент, когда уже пришла жалоба.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →