uCheckeruChecker
13 мин чтения

Анализ заголовков email: как читать и диагностировать

Письмо не дошло. Попало в спам. Подписчик уверяет, что не получал, а логи ESP говорят «delivered». Каждый раз, когда требуется выяснить, что произошло с конкретным сообщением, ответ находится в одном месте - в заголовках. Проблема в том, что их редко кто умеет читать.


Что такое заголовки письма

Каждое email-сообщение состоит из двух частей: тело (то, что видит получатель) и заголовки (метаданные, которые видят серверы). Заголовки записывают весь путь письма - от момента отправки до момента доставки в ящик. Каждый сервер, через который проходит сообщение, добавляет свою строку. Получается что-то вроде штампов в паспорте: по ним можно восстановить весь маршрут.

В Gmail заголовки доступны через «Показать оригинал» (Show original). В Outlook - «Свойства сообщения». В Thunderbird - Ctrl+U. Результат - блок текста, который выглядит пугающе, но подчиняется чётким правилам.

Анатомия заголовков: что за что отвечает

Вот реальный (анонимизированный) набор заголовков транзакционного письма. Разберём его блок за блоком.

Return-Path: <bounces@mail.example.com>
Received: from mx1.recipient.com (mx1.recipient.com [203.0.113.10])
    by inbox.recipient.com with ESMTPS id a1b2c3d4
    for <user@recipient.com>; Wed, 23 Apr 2026 09:14:02 +0000
Received: from sender-mta.example.com (sender-mta.example.com [198.51.100.25])
    by mx1.recipient.com with ESMTPS id e5f6g7h8
    for <user@recipient.com>; Wed, 23 Apr 2026 09:14:01 +0000
Authentication-Results: mx1.recipient.com;
    dkim=pass header.d=example.com header.s=s1 header.b=aB3kL9;
    spf=pass (mx1.recipient.com: domain of bounces@mail.example.com
        designates 198.51.100.25 as permitted sender)
        smtp.mailfrom=bounces@mail.example.com;
    dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
    d=example.com; s=s1; h=from:to:subject:date:message-id;
    bh=LPJNul+wow5MvFz8kU5OR6Hkz9TyF4RR3DN3kQ4bLEk=;
    b=aB3kL9mN...
From: Notifications <notify@example.com>
To: user@recipient.com
Subject: Your order #4821 has shipped
Date: Wed, 23 Apr 2026 09:13:58 +0000
Message-ID: <20260423091358.a1b2c3@sender-mta.example.com>
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8

Много текста. Разберём по частям, начиная с самого важного.

Received-цепочка: маршрут письма

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

# Шаг 1 (нижний Received): отправляющий сервер передал письмо
Received: from sender-mta.example.com (sender-mta.example.com [198.51.100.25])
    by mx1.recipient.com with ESMTPS id e5f6g7h8
    for <user@recipient.com>; Wed, 23 Apr 2026 09:14:01 +0000

# Шаг 2 (верхний Received): MX получателя передал во внутреннюю систему
Received: from mx1.recipient.com (mx1.recipient.com [203.0.113.10])
    by inbox.recipient.com with ESMTPS id a1b2c3d4
    for <user@recipient.com>; Wed, 23 Apr 2026 09:14:02 +0000

Что можно извлечь:

  • IP отправляющего сервера - 198.51.100.25. По нему можно проверить репутацию через Talos, Barracuda Central или MXToolbox. Если IP в блеклисте - вот вам и причина проблем.
  • Протокол - ESMTPS означает TLS-шифрование. Если видите просто ESMTP или SMTP - соединение было нешифрованным. В 2026 году это уже красный флаг для многих провайдеров.
  • Временные метки. Разница между шагами - 1 секунда. Нормально. Если между хопами проходят минуты или часы - сервер ставил письмо в очередь. Возможные причины: greylisting, перегрузка, rate limiting.
  • Hostname и reverse DNS. В скобках после имени хоста указан IP. Если reverse DNS (PTR-запись) не совпадает с hostname - это сигнал для спам-фильтров.

