如何配置 Discourse 接收邮件?

虽然许多人喜欢网页界面,但电子邮件仍然是许多人在线生活的“枢纽”。这就是为什么发送电子邮件如此重要,而当您发送电子邮件时,您也确实希望能够收到它。原因有以下几点:

  • 如果电子邮件“退回”(由于某种原因无法送达),您需要了解这一点。重复发送退回的电子邮件会使您的电子邮件被标记为垃圾邮件。接收退回的电子邮件可让您禁止向不存在的地址发送邮件。
  • 允许人们通过电子邮件回复帖子可以显著提高参与度,因为即使他们当时无法访问论坛,也可以直接从他们的邮件客户端回复。
  • 让人们通过电子邮件发布新主题或发送私信,对参与度也有类似的好处。此外,您可以使用 Discourse 来处理群组的电子邮件,例如基于电子邮件的支持渠道(Discourse 自己的电子邮件支持就是这样处理的)。

将电子邮件直接发送到您的 Discourse 论坛,而不是设置 POP3 轮询,有很多好处:

  • 无需处理 Gmail 或其他提供商的怪癖;
  • 您可以更好地控制人们用于发送帖子的电子邮件地址;以及
  • 交付没有延迟——无需等待下一次轮询运行即可看到新帖子的出现!

本操作指南旨在将这种热度带入您的论坛。

概述

此过程在您的 Discourse 服务器上创建一个新的容器,与典型的 app 容器一起,接收电子邮件并将其转发到 Discourse 进行处理。它支持所有电子邮件流程:处理退信、回复和创建新主题。任何使用我们支持的安装过程的自托管 Discourse 论坛都可以利用此过程来获得简单、流畅的传入电子邮件。

容器设置

我们将在已经运行您的 Discourse 实例的服务器上启动并运行 mail-receiver 容器。无需单独的 droplet 来处理邮件——整个容器只需要大约 5MB 的内存!

因此,首先登录您的 Discourse 服务器,并通过 sudo 成为 root

ssh [email protected]
sudo -I

现在,转到您的 /var/discourse 目录,并从方便提供的示例中创建一个新的 mail-receiver.yml 容器定义:

cd /var/discourse
git pull
cp samples/mail-receiver.yml containers/

由于每个站点都是唯一的,请在您喜欢的文本编辑器中打开 containers/mail-receiver.yml,并更改 MAIL_DOMAINDISCOURSE_MAIL_ENDPOINTDISCOURSE_API_KEY 变量以适合您的站点。(如果您是高级用户并且知道您正在容器外部使用 nginx,请参阅下面的外部 nginx 的其他配置。)

:bulb: 如果您使用默认邮件端点 (/admin/email/handle_mail),我们建议使用 receive_email API 密钥范围以提供额外的安全层。

如果您不确定您最喜欢的文本编辑器是什么,请尝试 nano

nano containers/mail-receiver.yml

使用 Ctrl-X 退出(对“您要保存更改吗?”说“是”,否则您的所有工作都将白费)。

现在,对容器进行初始构建,并启动它!

./launcher bootstrap mail-receiver
./launcher start mail-receiver

要检查一切正常,请查看日志:

./launcher logs mail-receiver

打印的最后一行应该非常类似于:

<22>Aug 31 04:14:31 postfix/master[1]: daemon started -- version 3.1.1, configuration /etc/postfix

如果是这样,一切都很好,您可以继续下一步。

DNS 设置

