О почте

2018-09-15

Бывает так.

Где-то на выделенном сервере работает тщательно настроенный Postfix. Через него ваше приложение, запущенное на этом же сервере, отправляет письма.

И SPF запись настроена. Она говорит, что с IP адреса нашего сервера действительно разрешается отправлять письма от нашего домена.

$ dig +noall +question +answer txt example.ru
;example.ru.              IN      TXT
example.ru.       28800   IN      TXT     "v=spf1 +a +mx include:_spf.yandex.net ~all"

И DKIM настроен. Письма подписываются, а ключ для проверки подписи тоже лежит в DNS.

$ dig +noall +question +answer txt mail._domainkey.example.ru
;mail._domainkey.example.ru. IN   TXT
mail._domainkey.example.ru. 28800 IN TXT  "v=DKIM1;k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTFcJLY5SlBNwtTqCHx5VHZZBnap4Z75T9Jb6g/JpNcwu3sMdBPmt8zQsxNflBXmovlBzowa4rAwu0MCk1HgZHt+5Ohm+qRscXTrP19XAcV+DA6ZVXekRNwoY7K+jwn3VJaUpEn3BK171M3gUPQ1G4sRDwh0A+S5ZEetH7V3SjmwIDAQAB;"

И даже все предыдущие письма, которые мы сами себе отправляли в Gmail, содержат заголовки, подтверждающие, что все проверки проходят успешно.

Authentication-Results: mx.google.com;
 dkim=pass header.i=@example.ru;
 spf=pass (google.com: domain of sender@example.ru designates 1.2.3.4 as permitted sender)
 smtp.mailfrom=sender@example.ru

Но вот в один прекрасный день мы видим в логах Postfix вот такое:

421-4.7.0 Our system has detected an unusual rate of unsolicited mail originating from your IP address. To protect our users from spam, mail sent from your IP address has been temporarily rate limited. Please visit https://support.google.com/mail/?p=UnsolicitedRateLimitError to review our Bulk Email Senders Guidelines. gsmtp (in reply to end of DATA command)

Google отказывается (временно) принимать письма, адресованные пользователям Gmail, когда они отправляются с нашего сервера.

Ну да, мы слали подтверждения регистрации. Да, это очень похожие письма. Да, это были десятки похожих писем. Но отправлялись они не все скопом, а по мере регистрации пользователей.

Что мы можем сделать ещё, чтобы удовлетворить Google? Давайте внимательно почитаем, что нам предлагают по указанной ссылке.

Gmail

Читаем внимательно, обращая внимание на каждый пункт.

Используйте Postmaster Tools.

Теоретически, Postmaster Tools — это такая веб консолька, где вы видите статистику получения почты Гуглом из вашего домена, и можете увидеть истинную причину ошибки. На практике я им не пользовался. Потому что там было пусто. Видимо, сильно мало писем мы рассылаем, чтобы там была хоть какая-то статистика.

Всегда отправляйте письма определенной категории с одного адреса.

Ну как бы у нас одна категория: письма подтверждения регистрации. И отправляются с одного адреса.

Не смешивайте разнотипный контент в одном сообщении.

Не такие уж и большие у нас письма, чтобы там появилось более одного типа контента.

Отправляйте сообщения с одного IP-адреса.

Сервер у нас один, так что IP адрес тоже один.

Убедитесь, что для ваших IP-адресов существуют действительные обратные записи DNS, указывающие на ваш домен.

Уже теплее.

DNS, как вы знаете, предназначен для преобразования символических (доменных) имён, типа "gmail.com", в IP адреса, типа "216.58.207.37" или "2a00:1450:4001:821::2005".

$ dig +noall +question +answer a gmail.com
;gmail.com.                     IN      A
gmail.com.              260     IN      A       216.58.207.37
$ dig +noall +question +answer aaaa gmail.com
;gmail.com.                     IN      AAAA
gmail.com.              55      IN      AAAA    2a00:1450:4001:821::2005

Но существует и обратное преобразование. IP адресу может быть сопоставлено некоторое каноничное доменное имя.

$ dig +noall +question +answer -x 216.58.207.37
;37.207.58.216.in-addr.arpa.    IN      PTR
37.207.58.216.in-addr.arpa. 86378 IN    PTR     fra16s24-in-f5.1e100.net.
$ dig +noall +question +answer -x 2a00:1450:4001:821::2005
;5.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.1.2.8.0.1.0.0.4.0.5.4.1.0.0.a.2.ip6.arpa. IN PTR
5.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.1.2.8.0.1.0.0.4.0.5.4.1.0.0.a.2.ip6.arpa. 86400 IN PTR fra16s20-in-x05.1e100.net.

Как видите, это DNS записи типа PTR в поддоменах in-addr.arpa. и ip6.arpa.. Из IP адреса там формируется доменное имя задом напёред.

Если что, домен 1e100.net, принадлежит Гуглу.

От нас требуется, чтобы обратная зона IP адреса нашего сервера, во-первых, существовала, и во-вторых, соответствовала нашему домену, с которого мы отправляем почту.

Обратная зона неразрывно связана с IP адресом. А значит, изменить её можно там, где вам выдали IP адрес. То есть, у хостера. Ищите где-нибудь в панельке управления сервером, где поменять обратную зону.

Reverse DNS settings

Раньше бывали почтовые сервера, которые не принимали письма с IP адресов, если обратная зона не соответствовала домену отправителя. Подобную проверку и сейчас можно включить в Postfix. Google, вроде, не настолько жесток. Но вполне очевидно, что правильная обратная зона улучшает репутацию сервера. Ведь наличие обратной зоны говорит о том, что это не какой-то домашний сервер с динамическим IP адресом, а честный оплаченный хост у приличного хостера.

