Разборы

Письма с сайта попадают в спам, хотя SPF настроен: DKIM, PTR и HELO

Письма с сайта или из 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, обратная запись IPIP -> 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.

Список для проверки

  1. В Authentication-Results все три pass?
  2. Ключ селектора из header.s опубликован в DNS?
  3. PTR исходящего IP указывает на имя, у которого есть A-запись на этот же IP?
  4. Сервер представляется этим же именем?
  5. В DMARC стоит adkim=r, а не строгий adkim=s?

Если письма с вашего сайта не доходят до клиентов, пришлите мне заголовки одного письма из спама. По ним обычно сразу видно, какой из пунктов не выполнен.

Похожая проблема на вашем сайте? Напишите в Telegram или оставьте заявку.