Сервис развивается: тестируем формат, собираем идеи, улучшаем сервис. Есть идеи?

Написать
Войти
Дайджесты новостей
Схема проверки SPF

Синтаксис записей SPF: механизмы, макросы и лимиты DNS по стандарту RFC 7208

Справочник по синтаксису записей SPF согласно стандарту RFC 7208: механизмы авторизации, квалификаторы, модификаторы redirect и exp, динамические макросы %{i}, жесткий лимит в 10 DNS-запросов и правила разделения строк внутри TXT-записи для защиты доменов от спуфинга и обеспечения доставляемости писем.

Синтаксис записей SPF: механизмы, макросы и лимиты DNS по стандарту RFC 7208

Запись SPF (Sender Policy Framework — инфраструктура политики отправителя) представляет собой стандарт аутентификации электронной почты, позволяющий владельцу доменного имени публично указать список серверов и IP-адресов, имеющих право отправлять письма от его имени. Опубликованный в апреле 2014 года стандарт RFC 7208 строго регламентирует грамматику, порядок обработки и системные ограничения этих записей.

Нарушение даже одного правила синтаксиса или превышение лимита в 10 DNS-запросов мгновенно приводит к статусу постоянной ошибки (PermError). В результате почтовые серверы получателей (такие как Gmail, Яндекс или Microsoft 365) перестают доверять письмам домена и отправляют их в папку «Спам» либо отклоняют вовсе. Чтобы поддерживать надежную доставляемость почты, системным администраторам и разработчикам необходимо понимать внутреннюю логику и ограничения SPF.

Грамматика и анатомия SPF-записи

Запись SPF публикуется исключительно как текстовая DNS-запись типа TXT. Она состоит из трех обязательных компонентов: версии, списка механизмов проверки и опциональных модификаторов:

v=spf1 ip4:192.0.2.0/24 include:_spf.google.com ~all

Правила синтаксиса требуют соблюдения строгих норм:

  1. Версионный тег v=spf1: обязан стоять в самом начале. Если запись начинается, например, с v=spf10, парсер получателя полностью проигнорирует ее.
  2. Разделители: все элементы разделяются строго одинарными пробелами. Использование пробела после двоеточия (например, include: example.com) делает всю запись невалидной.
  3. Единственность записи: доменное имя обязано иметь ровно одну запись, начинающуюся с v=spf1. Если администратор публикует две отдельные TXT-записи для SPF, почтовый сервер возвращает PermError. Все сервисы должны быть объединены в одну строку.

Механизмы и квалификаторы: логика первого совпадения

Почтовый сервер получателя выполняет процедуру check_host(), проверяя механизмы записи строго слева направо до первого совпадения. Как только IP-адрес отправителя совпал с каким-либо правилом, обработка немедленно останавливается.

Перед каждым механизмом может указываться квалификатор, определяющий результат проверки:

  • + (Pass): отправитель авторизован (квалификатор по умолчанию, если знак опущен).
  • - (Fail): отправитель явно не авторизован (жесткий отказ).
  • ~ (Softfail): отправитель, скорее всего, не авторизован; письмо принимается с понижением репутации.
  • ? (Neutral): домен не делает утверждений о подлинности адреса.

Спецификация RFC 7208 определяет восемь механизмов проверки:

МеханизмСинтаксисУсловие совпаденияВлияние на лимит 10 DNS-запросов
allall, -all, ~allСовпадает всегда (ставится в самом конце)0 (DNS не запрашивается)
ip4ip4:192.0.2.0/24IP-адрес входит в указанную IPv4-подсеть0 (локальная проверка)
ip6ip6:2001:db8::/32IP-адрес входит в указанную IPv6-подсеть0 (локальная проверка)
includeinclude:domain.comВложенная политика домена вернула Pass+1 (плюс все вложенные запросы)
aa, a:domain.comIP совпадает с A/AAAA-записями домена+1 DNS-запрос
mxmx, mx:domain.comIP совпадает с адресами MX-серверов+1 DNS-запрос (кап на 10 хостов)
existsexists:domain.comСформированное имя имеет любую A-запись+1 DNS-запрос
ptrptr:domain.comОбратный DNS резолвится в домен (запрещен)+1 (крайне медленный, не использовать)