Return-Path и envelope-from

Return-Path: <bounces@mail.example.com>

Return-Path - адрес, на который приходят bounce-уведомления. Его устанавливает принимающий сервер на основе SMTP-команды MAIL FROM (она же envelope-from). Этот адрес может полностью отличаться от того, что стоит в заголовке From - и это нормально.

ESP-сервисы почти всегда используют свой домен в Return-Path, чтобы обрабатывать bounces автоматически. Именно поэтому для DMARC alignment важен DKIM: SPF проверяется по envelope-from (домен ESP), а не по видимому From (ваш домен). Если DKIM подписан вашим доменом - alignment пройдён.

Authentication-Results: вердикт принимающего сервера

Это самый полезный заголовок при диагностике доставляемости. Принимающий сервер записывает результаты всех проверок аутентификации в одном месте.

Authentication-Results: mx1.recipient.com;
    dkim=pass header.d=example.com header.s=s1 header.b=aB3kL9;
    spf=pass (mx1.recipient.com: domain of bounces@mail.example.com
        designates 198.51.100.25 as permitted sender)
        smtp.mailfrom=bounces@mail.example.com;
    dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com

Три проверки, три результата. Вот что означает каждый:

  • dkim=pass - подпись валидна. header.d показывает, каким доменом подписано. header.s - селектор. Если видите dkim=fail - ключ не совпал, подпись повреждена или селектор указан неверно.
  • spf=pass - IP отправителя входит в SPF-запись домена из envelope-from. Обратите внимание: SPF проверяется для bounces@mail.example.com, а не для видимого From.
  • dmarc=pass - хотя бы один из протоколов (SPF или DKIM) прошёл и совпал по домену с From. dis=NONE значит, что никаких действий не применялось (письмо прошло все проверки).

Как выглядит провал аутентификации

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

Authentication-Results: mx.google.com;
    dkim=fail (body hash did not verify)
        header.d=example.com header.s=brevo01;
    spf=softfail (google.com: domain of transitioning bounces@sendinblue.com
        does not designate 185.41.28.98 as permitted sender)
        smtp.mailfrom=bounces@sendinblue.com;
    dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=QUARANTINE)
        header.from=example.com

Тут всё плохо. Разберём:

  • dkim=fail (body hash did not verify) - DKIM-подпись не совпала. Либо DNS-запись для селектора brevo01 не добавлена, либо тело письма было изменено после подписания (прокси, антивирус, форвардинг).
  • spf=softfail - IP 185.41.28.98 не указан в SPF-записи домена sendinblue.com как разрешённый отправитель. Это внутренняя проблема ESP или переходный период.
  • dmarc=fail, dis=QUARANTINE - ни SPF, ни DKIM не прошли с корректным alignment. Политика домена - quarantine, поэтому письмо отправлено в спам.

Решение: добавить DKIM-запись для нового ESP, убедиться, чтоd= в подписи совпадает с доменом в From, и дождаться пропагации DNS. После этого - отправить тестовое письмо и снова проверить заголовки.

DKIM-Signature: что скрывается внутри

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
    d=example.com; s=s1;
    h=from:to:subject:date:message-id;
    bh=LPJNul+wow5MvFz8kU5OR6Hkz9TyF4RR3DN3kQ4bLEk=;
    b=aB3kL9mN...

Теги:

  • v=1 - версия DKIM. Всегда 1.
  • a=rsa-sha256 - алгоритм подписи. RSA с SHA-256 - стандарт. Если видите ed25519-sha256, это более новый и быстрый алгоритм, но его поддерживают не все провайдеры.
  • c=relaxed/relaxed - каноникализация заголовков/тела. Relaxed допускает небольшие изменения в пробелах и регистре. Simple - нет. Для рассылок всегда используйте relaxed/relaxed, иначе промежуточные серверы сломают подпись.
  • d=example.com - домен, от имени которого подписано. Должен совпадать или быть родительским для домена в From (для DMARC alignment).
  • s=s1 - селектор. Публичный ключ находится в DNS по адресу s1._domainkey.example.com.
  • h= - список подписанных заголовков. Если заголовок From не указан здесь, подпись фактически бесполезна для DMARC.
  • bh= - хеш тела письма. Именно по нему проверяется целостность содержимого.
  • b= - сама подпись (base64). Принимающий сервер пересчитывает хеш и сравнивает с этим значением, используя публичный ключ из DNS.