Reverse DNS Check

Используйте во всех письмах массовой рассылки один и тот же адрес в поле "От:".

Ну мы так и делаем.

Подписывайте сообщения ключом DKIM. Gmail принимает ключи длиной не менее 1024 бит.

Это мы тщательно настроили в прошлый раз.

Опубликуйте запись SPF.

Есть такая запись.

Опубликуйте политику DMARC.

А вот это мы поленились сделать. Кажется, пришла пора каждому приличному почтовому домену, помимо SPF и DKIM, иметь ещё и DMARC.

В простейшем случае хватит и такого:

$ dig +noall +question +answer txt _dmarc.example.ru
;_dmarc.example.ru.       IN      TXT
_dmarc.example.ru. 28800  IN      TXT     "v=DMARC1;p=none"

Мол, про DMARC мы знаем, вот вам эта грешная политика, но ничего специального не хотим, отвалите. Главное, чтобы нужная TXT запись была.

Если вы уверены, что SPF и DKIM работают правильно, и хотите получать хоть какие-то сведения о том, кто шлёт почту от вашего домена, имеет смысл усложнить до "v=DMARC1;p=reject;pct=100;rua=mailto:postmaster@example.ru". Тут, во-первых, письма с неправильным SPF или DKIM будут отбрасываться, а во-вторых, сводная статистика по письмам с вашего домена будет присылаться на указанный емейл. Там приходят зазипованные XML, которые имеет смысл автоматически парсить и где-то диаграммки рисовать. В принципе, это всё уже автоматизировано.

DKIM, SPF, DMARC

У IP-адреса отправителя должна быть запись PTR для выполнения обратного запроса DNS. Необходимо, чтобы он совпадал с IP-адресом, который получен путем прямого преобразования доменного имени, указанного в записи PTR.

Ага. Значит, нужно пойти чуть глубже, чтобы доменное имя обратной зоны IP адреса нашего сервера резолвилось в тот же IP адрес.

$ dig +noall +question +answer a gmail.com
;gmail.com.                     IN      A
gmail.com.              147     IN      A       216.58.207.69
$ dig +noall +question +answer -x 216.58.207.69
;69.207.58.216.in-addr.arpa.    IN      PTR
69.207.58.216.in-addr.arpa. 82607 IN    PTR     fra16s25-in-f5.1e100.net.
$ dig +noall +question +answer fra16s25-in-f5.1e100.net.
;fra16s25-in-f5.1e100.net.      IN      A
fra16s25-in-f5.1e100.net. 86400 IN      A       216.58.207.69

Это требование слабее предыдущего упоминания обратной зоны. Приличные провайдеры заводят домен и обратную зону даже для динамических IP адресов.

$ dig +noall +question +answer -x 188.232.179.78
;78.179.232.188.in-addr.arpa.   IN      PTR
78.179.232.188.in-addr.arpa. 2572 IN    PTR     dynamicip-188-232-179-78.pppoe.omsk.ertelecom.ru.
$ dig +noall +question +answer dynamicip-188-232-179-78.pppoe.omsk.ertelecom.ru
;dynamicip-188-232-179-78.pppoe.omsk.ertelecom.ru. IN A

Упс. Или нет.

Reverse DNS

Домен отправителя должен пройти проверку SPF или DKIM.

Да. Уже да.

Чтобы получатель мог быстро отказаться от подписки, не покидая Gmail, мы настоятельно рекомендуем добавить заголовок List-Unsubscribe.

Упоминаются два RFC. RFC 2369 описывает List-* заголовки писем, в частности, заголовок List-Unsubscribe. RFC 8058 описывает заголовок List-Unsubscribe-Post.

Теперь понятно, как работают эти ссылки "отписаться" в Gmail. Если вы делаете рассылки, то включите эти заголовки в ваши письма, и Google будет лучше их воспринимать. А у пользователей будет возможность быстро отписаться от рассылки. Вам будет приходить HTTP POST запрос.

List-Unsubscribe: <https://example.com/unsubscribe.html/opaque123456789>
List-Unsubscribe-Post: List-Unsubscribe=One-Click

Но вообще-то у нас не рассылки, а уведомления.

List-Unsubsribe

С помощью поля заголовка "Precedence: bulk" обозначена массовая рассылка.

Precedence — это нестандартный заголовок. Он пару раз упоминался в довольно старых RFC как выходящий из употребления, и в основном использовался для предотвращения зацикливания автоматических ответов в списках рассылки. А вот эта вот рекомендация использовать Precedence: bulk — уникальная для современного Gmail.

Чёрт его знает, как Gmail обрабатывает этот заголовок. Но, вероятно, если вы рассылаете много похожих писем, стоит этот заголовок выставить. Не жалко.

No Spam

Итак. Чтобы уменьшить вероятность проблем с Gmail (и другими получателями), нужно:

  • Иметь валидную SPF запись в домене.
  • Настроить и использовать DKIM.
  • Иметь хоть какую-нибудь политику DMARC для домена.
  • Определить обратную зону для IP вашего сервера. Убедиться, что домен обратной зоны снова резолвится в IP сервера.
  • Если вы действительно делаете рассылку, добавить заголовки List-Unsubscribe и List-Unsubscribe-Post. Дайте пользователю возможность быстро отписаться.
  • Если вы рассылаете много похожих писем, добавить заголовок Precedence: bulk.
  • Следить за заголовками From, To, Return-Path, Reply-To. Они должны отражать действительность.
  • Следить за телом сообщений, не забывайте включать текстовую версию, помимо HTML.
  • Быть честными с пользователями, пишите в письмах только то, что нужно, не надо рекламы.

Успехов.