Письма с сайта или из CRM уходят в спам, хотя SPF настроен и даже DMARC есть. Обычно не хватает одного из двух: подпись DKIM не проверяется, потому что в DNS нет ключа нужного селектора, или у сервера не сходятся обратная запись IP и имя, которым он представляется. В разобранном случае после обеих правок оценка на mail-tester выросла с 4,9 до 9,7 из 10.
С чего начать: заголовки письма
Откройте письмо из спама и посмотрите оригинал. В Gmail это "Показать оригинал", в Яндексе "Свойства письма". Нужна строка Authentication-Results, ее добавляет сервер получателя:
spf=pass dmarc=pass dkim=permerror (no key for signature) header.s=mail
header.s это селектор, которым подписано письмо. dkim=permerror (no key for signature) значит, что получатель пошел за ключом по адресу mail._domainkey.ваш-домен и не нашел там записи.
Часть первая: селектор DKIM
У одного домена может быть несколько ключей DKIM одновременно, и это нормально. Яндекс 360 подписывает письма из веб-почты своим селектором, а сервер сайта или коробочного Битрикс24 своим. Получатель берет тот селектор, который указан в подписи письма, и ищет ровно его ключ.
Отсюда правило: у каждого источника писем должен быть свой опубликованный ключ. Типичная картина: ключ Яндекса в DNS есть, а ключа сервера, с которого уходят письма сайта, нет.
Проверить, опубликован ли ключ:
dig +short TXT mail._domainkey.example.ru @1.1.1.1
Пустой ответ значит, что ключа нет.
Где взять ключ на сервере
На BitrixVM письма уходят так: PHP -> msmtp -> Postfix -> OpenDKIM ставит подпись -> наружу. Нужные файлы:
/etc/opendkim/SigningTable- какой адрес каким селектором подписывать;/etc/opendkim/KeyTable- где лежит закрытый ключ селектора;/etc/opendkim/keys/<домен>.txt- готовая запись для DNS.
cat /etc/opendkim/SigningTable /etc/opendkim/KeyTable
cat /etc/opendkim/keys/example.ru.txt
Содержимое .txt публикуется в DNS как TXT-запись <селектор>._domainkey. Ключ 2048 бит длиннее 255 символов. Большинство DNS-панелей принимают его одной строкой и сами делят на части. Если панель не принимает, вставьте в двухстрочном виде, как в файле.
На серверах с Exim4 и FastPanel ключ лежит в /etc/exim4/dkim/, селектор по умолчанию dkim.
Часть вторая: PTR и HELO
Бывает, что все три проверки проходят (spf=pass, dkim=pass, dmarc=pass), а письма все равно в спаме. Тогда дело в том, как представляется сам сервер. Должны сходиться три вещи:
| Что | Пример | Кто настраивает |
|---|---|---|
| PTR, обратная запись IP | IP -> mail.example.ru | хостер, владелец IP |
| A-запись | mail.example.ru -> тот же IP | вы, в DNS домена |
| HELO, имя сервера при отправке | mail.example.ru | настройка почтового сервера |
Google с 2024 года требует PTR от всех отправителей, SpamAssassin добавляет штраф RDNS_NONE, Яндекс пишет в заголовках unknown [IP].
Проверка:
dig +short -x 203.0.113.10 @1.1.1.1 # PTR
dig +short mail.example.ru @1.1.1.1 # A-запись
postconf myhostname # HELO в Postfix
Подводные камни
- PTR ставит хостер, а не владелец домена. Обычно в личном кабинете хостинга есть поле для обратной записи, иначе пишите в поддержку.
- Исходящий IP может отличаться от IP сайта, если у хостера NAT. Какой адрес видят получатели, смотрите в заголовке
Receivedдоставленного письма. PTR и A-запись делайте на него. - Порядок важен: сначала A-запись, потом PTR, и только потом меняйте имя сервера. Иначе сервер начнет представляться именем, которое еще не существует.
Смена имени в Postfix:
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak-$(date +%F)
postconf -e 'myhostname = mail.example.ru'
postfix check && systemctl reload postfix
Проверка результата
Отправьте письмо с сервера на адрес, который выдаст mail-tester.com, и откройте отчет. Тему пишите латиницей: кириллица в письме без кодировки ловит ложный штраф самого теста.
printf 'From: box@example.ru\nTo: test-xxxx@srv1.mail-tester.com\nSubject: Deliverability test\n\nBody text.\n' | sendmail -f box@example.ru test-xxxx@srv1.mail-tester.com
Чего эти правки не дают сразу
Репутация домена и IP у Gmail и Яндекса восстанавливается 2-4 недели после исправлений. Следить удобно в Google Postmaster Tools и Постмастере Яндекса. Для массовых рассылок нужен еще заголовок List-Unsubscribe, такие письма лучше отправлять через модуль рассылок, а не как письма из CRM.
Список для проверки
- В
Authentication-Resultsвсе триpass? - Ключ селектора из
header.sопубликован в DNS? - PTR исходящего IP указывает на имя, у которого есть A-запись на этот же IP?
- Сервер представляется этим же именем?
- В DMARC стоит
adkim=r, а не строгийadkim=s?
Если письма с вашего сайта не доходят до клиентов, пришлите мне заголовки одного письма из спама. По ним обычно сразу видно, какой из пунктов не выполнен.