自定义直邮Postfix配置

如果您有一个需要自定义 Postfix 配置的 邮件接收容器,那么本主题就是为您准备的。下文将介绍设置 Postfix main.cf 配置变量以符合您需求的步骤。

Postfix 配置变量可以通过容器环境变量进行设置。任何以 POSTCONF_ 开头的环境变量,都会将其后剩余部分作为 Postfix 配置变量的名称,并将其值设置为该环境变量的值。例如,如果您将环境变量 POSTCONF_always_bcc 设置为 bob@example.com,那么 Postfix 将被配置为 always_bcc = bob@example.com,这将把所有 incoming 邮件的副本发送给 Bob。可怜的 Bob。

操作步骤

  1. 确定您想要设置的配置变量及其值。这可以通过阅读 官方手册、参考其他 Discourse 文档中的建议,或其他方式完成。

  2. 通过 SSH 连接到您的 Discourse 服务器,获取 root 权限,然后进入存放所有 discourse-docker 配置的位置:

    ssh ubuntu@192.0.2.42
    sudo -i
    cd /var/discourse
    
  3. 使用您喜欢的文本编辑器打开 containers/mail-receiver.yml 文件,并滚动到文件的 env: 部分。在其中添加您想要设置的变量条目,请注意不要修改其他内容,并保持适当的缩进。例如,如果我们添加 always_bcc 设置,文件可能看起来像这样:

    env:
      LANG: en_US.UTF-8
      MAIL_DOMAIN: discourse.example.com
      DISCOURSE_BASE_URL: 'https://discourse.example.com'
      DISCOURSE_API_KEY: abcdefghijklmnop
      DISCOURSE_API_USERNAME: system
    
      POSTCONF_always_bcc: 'bob@example.com'
    

    确认添加内容无误后,保存并退出编辑器。

  4. 要加载配置,您只需重启 mail-receiver 容器(无需 rebuild):

    ./launcher restart mail-receiver
    

    短暂重启后,容器应再次运行。

  5. 测试您的更改。确保您期望的效果已经实现,同时确认没有发生意外变更。

附录:向邮件接收容器添加文件

许多 Postfix 配置参数需要访问“数据库文件”,这些文件提供键/值信息,供 Postfix 用于决定如何处理邮件。如果您看到某个配置参数接受形如 hash:/some/file 的文件名,那么您就找到了使用数据库文件的场景。

问题在于,运行在容器内的 Postfix 需要在运行时能够访问这些文件。因此,您需要将这些文件复制到容器中,或者(更推荐的做法)将这些文件放在宿主机的某个目录中,然后将该目录作为卷挂载到容器内。以下说明介绍第二种方法。

完成此操作后,您放入 /var/discourse/shared/mail-receiver/etc 的任何文件将立即在容器内的 /etc/postfix/shared 路径下可见,并且您对那些文件所做的任何更改也将立即对 Postfix 生效。

以下是具体操作方法:

  1. 如果您尚未以 root 身份登录到 Discourse 服务器,请再次登录:

    ssh ubuntu@192.0.2.42
    sudo -i
    cd /var/discourse
    
  2. 使用您喜欢的文本编辑器打开 containers/mail-receiver.yml 文件,这次请找到 volume: 部分。在现有的 /var/spool/postfix 目录定义下方,添加一个新的定义,使您的 volume 部分如下所示:

    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
    

    保存并退出编辑器。

  3. 要挂载新卷,您只需重启 mail-receiver 容器(无需 rebuild):

    ./launcher restart mail-receiver
    

全部完成!

10 个赞

Matt,你认为从当前的 Postfix 配置中启用类似 admin@domain 或 info@domain 这样的账户是否可行?

我只需要几个用于接收邮件的地址,目前在 Discourse 中已经可以正常工作,但无法设置账户(这些账户似乎默认被阻止了,尽管邮件已被处理)。

感谢您提供的所有相关指南。

我刚刚使用 Digital Ocean 和 Mailgun 设置了一个 Discourse 试用服务,用于发送电子邮件。我有一个已注册的域名,其 MX 记录指向 Digital Ocean 的 IP 地址。Discourse 的出站和入站电子邮件都能正常工作。回复主题会生成发送给已设置通知的用户电子邮件,测试用户可以回复这些电子邮件,帖子也会出现在 Discourse 中。到目前为止一切顺利。

我尝试添加上面提到的 POSTCONF_always_bcc: 选项,但它似乎不起作用——我怀疑 Discourse 的“mail-receiver”部分无法通过 Mailgun 正确发送电子邮件,尽管“app”部分知道如何发送——app.yml 中包含 Mailgun 服务器的用户名和密码,但我没有看到任何关于如何将此信息放入 mail-receiver 设置文件的示例。

我知道 always_bcc 选项正在被读取和处理,因为如果我输入:

./launcher enter mail-receiver

然后运行

mailq

我可以看到我发送的测试消息正在队列中等待发送。在“发件人/收件人-------”列中,它显示了我的测试消息的来源地址,文字“(unknown mail transport error)”,然后是我在 always_bcc 设置中输入的电子邮件地址。

我曾希望能够以某种方式过滤入站消息,以便如果消息发送到 postmaster@mydomain 或 admin@mydomain,它将通过 Mailgun 在公共互联网上重新发送到我的 Gmail 地址,而不是发送给 Discourse 进行处理。这可能就是用户 @satonotdead 试图做的事情。

任何关于如何做到这一点的提示都将不胜感激!

嗯。是的,首先您需要配置mailgun 邮件接收器,使其具有某种传递邮件的方式,因为它不知道 app.yml 中的凭据或传输机制。我认为您需要添加一个更完整的配置,正如有关挂载卷的下一节所暗示的那样,其细节超出了本文档的范围。

