自定义直邮Postfix配置

If you have a mail receiver container which requires customised Postfix configuration, this is the topic for you. Herein are described the steps required to set Postfix main.cf configuration variables to whatever your heart desires.

Postfix configuration variables can be set via the container environment. Any environment variable starting with POSTCONF_ will set a Postfix configuration variable named for the rest of the environment variable to the value of the environment variable. For example, if you set the environment variable POSTCONF_always_bcc to bob@example.com, then Postfix will be configured with always_bcc = bob@example.com, which will send a copy of all incoming mail to Bob. Poor Bob.

Procedure

  1. Figure out what configuration variables you want to set, and what values to set them to. This may be done by reading the fine manual, or through recommendations in other Discourse documentation, or otherwise.

  2. Connect to your Discourse server via SSH, grab some root privileges, and head over to where all the discourse-docker configuration lives:

    ssh ubuntu@192.0.2.42
    sudo -i
    cd /var/discourse
    
  3. Open up containers/mail-receiver.yml in your text editor of choice, and swing down to the env: section of the file. Somewhere in there, add entries for the variables you want to add, being careful to not modify anything else, and maintaining appropriate indenting. For example, if we were adding our always_bcc setting, the file might look a bit like this:

    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'
    

    Once you’re happy with what you’ve added, save and exit your editor.

  4. To load the configuration, you simply have to restart the mail-receiver container (a rebuild is not required):

    ./launcher restart mail-receiver
    

    After a brief spasm, the container should be running again.

  5. Test your changes. Ensure both that what you wanted to have happen has, indeed, happened, and also that nothing you didn’t expect to change hasn’t.

Addendum: adding files to the mail-receiver container

Many Postfix configuration parameters require access to “database files”, which provide key/value information which Postfix uses to make decisions about what do with mail. If you see that a configuration parameter accepts a filename that looks like hash:/some/file, you’ve found a use for database files.

The thing is, Postfix running inside the container needs to be able to get at those files while it’s running, which means you need to either copy those files into the container, or (preferably) put those files into a directory on the host, and then mount that directory as a volume inside the container. These instructions describe the second method.

Once you have completed this procedure, any file you place into /var/discourse/shared/mail-receiver/etc will immediately become visible at /etc/postfix/shared inside the container, and any changes you make to those files will be immediately visible to Postfix.

Here’s how to make it happen.

  1. If you’re not still logged in as root to your Discourse server, do so again:

    ssh ubuntu@192.0.2.42
    sudo -i
    cd /var/discourse
    
  2. Open up containers/mail-receiver.yml in your text editor of choice, and this time head for the volume: section. Underneath the existing definition for the /var/spool/postfix directory, add another one, so that your volume section looks like this:

    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
    

    Save/exit your editor.

  3. To attach the new volume, you simply have to restart the mail-receiver container (a rebuild is not required):

    ./launcher restart mail-receiver
    

All done!

10 个赞

Matt, do you think that could be possible to enable accounts like admin@domain or info@domain from this Postfix configuration?

I only need to have a couple of addresses for incoming e-mail and I have it working with Discourse but I can’t set accounts (their seem to be blocked by default even though messages are processed).

Thanks for all your guides related.

我刚刚使用 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 电子邮件”的简单解决方案是为每个电子邮件创建一个组,并将任何想要接收这些电子邮件的人添加到该组中,他们可以将其作为群组消息进行处理。

2 个赞

您是指“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)才能使其生效。