Лимиты DNS и скрытые ловушки стандартов

Главное ограничение RFC 7208 (§4.6.4) — лимит в 10 DNS-запросов. Это защитная мера против атак типа «отказ в обслуживании» (DoS), предотвращающая бесконечную генерацию DNS-трафика при проверке почты.

Скрытые опасности переполнения лимита:

  • Каскадные include: подключение внешних SaaS-провайдеров (Google Workspace, Mailgun, SendGrid, Unisender) быстро исчерпывает бюджет. Например, один include:spf.protection.outlook.com может внутри содержать еще 2–3 вложенных вызова.
  • Лимит Void Lookups: стандарт рекомендует ограничивать число запросов к несуществующим доменам (NXDOMAIN или пустой ответ) максимум двумя. Если в записи остался старый include на удаленный домен, проверка вернет PermError задолго до достижения 10 запросов.
  • Ограничение строки в 255 байт: размер одной текстовой строки в DNS TXT ограничен 255 октетами. Чтобы опубликовать длинную запись, ее разбивают на несколько строк в кавычках внутри одной TXT-записи: "v=spf1 ip4:... " "include:... -all". Почтовый сервер склеивает эти строки без добавления пробелов.

Модификаторы redirect, exp и динамические макросы

Помимо механизмов, стандарт поддерживает модификаторы в формате имя=значение:

  • redirect=domain.com: передает полную оценку политике другого домена, если ни один собственный механизм не совпал. В отличие от include:, результат перенаправленного домена полностью заменяет текущий. Если в записи присутствует all, модификатор redirect игнорируется.
  • exp=domain.com: указывает на TXT-запись с текстом объяснения причин отказа, который возвращается при статусе Fail. Запрос exp происходит только после завершения проверки и не расходует лимит 10 DNS-лукапов.

Динамические макросы (RFC 7208 §7) позволяют конструировать DNS-имена в реальном времени на основе параметров входящего письма:

  • %{i} — IP-адрес отправителя (в точечном формате для IPv4 или посимвольном для IPv6).
  • %{ir} — реверсивный IP-адрес (например, 192.0.2.1 превращается в 1.2.0.192).
  • %{d} — проверяемый домен, а %{d2} оставляет только два правых сегмента (главный домен).

Связка механизма exists: и макросов позволяет авторизовывать тысячи динамических серверов всего одним DNS-запросом без перечисления IP-диапазонов:

v=spf1 exists:%{i}._spf.mta.salesforce.com -all

При получении письма почтовый сервер формирует запрос вида 198.51.100.7._spf.mta.salesforce.com. Если провайдер отдает для этого имени A-запись, письмо признается легитимным.

Типовые ошибки и пошаговая процедура аудита

Анализ реальных конфигураций показывает, что большинство ошибок возникает из-за опечаток и непонимания синтаксиса:

Неправильная записьКорректный синтаксисОписание проблемы
ipv4:192.0.2.0/24ip4:192.0.2.0/24Использовано ipv4 вместо стандартного ip4
include: example.cominclude:example.comПробел после двоеточия нарушает грамматику ABNF
ip4=192.0.2.0/24ip4:192.0.2.0/24Знак = допустим только в модификаторах
Две TXT-записи v=spf1Одна объединенная записьМножественные записи возвращают PermError
v=spf1 -all include:...v=spf1 include:... -allЭлементы после -all игнорируются

Официальная процедура настройки и верификации SPF:

  1. Инвентаризация отправителей: собрать перечень всех легитимных источников почты (корпоративная почта, CRM, транзакционные шлюзы, мониторинг).
  2. Сборка единой политики: сформировать строку v=spf1, разместив сначала прямые IP-диапазоны (ip4, ip6), затем проверенные include, и завершить терминатором ~all (на этапе внедрения) или -all (в стабильном режиме).
  3. Расчет бюджета DNS: проверить сумму DNS-запросов с помощью утилиты dig или валидатора SPF, убедившись, что число лукапов строго меньше 10.
  4. Публикация в DNS: добавить единственную TXT-запись на уровне домена.
  5. Тестирование и DMARC: отправить тестовые сообщения на внешние почтовые службы, проверить заголовки Authentication-Results: spf=pass и настроить мониторинг отчетов DMARC для отслеживания ошибок.