X-заголовки: информация от ESP и фильтров

Помимо стандартных заголовков, серверы и сервисы добавляют собственные. Они начинаются с X- (хотя RFC 6648 от 2012 года это уже не рекомендует, на практике все продолжают так делать).

X-Spam-Status: No, score=-2.1 required=5.0
    tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
    DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_NONE=-0.0001,
    SPF_HELO_NONE=0.001, SPF_PASS=-0.001]
X-Spam-Score: -2.1
X-Mailer: Postmark
X-PM-Message-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479

На что смотреть:

  • X-Spam-Status / X-Spam-Score - результат SpamAssassin или аналогичного фильтра. Отрицательный score - хорошо. Положительный выше порога (обычно 5.0) - спам. Поле tests= перечисляет конкретные правила и их вклад в score. Это прямой путь к диагнозу: какие именно факторы повысили спам-оценку.
  • X-Mailer / X-PM-Message-Id - идентификаторы ESP. По ним можно найти письмо в логах сервиса и получить дополнительную информацию о доставке.
  • X-Google-DKIM-Signature - дополнительная подпись, которую добавляет Gmail при пересылке. Не путайте с вашей DKIM-подписью.

Практическая диагностика: пошаговый алгоритм

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

  1. Откройте Authentication-Results. Если dkim=fail, spf=fail или dmarc=fail - проблема в аутентификации. Дальше можно не копать, пока не исправите DNS-записи.
  2. Проверьте Received-цепочку. Считайте хопы и время. Аномальная задержка между хопами - признак greylisting или проблем на стороне отправителя. Неожиданный промежуточный сервер - возможно, письмо перенаправлялось (forward), и это сломало SPF.
  3. Посмотрите Return-Path. Если домен в Return-Path не связан с вашим - это нормально для ESP. Но убедитесь, что DKIM alignment работает.
  4. Найдите X-Spam-Status. Если score высокий - изучите список правил. Частые виновники: HTML_IMAGE_RATIO (слишком много картинок), URIBL_BLOCKED (ссылки на заблокированные домены), MISSING_MID (нет Message-ID).
  5. Проверьте IP отправителя. Скопируйте IP из нижнего Received-блока и проверьте его через MXToolbox Blacklist Check или Talos Intelligence. Если IP в одном или нескольких DNSBL - это влияет на доставку.

Пересылка писем: почему ломается аутентификация

Одна из самых частых причин провала DMARC - пересылка. Подписчик настроил автоматический forward с рабочего адреса на личный. Письмо проходит через промежуточный сервер. Что происходит:

  • SPF ломается. Промежуточный сервер отправляет письмо со своего IP, которого нет в SPF-записи исходного отправителя.
  • DKIM может уцелеть - если промежуточный сервер не модифицирует подписанные заголовки и тело. Но некоторые серверы добавляют футеры, меняют кодировку или подставляют свои заголовки. В этом случае подпись ломается.
  • ARC (Authenticated Received Chain) - механизм, созданный для решения этой проблемы. Промежуточный сервер «запечатывает» результаты аутентификации в специальных заголовках ARC-Authentication-Results, ARC-Message-Signature, ARC-Seal. Gmail и Microsoft учитывают ARC при принятии решений о доставке.
ARC-Authentication-Results: i=1; mx.forwarder.com;
    dkim=pass header.d=example.com;
    spf=pass smtp.mailfrom=bounces@mail.example.com;
    dmarc=pass header.from=example.com
ARC-Seal: i=1; a=rsa-sha256; d=forwarder.com; s=arc-key;
    cv=none; b=Xk9mR2...