“如何处理 postmasteradmin 电子邮件”的简单解决方案是为每个电子邮件创建一个组,并将任何想要接收这些电子邮件的人添加到该组中,他们可以将其作为群组消息进行处理。

3 个赞

您是指“mail-receiver”而不是 Mailgun?例如,教“mail-receiver”如何通过公共互联网与 Mailgun 通信,并将凭据正确传递给它以要求它执行实际的递送?

是的。抱歉。

嗯,是的,或者以某种其他方式配置 mail-receiver(即 Postfix)来发送邮件。我主要认为,如果您知道如何做到这一点,您可能宁愿直接去做,而不是使用 mail-receiver。

另一种解决方案是让某个 mail thing 处理 domain 的邮件,并通过其他 MX 将剩余的邮件转发给 mail receiver。

经过今晚的多次尝试,我已成功将 postfix 安装在 Discourse 运行容器之外,并可以通过命令行通过 Mailgun 发送电子邮件。因此,我已经成功配置了 postfix 以使用 Mailgun。我仍然无法将设置放入 mail-receiver 容器中,以便通过 Mailgun 进行邮件转发。我确信一定有一个(简单的!)方法。我似乎找不到任何日志来了解消息为何卡在邮件队列中。自从我上次使用 Linux(多年前)以来,容器技术就已经出现了。有没有办法开启日志记录,以便我可以看到 postfix 试图进行的通信,从而找出问题所在?概念上,我希望 admin@mydomain 在收到邮件后,通过 Mailgun 直接发送到我的个人 Gmail 帐户,而 category1@mydomain 和 category2@mydomain 等则在本地推送到 Discourse 以用于创建帖子。

2 个赞

我们可以将 mail-receiver 用于 Discourse 容器之外的其他 VPS 或数据中心吗?

想法是更改 Discourse 的 IP 地址以增强隐私性,并使用与 Discourse 论坛协同工作的外部“mail-receiver”进行工作/身份验证。

是的。我正在做这件事。我在 DigitalOcean 上运行邮件接收器,并在另一个数据中心的机器上运行 Discourse。

有人能解释一下怎么做吗?这个人甚至因为回答我而要钱。

您有什么问题?

只要服务器安装了 Docker 并且可以访问必要的端口,就不需要进行任何特殊配置即可配置 mail-receiver。

我设置了 mail-receiver,因为它快速而简单。但是,当我尝试检查处理邮件时,它返回 404;

我的网站是子域名,例如:forum.site.com

在 app mail-receiver 中,我的端点是这样的:

DISCOURSE_MAIL_ENDPOINT: ‘http://forum.site.com/admin/email/handle_mail

我还需要重建 discourse 吗?

如果您收到 404,那很可能是 API 密钥不正确。

2 个赞

这是默认的API,但仍然给我404错误。我已通过Google Talk发送给你,请检查。

1 个赞

配置 SMTP Banner?

MXtoobox 的 SuperTool 报告了 SMTP Banner 检查问题。
image

通常,EHLO banner 应与 MAIL_DOMAIN 匹配,而 MAIL_DOMAIN 又应与反向 DNS 指针(PTR 记录)匹配。因此,如果我的 mail-receiverdiscourse.example 上运行,那么 POSTCONF_myhostname 应为 discourse.example

配置 EHLO banner 的正确方法是什么?

我的第一个想法是尝试在 mail-receiver.yml 中设置 HOSTNAME,这样它就可以替换 /etc/postfix/mail-receiver-environment.json 中的原始 host-mail-receiver.localdomain。但这不会改变 /etc/hostname,也不会改变 Postfix 配置中的 myhostname

我倾向于使用 POSTCONF_myhostname,但我担心它会产生不必要的副作用,因为 $myhostname 在多个地方使用,并且它将不再与 /etc/hostname 匹配。

root@host-mail-receiver:/etc/postfix# postconf | grep myhostname
lmtp_lhlo_name = $myhostname
local_transport = local:$myhostname
milter_macro_daemon_name = $myhostname
myhostname = host-mail-receiver.localdomain
myorigin = $myhostname
smtp_helo_name = $myhostname
smtpd_proxy_ehlo = $myhostname
root@host-mail-receiver:/etc/postfix# cat /etc/hostname
host-mail-receiver

Discourse-setup 有一个设置项。我不记得它的名字了,而且在手机上很难找到。你可以查看源码或者运行它。

Postfix 设置 smtp_helo_name 会更改 HELO(或 EHLO)命令中指定的名称,但这是一个传出邮件的传递设置,而 SMTP Banner 是在接收邮件时发送的。其中指定的默认主机名取自 myhostname,但您可以使用 smtpd_banner 设置来修改 Banner 以显示不同的内容。

1 个赞

不确定这是否能帮到其他人,我遇到了类似的问题,这让我意识到不知何故我撤销了 API 密钥。一旦我撤销了撤销,收件就又能正常工作了。

所以,感谢你让我意识到这与 API 密钥有关 :slightly_smiling_face:

1 个赞

自此内容写成以来,是否可能发生了什么变化?我发现,在 env: 下添加 POSTCONF_smtpd_banner 值,经过多次重启后,完全没有被采纳。我不得不重建(./launcher rebuild mail-receiver)才能使其生效。

各位好,

我刚刚完成了一个域名迁移(参考 Change the domain name or rename your Discourse ),一切顺利。但是,我正在使用 mail-receiver 容器,并为几个分类设置了 MX 记录以接收邮件……

据我所知,该容器的默认配置硬编码了传入域名和 LetsEncrypt 证书的路径。是否可以在配置中或通过这些高级选项允许使用两个域名?