为了让 Internet 上的其他人知道在哪里发送邮件,您必须为您的论坛创建一个 MX 记录。如何执行此操作的确切细节因 DNS 提供商而异,但总的来说,该过程应该与您最初设置论坛的 DNS 记录的方式非常相似,只是您创建的是 MX(或“邮件交换”)记录,而不是 A(或“地址”)记录。如果您的论坛位于 forum.example.com,并且您在 mail-receiver.yml 中将 MAIL_DOMAIN 设置为 forum.example.com,则 DNS 记录应如下所示:

  • DNS 名称: forum.example.com(这是 MAIL_DOMAIN
  • 类型: MX
  • 优先级: 10
  • 值: forum.example.com(这是您论坛的域名)

为确保 DNS 设置正确,请使用 http://mxtoolbox.com/ 等测试站点查找您配置的 MAIL_DOMAIN,并确保它指向您期望的位置。

注意:像 mailgun 这样的出站电子邮件提供商可能会要求您添加指向其服务器的 MX 记录。您需要删除这些记录,以便您的论坛的 MX 记录仅指向您论坛的域名。SPF 和 DKIM 记录必须仍然指向您的出站电子邮件提供商服务器,以便您可以发送电子邮件。

Discourse 配置

现在电子邮件已输入 Discourse,是时候向 Discourse 解释它应该对收到的电子邮件什么了。

  • 以管理员身份登录您的 Discourse 论坛并导航到管理面板的“站点设置”,然后单击“电子邮件”选项卡。(forum.example.com/admin/site_settings/category/email)
  • 更改以下设置:
    • 启用 reply by email 设置
    • reply_by_email_address 字段中,输入 replies+%{reply_key}@forum.example.com
    • 启用 manual polling 设置

您可以自动使用 任何 @forum.example.com 地址作为类别或群组电子邮件的地址,无需任何进一步设置。

故障排除

事情从来没有按计划进行。以下是如何找出问题所在。

  1. 运行 ./launcher start mail-receiver 时出现 OCI 运行时创建失败错误? 您的主机名可能太长。使用这些说明重命名它并选择一个较短的名称,然后重新构建。
  2. 电子邮件是否到达 mail-receiver 运行 ./launcher logs mail-receiver,并查找提及电子邮件发送和接收地址的日志条目。如果没有这些,则消息根本没有到达,问题出在上游。检查 MX 记录、发送邮件服务器日志和防火墙权限(SMTP 端口 25)。
  3. 消息是否卡在队列中? 运行 ./launcher enter mail-receiver,然后运行 mailq。它应该报告,“邮件队列为空”。如果其中有任何消息,您将获得列出的收件人和发件人地址。只有在向 Discourse 本身传递时出现问题时,消息才会停留在队列中,因此请 exit 退出容器,然后检查…
  4. mail-receiver 是否以某种方式出错? 运行 ./launcher logs mail-receiver | grep receive-mail 并查找任何看起来像堆栈跟踪的内容,或者基本上除了“收件人:@forum.example.com”之外的任何内容。这些错误消息虽然不一定是不言自明的,但应该在很大程度上有助于解释问题所在。查找 yml 文件中的拼写错误。特别是,检查 DISCOURSE_MAIL_ENDPOINT URL 是否与您的站点 URL 匹配,通常以 https:// 开头。

与外部 nginx 集成

如果您是高级用户并且已配置外部 nginx,例如在 Discourse 重新构建或启动时添加一个离线页面以显示,您会发现 mail-receiver 和在外部 nginx 中处理的 HTTPS 的组合需要稍微不同的处理才能通过 TLS 启用电子邮件的 SSL。以下是与推荐的外部 nginx 配置(带有 letsencrypt 证书)一起使用的示例 containers/mail-receiver.yml 片段:

DOMAIN

  POSTCONF_smtpd_tls_key_file:  /letsencrypt/live/forum.example.com/privkey.pem
  POSTCONF_smtpd_tls_cert_file:  /letsencrypt/live/forum.example.com/fullchain.pem

volumes:
  - volume:
      host: /var/discourse/shared/mail-receiver/postfix-spool
      guest: /var/spool/postfix
# uncomment to support TLS
  - volume:
      host: /etc/letsencrypt/
      guest: /letsencrypt

请注意,您不能仅将 /etc/letsencrypt/live 导出为卷,因为实际文件是指向 ../../archive/... 的符号链接,如果您在卷规范中更具体,这些符号链接将无法解析。

防止传出的主机电子邮件干扰 (Postfix)

如果您有(或想要)来自您的主机服务器(通过 Postfix)的自动消息,则邮件接收器将发生冲突,因为它需要端口 25 才能运行。一种解决方案是禁止主机 Postfix 侦听端口 25:

nano /etc/postfix/master.cf

并注释掉如下所示的行:

smtp inet n - y - - smtpd

然后 service postfix reload。您可能还需要重新启动邮件接收器容器。

在主机 Postfix 和邮件接收器都运行的情况下,执行 netstat -tulpn | grep :25 以确认 docker-proxy 正在使用端口 25。

阻止不需要的域向您发送邮件

要阻止来自不需要的域的电子邮件到达您的 Discourse,您的 mail-receiver.yml 应如下所示:

  DISCOURSE_API_USERNAME: system

  POSTCONF_smtpd_sender_restrictions: 'texthash:/etc/postfix/shared/sender_access'

volumes:
  - volume:
      host: /var/discourse/shared/mail-receiver/postfix-spool
      guest: /var/spool/postfix
  - volume:
      host: /var/discourse/shared/mail-receiver/etc
      guest: /etc/postfix/shared
# uncomment to support TLS
#  - volume:
#      host: /var/discourse/shared/standalone/letsencrypt
#      guest: /letsencrypt

然后创建 /var/discourse/shared/mail-receiver/etc 路径,并在其中创建一个 sender_access 文件,其中包含要拒绝的域,如下所示:

qq.com REJECT
163.com REJECT

重建,您就大功告成了!

DMARC 支持

DMARC 支持已在 discourse/mail-receiver:release 映像中默认启用,以更强有力地验证传入电子邮件。自带有时间戳的映像 discourse/mail-receiver:20240720054629 起启用此功能。

可以通过 INCLUDE_DMARC docker 环境变量切换此功能。如果首选更宽松的传入邮件服务器配置,请将该环境变量设置为 false 并重建映像。

没有 DMARC 支持的最后一个版本是 discourse/mail-receiver:20211208001915

延伸阅读

1 Like