Категория отказа в учёте — настраиваемая, а не вендорская

критично

bounce category patterns
Вендорский словарь категорий можно дополнить своим

В каждой записи учёта об отказе есть поле bounceCat — категория. До этого раздела руководства она выглядит закрытым словарём из семнадцати значений: bad-mailbox, quota-issues, spam-related и прочие. Это не так.

Категорию выбирают правила, и правила можно писать свои. Блок <bounce-category-patterns> без имени разбирается раньше вендорских умолчаний из файла умолчаний; именованный блок можно привязать к конкретному приёмнику, и он разбирается раньше обоих. Порядок такой: правила приёмника, потом свои общие, потом вендорские.

Правило состоит из трёх частей. Необязательный этап сессии, регулярное выражение и имя категории: rcpt-to /invalid recipient/ recipient-related. Этап сейчас единственный — rcpt-to, он ограничивает совпадение ответами на команду с адресом получателя. Без этапа совпадают ответы с любого этапа.

Свои имена категорий разрешены прямо. Словарь не закрыт: можно завести категорию, которой у вендора нет, и она попадёт в учёт как есть. Именно это и делает механизм ценным — классификация переезжает туда, где приходит ответ, до записи в учёт.

Совпадение работает так же, как в списках образцов SMTP — руководство отсылает к <smtp-pattern-list> за подробностями.

Главная ловушка — думать, что вендорская категория означает то, что написано в её имени. Категории назначаются по тексту ответа приёмника, а тексты у всех разные и меняются. no-answer-from-host по определению вендора — «хост не ответил после подключения, ошибка 4xx или 5xx»; это молчание сервера, а не отсутствие адреса. Кто читает такую категорию как «адреса нет», принимает решение об адресе по состоянию чужого сервера.
Что делает Хаб. Пишет безымянный <bounce-category-patterns> в шаблоне политик — набор из Protosender, несколько десятков образцов, — но с вендорскими именами категорий. Дальше Хаб отображает категории на свою ось «жёсткий или мягкий»: жёсткий значит «адреса не существует», и по нему адрес попадает в чёрный список; мягкий значит «ящик есть, просто письмо сейчас не приняли», и по нему сбавляют темп.

Список жёстких категорий один на весь Хаб — bad-mailbox, inactive-mailbox, bad-domain (PmtaEventNormalizer::HARD_CATEGORIES). Раньше он лежал копиями в четырёх местах и расходился ровно на no-answer-from-host; теперь эта категория мягкая везде.

Этот механизм — способ убрать перевод целиком. Если правила писать самим, узел может писать в учёт сразу нашу категорию, взятую из слов приёмника, а не вендорскую, которую потом надо истолковать. Один шаг между отказом и решением об адресе исчезает.

Рекомендуемые значения

Что стоит завести своими правилами:

Категория Что ловить Зачем
«адреса нет» no such user, unknown recipient, 5.1.1 на этапе получателя прямое основание снять адрес
«ящик переполнен» mailbox full, over quota ящик жив, адрес снимать нельзя
«придержали за репутацию» spam, blocked, spamhaus не про адрес вовсе — про нас
«сервер молчит» таймауты и обрывы не про адрес и не про репутацию

Этап rcpt-to стоит указывать почти всегда там, где речь об адресе. Ответ «нет такого пользователя», сказанный на этапе данных, относится к письму целиком, а не к одному получателю, и трактовать его как приговор адресу нельзя.

Своё имя категории лучше вендорского, когда смысл не совпадает с вендорским ни с одной из семнадцати: собственное имя честнее, чем натянутое чужое.

Таблица категорий и совет про этап получателя — наши. Из руководства здесь порядок разбора трёх уровней правил, форма записи правила, единственный доступный этап и прямое разрешение своих имён категорий.
Пример в конфигурации
# свои правила разбираются раньше вендорских
<bounce-category-patterns>
    /mailbox +(is +)?full/ quota-issues
    rcpt-to /[45]\.\d+\.\d+/ recipient-related</bounce-category-patterns>
<bounce-category-patterns custom>
    /no longer available/ quota-issues
</bounce-category-patterns>
<domain hotmail.com>
    bounce-category-patterns custom
</domain>
Пример руководства. Выделенная строка ограничена этапом получателя — она совпадёт только с ответом на команду с адресом. Именованный блок ниже привязан к одному приёмнику и разбирается раньше общего.
жёлтым — — имена директив, голубым — блоки. Так же они подсвечены и в тексте карточки.
▲

Типичные ошибки и проблемы

что делают не так и чем это кончается3 ошибки▶

Читают имя категории как утверждение об адресе

§ 12

Чем чреватоКатегорию назначил образец по тексту ответа приёмника. Имя no-answer-from-host означает «сервер не ответил», а не «адреса нет»: ящик может быть жив, просто хост промолчал. Решение снять адрес по такой категории удаляет живой контакт.
Как заметитьБаза адресов худеет после дней, когда у приёмника были неполадки, а не после чистки по настоящим отказам.
Как правильноСвериться с определением категории у вендора, прежде чем строить на ней решение. Что означает «адреса нет», лучше определить своими правилами, а не догадкой об имени.

Пишут правило без этапа получателя

§ 11.7.1

Чем чреватоБез этапа совпадают ответы с любого места сессии. Ответ «нет такого пользователя», сказанный на этапе данных, относится ко всему письму, а его засчитывают одному адресу.
Как заметитьВ категорию «адреса нет» попадают письма, отправленные на заведомо живые ящики.
Как правильноСтавить rcpt-to во всех правилах, где категория говорит об отдельном адресе. Это единственный доступный этап, и он для того и нужен.

Заводят правило и ждут, что оно перекроет вендорское

§ 11.7.1

Чем чреватоПерекроет только при более раннем разборе. Безымянный блок идёт раньше вендорского, именованный — раньше обоих, но лишь для тех приёмников, у которых на него есть ссылка. Правило в именованном блоке без ссылки не разбирается вовсе.
Как заметитьКатегория в учёте по-прежнему вендорская, хотя своё правило написано и подходит по тексту.
Как правильноПроверить, есть ли у приёмника строка со ссылкой на список. Общие правила писать в блок без имени — он действует на всех.
Совместимость
PowerMTA 6.0
описана в руководстве этой версии · платформа: любая
С какой версии директива доступна, вендор указывает не для всех — здесь пометки нет. Имя встречается и в издании руководства 5.0.
Наследование
Наследуется не сам список, а ссылка на него: строка bounce-category-patterns в блоке приёмника сливается по обычному правилу — от общего образца к точному, и по уровням узел, пул, адрес отправки. Сами блоки правил живут в корне файла. Порядок разбора при этом фиксированный и наследованию не подчиняется: сначала именованный список приёмника, потом безымянный общий, потом вендорский из файла умолчаний.
⇄

Связанные записи

3 связи

Как проверить на узле
Смотреть надо не конфигурацию, а то, что реально попало в учёт:
pmtastats bounce-categories --bounceCat all /var/log/pmta/acct-*.csv
grep -n -A6 '^<bounce-category-patterns' /etc/pmta/config
Первая команда печатает разбивку отказов по категориям — по ней сразу видно, попадают ли письма в задуманные категории или всё сваливается в other. Вторая покажет, какие правила вообще заведены; пустой вывод означает, что действуют только вендорские.
В Хабе
Цена ошибки
обратимо: вредит, пока стоит
Сценарии
Классификация отказов · Подавление адресов
Важность
критично