У клиента-медклиники на Тверской письма падали в спам у половины контрагентов. Записи в DNS были образцовые: один SPF, DKIM подписывался, DMARC настроен, PTR совпадал. Я два часа искал ошибку в зоне и не нашёл, потому что искал не там. Разбираю случай целиком — от вводящего в заблуждение сообщения в логе до истории с рассылкой, которая всё это устроила.
Письма Zimbra улетают в спам при валидных SPF, DKIM и DMARC
«Мы всё настроили правильно, а нас всё равно не читают»
Эта заявка приходит примерно так. Контрагент говорит: ваши письма у нас в спаме. Вы идёте проверять — и находите, что всё в порядке. SPF есть. DKIM подписывается. DMARC настроен. Обратная зона совпадает. Онлайн-проверялка ставит десять из десяти.
А письма в спаме.
Дальше человек обычно идёт по второму кругу тех же проверок, потому что больше идти некуда. Проверялка снова показывает десять из десяти. Ощущение при этом такое, будто вам врут все сразу: и получатель, и собственные инструменты.
Дальше начинается самое вредное для нервов: вы правите то, что и так работало. Меняете политику DMARC, добавляете механизмы в SPF, перевыпускаете ключ подписи. Каждое изменение приживается в зоне часами, эффекта нет, и через неделю вы уже не помните исходную конфигурацию.
Я прошёл этот круг с клиникой на Тверской в январе 2025-го и потратил два часа впустую. Проблема оказалась в двух местах, о которых я не думал вообще: в файле на самом сервере, который никто не открывал с момента установки, и в том, что происходило с их адресом за полгода до моего приезда.
Клиника, 31 место, и первый честный прогон
Многопрофильная клиника на Тверской, 31 рабочее место, три врача-совместителя с внешних адресов. Zimbra 9 Open Source на арендованном сервере, свой белый адрес, свой домен. Жалоба поступила от страховой компании: направления и акты сверки регулярно оказываются в спаме, и никто их там не ищет.
Первым делом я прогнал цепочку целиком. Не отдельные записи, а именно цепочку: MX ведёт на имя, имя разворачивается в адрес, у адреса есть обратная запись, и она разворачивается обратно в то же имя.
$ dig +short MX klinika.example.ru
10 mail.klinika.example.ru.
$ dig +short A mail.klinika.example.ru
203.0.113.44
$ dig -x 203.0.113.44 +short
mail.klinika.example.ru.
$ dig +short A mail.klinika.example.ru
203.0.113.44
Кольцо замкнулось. Это первое, что я проверяю на любой жалобе про доставляемость, и это же первое, что чаще всего разомкнуто у клиентов: обратная запись либо не заказана у хостера, либо ведёт на техническое имя вида server44.datacenter.tld, а оно ни во что обратно не разворачивается.
Тут было правильно. DKIM тоже подписывался — я проверил не в DNS, а в самом каталоге Zimbra, где ключ и живёт:
$ /opt/zimbra/libexec/zmdkimkeyutil -q -d klinika.example.ru
DKIM Domain: klinika.example.ru
DKIM Selector: 8A2F31C4-7B5D-11EC-9C2E-0050569A1F03
DKIM Public signature:
8A2F31C4-7B5D-11EC-9C2E-0050569A1F03._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv1..." )
Селектор совпадал с опубликованным в зоне посимвольно. Ключ на 2048 бит — так и должно быть, начиная с версии 8.7 утилита генерирует именно такой, а публичную часть в DNS всё равно нужно класть руками. Положили в 2022-м, лежит.
Ложный след: «public key: DNS error: no nameservers»
А потом я открыл журнал amavis и увидел там строку, из-за которой два часа искал не то:
$ grep -i dkim /opt/zimbra/log/amavis.log | tail -2
(01423-04) DKIM signature: d=klinika.example.ru s=8A2F31C4 c=relaxed/relaxed
a=rsa-sha256 ... public key: DNS error: no nameservers
(01423-04) Passed SPAM {RelayedInternal}, [10.10.0.9]:41022
Читается однозначно: сервер не может получить публичный ключ из DNS. Я пошёл проверять зону — с четырёх разных резолверов, включая публичные. Ключ отдавался отовсюду. Проверил длину TXT-записи, разбиение на части, кавычки, лишние пробелы, регистр селектора. Всё было корректно.
Час я потратил на подозрение, что регистратор режет длинную запись. Ещё час — на то, чтобы убедиться, что не режет.
Сообщение врёт. Точнее, оно говорит правду о своём непосредственном затруднении, но не о причине. «Нет серверов имён» здесь означает не «в DNS нет записи», а «мне не у кого спросить»:
$ cat /etc/resolv.conf
# Generated by NetworkManager
search klinika.local
Ни одной строки nameserver. Пусто. Сервер прекрасно резолвил имена — через локальный кэширующий сервис, настроенный совсем другим способом, — но библиотека, через которую проверяются подписи, ходит именно сюда. И не находит ничего.
Лечится одной строкой, применяется мгновенно, перезапуска почты не требует. Практический эффект: внутренние письма между сотрудниками перестали помечаться как спам. Проблема со страховой при этом никуда не делась, и это меня привело к следующей находке.
Две SPF-записи: молчаливый саботаж
Онлайн-проверялки, которыми пользуются админы, обычно показывают первую найденную запись SPF и радостно рисуют зелёную галочку. Я запросил зону напрямую и посчитал строки:
$ dig +short TXT klinika.example.ru | grep -i spf
"v=spf1 a mx ip4:203.0.113.44 ~all"
"v=spf1 include:_spf.rassylka-service.ru -all"
Две. Вторую добавили в июле 2024-го, когда клиника запускала рассылку об акциях по базе пациентов, — сервис рассылок попросил, админ добавил, старую не тронул.
По стандарту домен с двумя записями SPF считается ошибочно настроенным, и проверяющая сторона имеет полное право не проверять SPF вообще. На практике так и происходит: часть принимающих серверов даёт постоянную ошибку, часть — просто пропускает проверку. У фильтра, который считает баллы, из-за этого выпадает целый блок положительных признаков — письмо не получает плюсов за пройденный SPF и приезжает к порогу с худшим счётом, чем должно.
Никакой аварии. Никаких сообщений об ошибке. Просто у вашей почты тише голос.
Правильно тут одна запись, в которую включено всё:
klinika.example.ru. IN TXT "v=spf1 a mx ip4:203.0.113.44 include:_spf.rassylka-service.ru ~all"
И заодно совет, который я даю всем: считайте механизмы. Каждый include разворачивается в запросы, и лимит на количество обращений при проверке равен десяти. Три сервиса рассылок, антиспам-шлюз и облачная бухгалтерия — и вы за лимитом, а поведение снова становится непредсказуемым.
Проверьте у себя за две минуты
Четыре команды. Первые две — с любой машины, вторые две — на почтовом сервере.
dig +short TXT example.ru | grep -ci "v=spf1"
dig -x $(dig +short A mail.example.ru) +short
cat /etc/resolv.conf | grep -c nameserver
/opt/zimbra/libexec/zmdkimkeyutil -q -d example.ru
Как читать:
| Что увидели | Что это значит | Когда действовать |
|---|---|---|
| Первая команда вернула 1 | SPF единственный — так и должно быть | Ничего не трогать |
| Первая команда вернула 2 и больше | Проверка SPF у части получателей не выполняется вовсе | Сегодня |
| Первая команда вернула 0 | SPF нет — вы в спаме у всех крупных провайдеров | Немедленно |
| Вторая команда вернула имя хостера, а не ваше | Обратная запись не совпадает с прямой, цепочка разомкнута | На этой неделе |
| Третья команда вернула 0 | Проверка подписей на сервере не работает, в логе будет вводящая в заблуждение ошибка про серверы имён | Сегодня |
| Селектор из четвёртой команды не совпадает с опубликованным | Подпись ставится ключом, которого нет в зоне | Немедленно |
Три минуты вместе с чтением. У примерно половины серверов, которые я смотрю впервые, что-то из этого списка не сходится.
Репутация: то, что весит больше всех записей
После правки resolv.conf и склейки SPF стало заметно лучше — но не со страховой. Их шлюз продолжал отправлять письма клиники в спам стабильно. Я проверил адрес по спискам и получил ответ:
$ dig +short 44.113.0.203.dnsbl-1.uceprotect.net
127.0.0.2
$ dig +short 44.113.0.203.zen.spamhaus.org
(пусто)
Адрес числился в списке первого уровня — том, куда попадают за жалобы получателей. У крупных операторов он влияет мало, а вот корпоративные шлюзы вроде того, что стоял у страховой, читают его буквально.
История выяснилась за пять минут разговора. В июле 2024-го клиника разослала по базе пациентов приглашение на акцию — 4200 адресов, одним заходом, со своего почтового сервера. Восемнадцать процентов адресов оказались мёртвыми, тридцать четыре человека нажали кнопку «это спам». Для лежалой базы, которую два года не чистили, это нормальные цифры. Для репутации адреса, с которого ходит вся рабочая переписка, — приговор на несколько месяцев.
Отдельно скажу вслух, раз речь о клинике: рассылка рекламы по базе пациентов — это ещё и вопрос согласий на обработку персональных данных. Мы это тоже обсудили, но это уже не моя часть работы.
Здесь я и допустил свою ошибку. Предложил самое очевидное — сменить адрес отправки. Взяли новый белый адрес, заказали обратную запись, переключили. Стало хуже: девять дней крупные провайдеры притормаживали почту с адреса без истории, доставка растянулась до получаса, а корпоративный шлюз страховой встретил новичка ровно так же настороженно. Мы вернулись на прежний адрес и пошли скучным путём.
Что мы сделали и в каком порядке
Порядок здесь важнее содержания: пока техника не приведена в порядок, за репутацию браться бессмысленно — вас исключат из списка и внесут обратно.
- Первое. Прописали серверы имён в
/etc/resolv.conf. Заняло минуту, убрало ложные пометки на внутренней почте. - Второе. Свели два SPF в один, проверили число обращений при развороте — уложились в пять из десяти допустимых.
- Третье. Вынесли всю массовую рассылку на отдельный сервис и отдельный поддомен. Рабочая переписка и маркетинг больше не делят один адрес — это единственная мера, которая гарантированно не даёт истории повториться.
- Четвёртое. Написали в список и остановили рассылку совсем. У этого уровня блокировки бесплатного «исключите нас» нет: запись просто истекает сама, если новых срабатываний не приходит. Наша истекла через шесть дней после того, как рассылка замолчала.
- Пятое. Ужесточили DMARC до карантина только после того, как две недели смотрели отчёты и убедились, что вся легитимная почта проходит проверки.
_dmarc.klinika.example.ru. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@klinika.example.ru; fo=1"
# через две недели наблюдений:
_dmarc.klinika.example.ru. IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@klinika.example.ru"
Последовательность с DMARC принципиальна. Политика жёстче наблюдения, включённая до того, как вы посмотрели отчёты, — это способ самостоятельно уронить себе доставляемость. У меня был клиент, который поставил отклонение сразу и полторы недели не получал ничего от собственной облачной бухгалтерии, потому что она отправляла от его домена со своих адресов.
Итог, сроки и во что это обошлось
Сроки по этой истории такие. Технические правки — 3 часа работы. Возврат репутации — шесть недель, из которых девять дней я сам же и потерял на неудачную смену адреса.
| Показатель | Январь 2025 | Март 2025 |
|---|---|---|
| Записей SPF у домена | 2 | 1 |
| Строк nameserver в resolv.conf | 0 | 2 |
| Адрес в списках по жалобам | числится в одном | чист |
| Писем в спаме у страховой | примерно каждое второе | 0 за месяц наблюдений |
| Внутренняя почта с пометкой спама | около 40 писем в день | 0 |
Цена бездействия у клиники считалась просто, потому что она была измеримой. За три месяца, пока проблему терпели, потерялись 12 направлений от страховой — каждое это пациент, который не пришёл. По их среднему чеку получилось около 180 тысяч рублей несостоявшихся приёмов. Плюс два акта сверки, найденных в спаме через полтора месяца, и связанная с этим задержка оплаты.
Против трёх часов работы и шести недель ожидания.
Главный вывод, который я увожу из каждого такого случая: правильные записи — это условие, а не гарантия. Их отсутствие вас точно утопит, но их наличие ничего не обещает, если с вашего адреса когда-то ушло четыре тысячи писем в холодную базу.
Если у вас похожая история — выполните четыре команды из раздела про двухминутную проверку и пришлите мне вывод вместе с именем домена. Отвечу, где именно рвётся: в записях, на самом сервере или в репутации адреса. Это три принципиально разных сценария, и лечатся они по-разному.
Частые вопросы
Онлайн-проверялка ставит нам десять из десяти. Разве этого мало?
Мало, и по двум причинам. Первая: такие сервисы обычно показывают первую найденную запись SPF и не считают их количество, а именно количество и ломает проверку у получателей. Вторая: они проверяют записи, а не поведение. Репутация адреса, история жалоб, объём и характер исходящего потока — ничего из этого внешний валидатор не видит. Поэтому идеальная оценка вполне уживается с письмами в спаме, и это не парадокс, а разные предметы измерения.
В логе ошибка про серверы имён, но DNS на сервере работает. Как так?
Резолвинг имён у операционной системы и проверка подписей — разные пути. Второй читает список серверов имён из системного файла напрямую, и если там пусто, он не пойдёт искать обходные варианты, а честно сообщит, что спрашивать не у кого. Формулировка при этом такая, что все идут проверять записи в зоне — я сам так и сделал и потерял на этом два часа. Проверяется одной строкой: посчитайте в файле строки со словом nameserver. Если ноль, вы нашли причину.
Нам нужна рассылка. Как её делать, чтобы не уронить рабочую почту?
Отдельный поддомен и отдельный отправляющий сервис. Не потому, что своими силами нельзя, а потому, что репутация считается по адресу отправки, и вы не хотите, чтобы реакция на маркетинг влияла на письма бухгалтерии. Практически: заводите домен третьего уровня, свой SPF и свой ключ подписи, шлёте через специализированный сервис, а корпоративный сервер оставляете только для переписки. Ещё чистите базу перед отправкой — восемнадцать процентов недоставленных адресов заметны принимающей стороне не меньше, чем жалобы.
Сколько времени восстанавливается репутация адреса?
По моему опыту от двух недель до трёх месяцев, и зависит это в основном от того, продолжается ли поток, который её испортил. Исключение из конкретного списка занимает несколько дней и делается по заявке, но само по себе оно мало что решает: принимающие стороны считают репутацию и по собственным данным, которые вы не увидите и на которые не подадите заявку. Единственный работающий рецепт — стабильный чистый поток и терпение. Смена адреса чаще ухудшает ситуацию: у нового адреса нет истории, и к нему относятся с подозрением недели полторы.
Стоит ли сразу ставить DMARC в режим отклонения?
Нет. Сначала режим наблюдения и сбор отчётов недели на две, чтобы увидеть все источники, которые шлют от вашего имени. Их всегда больше, чем помнят: облачная бухгалтерия, сервис заявок с сайта, CRM, чей-нибудь личный клиент с внешнего адреса. Только когда вы убедились, что каждый из них проходит проверки, переводите политику в карантин, а потом уже, при желании, в отклонение. Обратный порядок — самый быстрый способ отрезать себя от собственных сервисов, и обнаруживается это обычно на третий день по звонку бухгалтера.
Оставить комментарий