Тільки починаєте з DMARC? Почніть з основ →
Ви додаєте до запису SPF ще одного постачальника. Зміна в DNS проходить, жоден лист не повертається. А за тиждень зведені звіти показують, що SPF провалюється для пошти з Google Workspace — відправника, якого ніхто не чіпав роками.
Запис не помилковий. Він задорогий. SPF обмежує кожну перевірку десятьма DNS-запитами, і новий include підняв ваш запис до 11. Після перевищення ліміту отримувач припиняє перевірку й повертає permerror для кожного листа з домену, а не лише для пошти нового постачальника.
Що входить у ліміт
RFC 7208, розділ 4.6.4 називає все, що коштує запит: механізми include, a, mx, ptr і exists та модифікатор redirect. Реалізації повинні обмежувати їхню загальну кількість десятьма, а після перевищення — повертати permerror.
Найчастіше спотикаються на трьох деталях:
- Вкладені запити теж входять у ліміт.
include:коштує один запит плюс кожен запит усередині запису, на який він посилається, — до самого низу. ip4,ip6іallнічого не коштують. Під час перевірки вони не звертаються до DNS.- Порожні запити мають власний ліміт — два. Сюди належить механізм, що не знаходить жодного запису: наприклад, include постачальника, який прибрав свій SPF-хост. Третій такий запит теж дає
permerror.
Скільки насправді коштує один include
Інструкції постачальників кажуть, який include додати. Скільки він коштує, там не пишуть. Ми розгорнули поширені include 14 жовтня 2026 року:
| Include | Запитів |
|---|---|
_spf.google.com (Google Workspace) |
1 |
spf.protection.outlook.com (Microsoft 365) |
1 |
mail.zendesk.com |
1 |
amazonses.com |
1 |
_spf.salesforce.com |
2 |
sendgrid.net |
2 |
mailgun.org |
5 |
email.freshdesk.com |
7 |
Найбільші провайдери публікують плоскі списки діапазонів ip4: і ip6:, тож кожен коштує один запит. Інші вкладають записи один в одного. Include, який Freshdesk наводить у документації, веде до SendGrid і ще до чотирьох регіональних записів самого Freshdesk: сім запитів за один рядок вашого запису. Додайте Google Workspace і Mailgun — і такому запису потрібно вже 13:
v=spf1 include:_spf.google.com include:email.freshdesk.com include:mailgun.org ~all
Ці цифри змінюються щоразу, коли постачальник перебудовує свій запис, і про це ніхто не попереджає. Вважайте таблицю знімком і перевіряйте власний запис. Найнадійніше — пройти дерево вручну: запитайте TXT-запис, повторіть те саме для кожного include у ньому і так до кінця.
dig +short TXT email.freshdesk.com
Що permerror робить із DMARC
DMARC проходить, коли SPF або DKIM проходить і узгоджується з доменом у полі From: (RFC 9989). permerror — не pass, тож щойно запис виходить за ліміт, SPF більше нічим не допомагає жодному листу. Усі відправники тепер тримаються лише на DKIM.
Пошта від сервісів, що підписують її вашим доменом, і далі проходить. Пошта, яка трималася на SPF, провалює DMARC: локальний поштовий релей, сканер, що надсилає від scans@, постачальник, для якого так і не налаштували DKIM. За p=none цього ніхто не помітить. За p=quarantine чи p=reject це втрачені листи.
Зведені звіти покажуть проблему раніше, ніж хтось поскаржиться. Шукайте в блоці auth_results таке:
<spf>
<domain>example.com</domain>
<result>permerror</result>
</spf>
permerror на вашому власному домені для всіх джерел вказує на сам запис: ліміт запитів, синтаксичну помилку або два записи SPF на одному імені — розділ 4.5 теж трактує це як permerror. Як читати решту звіту, розповідає стаття про зведені звіти.
Спершу скоротіть запис, потім згортайте
Більшість записів, що вийшли за ліміт, тягнуть зайвий баласт. Почніть із цього: кожен крок прибирає запити й не додає нічого, що доведеться підтримувати.
Приберіть include постачальників, якими вже не користуєтеся. Такий є в кожному записі: маркетингова платформа трирічної давності, служба підтримки, яку давно замінили. Зведені звіти за 30 днів покажуть, які джерела справді надсилають пошту. Include, діапазони якого жодного разу не трапляються серед джерел, — кандидат на видалення.
Приберіть include, які ніколи не перевіряються. SPF перевіряє домен конверта (MAIL FROM), а не видиму адресу From: (RFC 7208, розділ 2.4). Багато платформ надсилають пошту з адресою повернення на власному домені. Для такої пошти отримувач перевіряє SPF постачальника, а ваш include навіть не читає. У звітах домен SPF для такого джерела — домен постачальника, а не ваш. Ці листи проходять DMARC через узгоджений DKIM або не проходять взагалі, тож include лише витрачає запити.
Замініть a, mx і ptr адресами. Для власних серверів ip4: і ip6: нічого не коштують. ptr у записі бути не повинно взагалі: розділ 5.5 прямо каже, що його не слід публікувати. Механізм mx часто лишається з типового запису, який згенерував DNS-хостинг. Якщо вхідну пошту обслуговує Google чи Microsoft, вихідну вже авторизує їхній include, а mx витрачає запит на сервери, які пошту приймають, а не надсилають.
Винесіть великого відправника на окремий піддомен. Більшість сервісів, що надсилають пошту, підтримує власний Return-Path — зазвичай це CNAME на кшталт bounce.example.com, що вказує на постачальника. SPF для такої пошти перевіряється на піддомені, з окремим лімітом у 10 запитів, і нічого не забирає з вашого основного запису. У режимі relaxed, який DMARC використовує за замовчуванням, bounce.example.com узгоджується з example.com у полі From:. Це єдине виправлення, яке заодно покращує й узгодження; як воно працює, пояснює стаття про узгодження DMARC.
Згортання SPF і чому статична копія застаріває
Згортання (SPF flattening) замінює кожен include: діапазонами ip4: і ip6:, на які він розгортається, і запити на цих постачальників падають до нуля. Але в нього є чотири власні проблеми.
Копія не стежить за постачальником. Коли провайдер додає діапазон, його власний запис змінюється того ж дня. Ваша згорнута копія — ні, і пошта з нового діапазону провалює SPF без жодної помилки. Згорнутий вручну запис працює в день публікації і відтоді лише старіє.
Макроси не згортаються. Salesforce публікує v=spf1 exists:%{i}._spf.mta.salesforce.com -all. Макрос %{i} підставляє IP-адресу, з якої прийшов лист, тож рішення ухвалюється для кожного листа окремо, у момент запиту. Списку діапазонів, який можна скопіювати, просто немає. Залиште цей include як є.
Розмір. RFC 7208 радить тримати відповідь SPF у межах 450 октетів, щоб вона вміщалася в UDP-пакет (розділ 3.4), а один рядок TXT вміщує щонайбільше 255 символів (розділ 3.3). Лише дерево Freshdesk розгортається в десятки діапазонів. Згорнутий запис реального домену врешті розкладається на кілька зв'язаних записів на піддоменах, які тепер підтримуєте ви.
Два записи. Якщо вставити згорнутий запис поруч зі старим, на одному імені опиняться два записи v=spf1 — а це окремий permerror.
Згортання безпечне, коли записи регулярно розгортаються наново, а результат публікується знову щоразу, як постачальник змінює свої діапазони. На тарифі Professional DDMARC робить це за вас: ви вказуєте свої джерела пошти, DDMARC розгортає їх, тримає діапазони актуальними, коли провайдери їх змінюють, і віддає результат зі своєї зони, тож ваш основний запис зводиться до одного include. Хоч би яким інструментом ви згортали, перевірте, як він обробляє записи з макросами на кшталт Salesforce.
Порядок, у якому ми працюємо
- Спершу знизьте TTL. Встановіть для запису SPF TTL 300 секунд — щонайменше за один старий TTL до зміни, зазвичай за добу. Тоді резолвери швидко підхоплять новий запис, а помилку можна буде відкотити за хвилини. Коли звіти стануть чистими, поверніть попередній TTL.
- Порахуйте. Розгорніть дерево include до кінця й запишіть обидва підсумки: загальну кількість запитів і кількість порожніх.
- Складіть перелік. Візьміть зведені звіти за 30 днів і випишіть кожне джерело, що надсилає пошту від вашого домену, з його доменом SPF і результатом.
- Скоротіть. Приберіть мертві include, include, які ніколи не перевіряються, і механізми
a,mx,ptr, які можна замінити адресами. - Винесіть. Переведіть найбільших відправників на піддомен із власним
Return-Path. - Згорніть решту — інструментом, що тримає її актуальною.
- Перевіряйте кожен новий include до публікації. Зробіть підрахунок запитів частиною підключення нового постачальника. Більшість записів виходить за ліміт по одному постачальнику за раз.