Я пытаюсь разобраться, как заставить Discourse очищать списки электронной почты, в частности, обрабатывать письма с ошибками доставки (bounce). Сайт использует частный SMTP-сервер для отправки писем, но адрес для получения ответов настроен на Gmail-аккаунт, к которому Discourse получает доступ по протоколу POP.
Таким образом, я вижу письма с ошибками доставки в панели управления «Полученные» (Received).
Discourse использует reply_key для связывания возвратов с отправленными письмами. Когда Discourse отправляет почту, он использует значение reply_by_email_address в качестве отправителя SMTP-оболочки.
Вам необходимо убедиться, что ваш reply_by_email_address включает {reply_key}, чтобы ваш экземпляр мог связывать возвраты с правильным отправленным письмом.
Например, здесь, на meta, это установлено как incoming+%{reply_key}@meta.discoursemail.com, и любое письмо, отправленное на этот адрес, будет доставлено в этот экземпляр.
Спасибо за ответ. К сожалению, мне пришлось отключить reply_key в ответе на письмо, так как наш почтовый релей-сервер не поддерживает адресацию с использованием символа +. Есть ли какой-то другой вариант?
Ваш почтовый сервер-ретранслятор не должен иметь значения, важно только конечный сервер, где находится почтовый ящик. Локальные части адресов электронной почты непрозрачны для любых промежуточных серверов.
Разве это не Gmail, как указано ниже:
Не уверен, что у нас есть другой механизм для надежного обнаружения возвратов писем.
Чтобы прояснить ситуацию: целевой SMTP-сервер домена, получающий отклонённое письмо, не распознаёт адресацию с символом +, поэтому он пересылает письма только на основе поля To на адрес Gmail, который Discourse обрабатывает через POP. Если поле To содержит reply_key, то такое письмо не будет переслано на учётную запись Gmail, используемую Discourse.
Следовательно, я не могу размещать reply_key в адресе электронной почты. Можно ли разместить его в другом месте? Например, в теме письма, в теле письма или где-либо ещё, где Discourse сможет его распознать и обработать?
Было бы очень полезно, если бы вы указали, какие именно настройки вы используете, даже если они слегка анонимизированы.
Также стоит рассмотреть возможность настройки параметра alternative_reply_by_email_addresses.
Я не думаю, что это возможно.
Если это возможно, для вашей конфигурации я рекомендую следующее:
установите параметр reply_by_email_address в значение inbound+%{reply_key}@forum.hostname
настройте почтовый сервер для приёма писем на домен forum.hostname и пересылки всех писем на the.gmail.account@gmail.com
В данном случае промежуточный почтовый сервер не должен понимать адресацию с символом плюс; ему достаточно просто пересылать все письма для этого домена.
Электронное письмо, отправленное с помощью Discourse, исходит с адреса discourse@xxx.com через выделенный SMTP-сервер домена, настроенный для Discourse (с использованием адреса домена Discourse).
При ответах или возврате писем (bounce) SMTP-сервер домена пересылает их на адрес discourse.xxxx@gmail.com. Этот SMTP-сервер домена не распознаёт адресацию с использованием символа +, поэтому, если включить reply_key в адрес ответа, письмо будет отброшено сервером домена. Я могу настроить правила только для пересылки отдельных/уникальных входящих адресов электронной почты.
Форум Discourse затем использует POP через Gmail для доступа к этим пересланным ответам/возвращённым письмам и их парсинга.
Я понимаю, что вы имеете в виду. К сожалению, из-за ограничений правил SMTP-сервера я не могу настроить пересылку для поддоменов; я могу настроить её только для уникальных идентификаторов адресов в поле «Кому».
Однако у меня есть уточнение — скорее, несоответствие в том, как, по-видимому, работает Discourse:
Когда пользователь отвечает на электронное письмо, связанное с постом, оно приходит корректно — ответы работают безупречно, даже если параметр {reply_key} явно нигде не настроен (см. скриншоты выше).
Однако, когда письмо возвращается (bounce), Discourse классифицирует его как Полученное (Received), а не как Возвращённое (Bounced).
В журналах ошибок видно, что какой-то компонент Discourse распознаёт это как возвращённое письмо (см. журнал ошибок в моём первом сообщении). Если какой-то компонент Discourse распознаёт это как возвращённое письмо, почему оно отображается в разделе Полученное, а не в разделе Возвращённое?
Так почему же ответ пользователя на пост обрабатывается Discourse корректно, а возвращённое письмо — нет (и, судя по всему, существует несоответствие между журналами ошибок и панелью управления для возвращённых писем)? Не упустил ли я что-то в конфигурации?
Я также пробовал настроить параметр «Ответ по адресу электронной почты» в Discourse как discourse.xxx+%{reply_to}@gmail.com, но при доставке письма Gmail, похоже, считает, что домен yyy.com (домен SMTP Discourse) пытается подделать домен Gmail, и в итоге помечает письмо как спам. Похоже, что установка домена для ответа, отличного от домена отправителя, вызывает сбои DMARC и SPF.
ARC-Authentication-Results: i=1; mx.google.com;
spf=softfail (google.com: domain of transitioning discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com does not designate y.y.y.y as permitted sender) smtp.mailfrom=discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com;
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yyy.com
Return-Path: <discussion.xxx+verp-b9c40db917ca04993dd3433cc9748518@gmail.com>
Вы отключили опцию «Найти связанные посты по ключу» (надеюсь, вы прочитали предупреждение), поэтому Discourse использует заголовок in-reply-to электронной почты для определения, к какой теме/посту должен относиться ответ.
Это невозможно сделать для отскочивших писем — Discourse должен знать конкретное сообщение, которое отскочило, и эта информация гарантированно содержится только в одном месте — в адресе поля To: (который берется из адреса envelope-from исходного сообщения).
Для этого, когда Discourse отправляет сообщение, он должен получать ответ на адрес, с которого оно было отправлено. Discourse ищет это в заголовке To: (а не в envelope-to).
подделывает домен gmail
Если вы хотите отправлять письма с адреса gmail, вам нужно делать это через их серверы. Но они этого не любят.
Похоже, вы не настроили DKIM для yyy.com; вам следует это сделать. Если вы всё настроите правильно, DMARC должен пройти успешно.
Да, он настроен, и письма, отправляемые через SMTP-сервер yyy.com, успешно проходят проверку SPF, DKIM и DMARC (по крайней мере, со страницы «Отправить тестовое письмо» в консоли администратора).
Проблема возникает, когда я указываю адрес Gmail в качестве reply_by_email_address вместо адреса домена yyy.com. Есть ли способ настроить это так, чтобы DMARC не сбрасывался при указании адреса Gmail в reply_by_email_address, при этом исходящий сервер остаётся yyy.com?
Не может ли он проанализировать остальное содержимое или вложения в письме с ошибкой доставки, чтобы извлечь эту информацию, если не может найти то, что нужно, в «очевидном» месте? Или, по крайней мере, предоставить в настройках опцию для этого с необходимыми предупреждениями о возможности подмены личности?
Согласование DMARC не проходит, поскольку в данной ситуации reply_by_email_address используется как адрес envelope-from.
Почти единственное, что гарантированно остаётся целым при отклонении письма, — это адрес.
Возможно, тема письма, но размещать там такую информацию было бы непрактично.
Я вижу, что некоторые системы включают оригинальное сообщение как вложение… теоретически возможно проверять отклонённые письма на наличие вложений для получения дополнительной информации, если они существуют.
Если я правильно понимаю, reply_by_email_address должен быть установлен в поле reply-to заголовка письма, отправляемого системой Discourse (с домена yyy.com). Таким образом, когда пользователь отвечает, он отвечает на адрес в поле reply-to (gmail.com), а не на исходный адрес (yyy.com). Следовательно, в ответном письме адрес в поле from должен быть адресом пользователя, а адрес в поле to — адресом gmail.com.
Почему reply_by_email_address используется как адрес в поле from?
Итак, по сути, reply_by_email_address используется в заголовке From, чтобы при возврате письма (bounce) оно возвращалось на этот адрес. Этот же адрес также устанавливается в заголовке Reply-To, если отправка ответов по электронной почте включена.
Таким образом, если моё понимание верно, то если в Discourse появится отдельная настройка (reply_to_email) для заголовка Reply-To, это решит проблему с неудачей DMARC. При этом при отправке в заголовке From будет использоваться домен yyy.com (взятый из reply_by_email_address), а в заголовке Reply-To — gmail.com (взятый из новой настройки reply_to_email). Если письмо вернётся, оно всё равно будет доставлено на адрес reply_by_email_address, но если пользователь ответит, ответ придёт на адрес reply_to_email.
Чтобы пройти проверку DMARC, должны совпадать либо SPF (который проверяет envelope-from в сочетании с IP-адресом отправителя), либо DKIM (который проверяет заголовок From и контрольные суммы сообщения) соответствие.
Получается, вся суть этой затеи — иметь «красивый» адрес reply-to, на который пользователи будут отвечать?
Вы хотите что-то вроде этого?
envelope-from: outgoing+12309847801923840923502389423@yyy.com
…
From: notifications@yyy.com
To: user@contoso.com
Reply-to: my_sweet_forum+12309847801923840923502389423@gmail.com
У вас должен быть именно такой envelope-from, иначе возвраты не будут работать.}
Да, всё верно. Идея в том, чтобы envelope-from отличался от reply-to.
Поскольку домен envelope-from совпадает с IP-адресом отправителя, SPF-проверка должна пройти успешно. В то же время ответы будут отправляться на Gmail для обработки, а если письмо отскочит, оно вернётся на сервер исходного домена, который затем перешлёт уведомление об ошибке обратно в почтовый ящик Gmail.
На самом деле это будет выглядеть так:
envelope-from: outgoing@yyy.com
…
From: notifications@yyy.com
To: user@contoso.com
Reply-to: my_sweet_forum+12309847801923840923502389423@gmail.com
В моей настройке для outgoing не используется VERP, так как мой входящий SMTP не поддерживает VERP (то есть уведомление об ошибке не будет содержать VERP-адрес). Вот почему reply-to отправляется на Gmail, поскольку он поддерживает VERP. Это не должно вызывать сбой DMARC, как происходит сейчас.