Налаштування Feedback Loop для Yahoo, Outlook і Mail.ru: як ловити скарги і чистити список автоматично
FBL — єдиний канал, що називає конкретного отримувача, який натиснув «Спам». Розбираємо, чому три провайдери прив'язують скаргу до трьох різних ключів, як обійти редагування адреси в ARF-звіті через вшитий токен і як за секунди після скарги додати адресу в suppression.
EvilMail Team11 липня 2026 р.12 хв читання
Inbox placement поповз униз, open rate просів на кілька пунктів, Google Postmaster показує «Low» замість «High» — і ти знаєш тільки одне: хтось скаржиться. Постмастер дає відсоток, але не називає жодної адреси. Прибрати проблему не вийде, бо ти не бачиш, ХТО тисне «Спам». Саме цю дірку закриває Feedback Loop: це єдиний канал, який після кожного кліку «Спам» присилає звіт із конкретним отримувачем (майже — і про це «майже» половина статті). Без FBL ти дізнаєшся про проблему тоді, коли провайдер уже вимкнув тобі inbox.
Чому FBL — це не те саме, що Postmaster Tools
Розведемо два сигнали, які постійно плутають.
Агрегована статистика. Google Postmaster Tools, Microsoft SNDS, дашборд Mail.ru віддають відсоток скарг по домену чи IP за день. Це термометр: показує, що температура піднялась, але не показує, хто хворий.
Per-complaint сигнал (FBL). На кожен окремий клік «Спам» провайдер генерує ARF-звіт і шле його на заздалегідь узгоджену адресу. Це не відсоток — це подія на рівні одного листа й одного підписника.
Ключове непорозуміння 2026 року: у Gmail per-message FBL не існує. Немає кабінету, де б ти зареєстрував домен і почав отримувати ARF на кожну скаргу від gmail-користувачів. Gmail віддає лише агрегований complaint rate у Postmaster Tools. Тому коли інженер каже «налаштувати FBL», реально це означає
Yahoo + Microsoft + Mail.ru/Yandex
, а Gmail закривається окремим інструментом і окремою логікою. Не гай час на пошук «Gmail FBL signup» — його немає.
Навіщо це взагалі. З лютого 2024 діють bulk-sender-вимоги Yahoo і Google: для відправників від 5000 листів/добу на Gmail обов'язкові SPF+DKIM+DMARC, one-click List-Unsubscribe (RFC 8058), валідний forward-confirmed rDNS — і spam complaint rate стабільно нижче 0.3%, а реальна робоча ціль — нижче 0.1%. Без FBL ти цей поріг не бачиш на рівні окремих адрес: коли Postmaster покаже 0.31%, ти вже за межею, а видалити конкретних скаржників без per-complaint звіту неможливо.
Три провайдери — три ключі прив'язки скарги
Спершу — картина цілком.
Різні ключі дають різні операційні наслідки, не академічні:
Yahoo прив'язує скаргу до DKIM-домену (`d=`). FBL «їде» за твоїм підписом, навіть якщо ти змінив IP чи ротуєш пул. Це зручно: репутація й скарги належать домену, який ти контролюєш.
Microsoft прив'язує до вихідної IP-адреси. На shared IP це біль: чужі скарги псують твою репутацію, а ARF приходить власнику IP, а не реальному відправнику листа. На власному /32 — чисто й передбачувано.
Mail.ru і Yandex прив'язують до домену з підтвердженням через TXT — механіка близька до Yahoo.
Yahoo Complaint Feedback Loop через Sender Hub
Реєстрація живе в Yahoo Sender Hub (senders.yahooinc.com). Порядок такий.
Спершу — валідний DKIM, і він має підписувати реальний трафік до подачі заявки. Yahoo відхилить реєстрацію, якщо не побачить твій d=-домен у підписаній пошті. Перевір ключ перед подачею:
bash
# перевірити, що публічний ключ реально резолвиться
dig +short TXT mail._domainkey.evilmail.pro
# на самому сервері — що приватний ключ відповідає опублікованому
opendkim-testkey -d evilmail.pro -s mail -vvv
Записи, які мають бути живими:
dns
mail._domainkey.evilmail.pro. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEB..."
_dmarc.evilmail.pro. IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; fo=1"
DMARC потрібен і для агрегації, і тому що Yahoo прив'язує FBL саме до автентифікованого d=. Далі в Sender Hub додаєш домен, підтверджуєш контроль над ним і вказуєш адресу, куди слати ARF (у нас — [email protected]).
Головний нюанс, через який більшість гайдів застаріли: Yahoo редагує (redact) адресу отримувача в ARF-звіті. У тілі звіту ти НЕ побачиш, хто саме поскаржився — лише що скарга була на твій d=. Це не баг реалізації, це навмисна приватність. І це рівно та причина, чому далі йде розділ про токени.
Microsoft JMRP і SNDS
У Microsoft два різні інструменти, і їх плутають. Реєстрація на postmaster.outlook.com, форми JMRP/SNDS — на sendersupport.olc.live.com.
JMRP (Junk Mail Reporting Program) — це власне FBL. Реєструєш вихідні IP-діапазони, і на кожну скаргу outlook.com/hotmail/live тобі приходить ARF.
SNDS (Smart Network Data Services) — це агрегат по IP: complaint rate, обсяг, RCPT-помилки, spam-trap hits. Окремо від JMRP, але реєструється тим самим Microsoft-акаунтом.
Верифікація власності — через контактну адресу в WHOIS/PTR твого IP-блоку: Microsoft шле код на адресу з rDNS/WHOIS. Оскільки ключ тут — IP, одна заявка покриває весь трафік із цього IP. На shared-пулі це і плюс (одна реєстрація), і мінус (чужі скарги в твоєму звіті). На власному IP усе, що прилетить у JMRP, — твоє.
Mail.ru і Yandex postmaster
Аудиторію RU/UA/CIS Gmail-центричні гайди ігнорують, а даремно — там мільйони скриньок. На postmaster.mail.ru додаєш домен, підтверджуєш його TXT-записом, вмикаєш FBL і вказуєш адресу для звітів. Yandex — аналогічно на postoffice.yandex.ru. Обидва прив'язують скаргу до домену, як Yahoo, і обидва шлють той самий формат ARF — тобто твій парсер із наступного розділу працює з ними без змін. Це головна причина не робити три різні обробники: формат один.
Редагування адреси: як дізнатися, ХТО поскаржився
Технічне серце. Раз Yahoo і Microsoft вирізають Original-Rcpt-To/To:, зіставляти скаргу з підписником треба за токеном, який ти вшив у лист ДО відправки. Що виживає редагування, а що ні — на розрізі ARF нижче.
Три робочі підходи, будь-який один достатній:
VERP у Return-Path — bounce+<hmac(subscriber_id|campaign_id)>@bounce.evilmail.pro. Це envelope-адреса, вона виживає редагування, бо провайдер не чіпає технічний Return-Path так, як To:. Тримай окремий домен bounce.evilmail.pro з власним SPF/DKIM.
Кастомний хедер — Feedback-ID: <campaign>:<subscriber_hash>:evilmail (конвенція Google, не RFC-стандарт) або власний X-Feedback-ID. Непрозорий, без PII, детермінований.
Унікальний DKIM-селектор чи `i=` на кампанію — рідше, але теж живе в заголовках.
Правило, яке треба вибити в граніті: токен завжди в заголовках, ніколи в тілі. У ARF тіло оригінального листа часто вирізане повністю — залишаються лише headers частини message/rfc822. Якщо твій ідентифікатор жив у HTML-тілі чи в pixel-URL, після редагування його не буде.
Автоматична обробка ARF і миттєва чистка списку
Маршрут: провайдер → [email protected] → Postfix pipe (або IMAP-поллер) → парсер → suppression-таблиця. Через /etc/aliases:
text
abuse: "|/usr/local/bin/fbl-parser.py"
Чистіше — окремим транспортом, щоб pipe крутився під непривілейованим користувачем fbl:
text
# master.cf
fbl-pipe unix - n n - - pipe
flags=Rq user=fbl argv=/usr/local/bin/fbl-parser.py
# virtual
[email protected] fbl-pipe:
Сам парсер — на стандартному email-модулі, без зовнішніх залежностей:
python
import sys, email
from email.policy import default
msg = email.message_from_binary_file(sys.stdin.buffer, policy=default)
if msg.get_content_type() != "multipart/report":
sys.exit(0) # не ARF — тихо ігноруємо
fb_type, token = None, None
for part in msg.walk():
ct = part.get_content_type()
if ct == "message/feedback-report":
report = email.message_from_string(part.get_content(), policy=default)
fb_type = report.get("Feedback-Type", "").lower()
if ct == "message/rfc822":
orig = part.get_payload(0) # заголовки оригіналу
token = (orig.get("Feedback-ID")
or _verp(orig.get("Return-Path", "")))
if fb_type == "abuse" and token:
sub_id = resolve_token(token) # HMAC -> subscriber_id
suppress(sub_id, reason="fbl", source=detect_provider(msg))
Дві речі, на яких падають реалізації. Ідемпотентність: провайдер може прислати дубль, а той самий підписник міг натиснути «Спам» на двох листах — suppress() має бути upsert, а не insert. І shared suppression: список блокування спільний для ВСІХ кампаній, не для поточної. Інакше ти прибереш людину з розсилки А, а завтра гатиш по ній із розсилки Б — і отримаєш другу скаргу від того самого адресата, яка вже нічого не додасть, крім деградації репутації.
Тестуй на живому семплі: Yahoo при активації FBL шле тестовий ARF-звіт — прожени його через парсер і переконайся, що resolve_token() дає правильний subscriber_id, а не мовчазний None.
Чекліст перед запуском
DKIM валідується (opendkim-testkey, dig TXT) — без нього Yahoo-заявку відхилять на порозі.
Три кабінети підтверджені: Yahoo Sender Hub, Microsoft JMRP+SNDS, postmaster.mail.ru (за потреби — Yandex postoffice).
Кожна відправка вшиває унікальний токен у Feedback-ID або VERP Return-Path — і токен у заголовках, не в тілі.
`abuse@` реально доставляється в парсер — перевір права pipe під користувачем fbl, а не root.
Парсер протестований на живому ARF від кожного провайдера, включно з тестовим звітом Yahoo.
Suppression блокує ВСІ майбутні відправки на адресу, спільно між кампаніями, ідемпотентно.
Моніторинг: SNDS complaint rate + власний лічильник FBL/добу з алертом на перевищення 0.1%.
Коли ця петля замкнена, complaint rate перестає бути чорною скринькою: кожна скарга за секунди перетворюється на рядок у suppression, а не на повільну ерозію репутації, яку ти помітиш через тиждень у Postmaster. Саме на такій самоочисній інфраструктурі тримається доставка на evilmail.pro — не на здогадках про те, чому просів inbox, а на конкретному списку адрес, які більше не отримають від тебе жодного листа.