ARC-Message-Signature: i=1; a=rsa-sha256; d=forwarder.com;
    s=arc-key; h=from:to:subject:date;
    bh=LPJNul+wow5MvFz8kU5OR6Hkz9TyF4RR3DN3kQ4bLEk=;
    b=pQ7nW1...

Если видите ARC-заголовки в цепочке - значит, промежуточный сервер корректно обработал пересылку. Поле cv=none означает, что это первый хоп ARC-цепочки. cv=pass на последующих хопах - предыдущие звенья валидны. cv=fail - цепочка нарушена, доверия нет.

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

Читать заголовки глазами - полезный навык, но на потоке эффективнее использовать инструменты.

Google Admin Toolbox - Messageheader. Вставляете сырые заголовки, получаете визуализацию маршрута с таймингами между хопами. Бесплатно, работает в браузере.

MXToolbox Header Analyzer. Разбирает заголовки и отмечает проблемы: задержки, отсутствие TLS, неудачную аутентификацию. Выделяет подозрительные строки цветом.

Командная строка. Для тех, кто предпочитает терминал:

# Извлечь все Received-заголовки из .eml файла
grep -E "^Received:" message.eml

# Проверить DKIM-подпись локально (требуется opendkim-tools)
opendkim-testmsg < message.eml

# Быстрый DNS-запрос для проверки DKIM-ключа по селектору из заголовка
dig TXT s1._domainkey.example.com +short

# Проверить, не в блеклисте ли IP из Received
dig +short 25.100.51.198.zen.spamhaus.org
# Если вернулся 127.0.0.x — IP заблокирован

Типичные паттерны в заголовках и что они означают

За годы работы с почтовой инфраструктурой накапливаются характерные сценарии. Вот самые частые.

  • Несколько DKIM-Signature. Письмо подписано дважды - сначала ESP (своим доменом), потом вашим (custom DKIM). Это нормально и даже полезно. Gmail учитывает обе подписи.
  • spf=none. Для домена из envelope-from не существует SPF-записи. Не fail, а именно none - запись отсутствует. Срочно добавить.
  • dkim=temperror. Принимающий сервер не смог получить DKIM-ключ из DNS. Временная проблема, обычно связанная с DNS-таймаутом. Если повторяется - проверьте TTL записи и доступность DNS.
  • Received с подозрительным hostname. Если в цепочке появляется сервер с непонятным именем или IP из диапазона, не принадлежащего вашему ESP, - это может быть признаком компрометации или нежелательного перенаправления.
  • X-MS-Exchange-Organization-AuthAs: Anonymous. Типично для Exchange Online. Означает, что письмо пришло извне организации. Не ошибка, но информативно при диагностике внутренней маршрутизации.

Заголовки и доставляемость: прямая связь

Аутентификация - необходимое условие, но не достаточное. Все три проверки могут быть пройдены, а письмо всё равно окажется в спаме. Почему? Потому что спам-фильтры учитывают десятки других факторов: репутацию домена и IP, контент, поведение получателей, соотношение жалоб к объёму. Заголовки помогают исключить инфраструктурные причины. Если Authentication-Results показывает три pass, а письма всё равно в спаме - дело не в DNS, а в репутации или контенте.

Другой важный аспект - качество списка. Отправка на несуществующие адреса, спам-ловушки и давно неактивные ящики разрушает репутацию. Заголовки расскажут, как сервер обработал конкретное письмо. Но чтобы не попадать в ситуацию, когда приходится разбирать заголовки десятков проблемных писем, проще не допускать грязные адреса в базу.

Заголовки - это следствие. База - причина.

Умение читать email-заголовки - ценный навык для диагностики. Но лучшая диагностика - профилактика. Если база содержит только валидные, активные адреса, поводов разбирать заголовки становится на порядок меньше.

Проверьте базу в uChecker - за минуты увидите невалидные адреса, спам-ловушки и рискованные контакты. Чистая база означает меньше bounces, здоровую репутацию домена и заголовки, в которых стоит pass, а не fail.

email headers анализзаголовки emailReceived заголовокAuthentication-Resultsдиагностика почтыemail troubleshooting