Postfix - 多个域的发件人相关中继

Postfix - 多个域的发件人相关中继

过去几天,我一直在研究 SO 问题和 Postfix 文档,但还是没能找出我做错了什么。我的情况如下:

  • 我有一台运行 Postfix 的服务器,它有自己的 FQDN(DomainA)。DomainA 的邮件通过 MailGun 中继。
  • 该服务器托管多个网站域名,现在的计划是确保这些域名的邮件通过 MailGun 转发,但作为单独的域名。这将创建单独的退回地址等。将其称为 DomainB
  • 根据标头中存在的域,配置 Postfix 以选择适当的 SASL 身份验证,确保添加适当的标头。

版本信息:Debian 7 上的 Postfix 2.11.2(Wheezy)

postconf -n 的输出:

alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_at_myorigin = no
append_dot_mydomain = no
biff = no
canonical_maps = regexp:/etc/postfix/canonical
canonical_classes = envelope_sender, header_sender
config_directory = /etc/postfix
inet_interfaces = localhost
inet_protocols = ipv4
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
mydestination = localhost.com, localhost
myhostname = DomainA.com
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
readme_directory = no
recipient_delimiter = +
sender_dependent_relayhost_maps = hash:/etc/postfix/relayhost_map
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sender_dependent_authentication = yes
smtp_tls_note_starttls_offer = yes
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes

Relayhost_map文件的内容:

@DomainA.com      [smtp.mailgun.org]:587
@DomainB.name     [smtp.mailgun.org]:587

尝试 canonical_maps 的第 1 个全部电子邮件地址重写为[电子邮件保护]

/./ [email protected]

从命令行发送电子邮件时 mail.log 的输出:

    Aug 18 01:55:12 DomainA postfix/pickup[3572]: C72492A00B8: uid=0 from=<root>
    Aug 18 01:55:12 DomainA postfix/cleanup[3591]: C72492A00B8: message-id=<[email protected]>
    Aug 18 01:55:12 DomainA postfix/qmgr[3573]: C72492A00B8: from=<[email protected]>, size=437, nrcpt=1 (queue active)
    Aug 18 01:55:13 DomainA postfix/smtp[3593]: C72492A00B8: to=<[email protected]>, relay=smtp.mailgun.org[50.56.21.178]:587, delay=0.28, delays=0.02/0.02/0.16/0.08, dsn=2.0.0, status=sent (250 Great success)

邮件客户端收到的电子邮件标题:

Delivered-To: [email protected]
Return-Path: <[email protected]>
[snip]
Sender: [email protected]
[snip]
From: Primary Root <[email protected]>
To: [email protected]
Subject: test mail #5

有两件事在我看来是非常错误的:

  1. 为什么发件人地址设置为[电子邮件保护]即使 Postfix 已设置为:

    append_at_myorigin = 没有 append_dot_mydomain = 没有

  2. 由于发件人地址附加了 DomainA.com,Postfix 似乎选择使用 DomainA 的 SASL 详细信息来中继邮件 - 通过查看 MailGun 仪表板上的日志确认。这导致退回地址也被设置为 DomainA。

尝试 canoncial_maps 中的 #2-仅有的以 DomainB.com 结尾的电子邮件地址被重写为[电子邮件保护]

/@DomainB.name/ [email protected]

.muttrc 文件设置为强制发件人电子邮件地址为 DomainB.com

set from="[email protected]"
set use_from=yes
set use_envelope_from = yes

mail.log的输出:

Aug 18 03:40:49 DomainA postfix/qmgr[8809]: 2BEB92A00D3: from=<[email protected]>, size=441, nrcpt=1 (queue active)
Aug 18 03:40:49 DomainA postfix/smtp[8824]: 2BEB92A00D3: to=<[email protected]>, relay=smtp.mailgun.org[104.130.177.23]:587, delay=0.58, delays=0.01/0.02/0.37/0.17, dsn=2.0.0, status=sent (250 Great success)

邮件客户端收到的电子邮件标题:

Delivered-To: [email protected]
[snip]
Return-Path: <[email protected]>
[snip]
Sender: [email protected]
[snip]
From: Primary Root <[email protected]>
To: [email protected]
Subject: test mail hdr #7
  1. 从这个测试中,我可以看出规范映射不是问题。重写正确进行。但是,Postfix 似乎无法将输出识别为有效的电子邮件地址,并附加了 FQDN,这导致中继中断。

欢迎任何关于如何解决此问题的建议/想法!

答案1

为了从新的角度看待这个问题,我开始在另一台服务器上配置类似的中继主机设置,正是在这个过程中,我终于找到了问题的根源。结果发现我的 sasl_passwd 文件中缺少了一个关键字符。

修复之前的 sasl_passwd 文件:

DomainB.name        [email protected]:somepassword
#Fallback
[smtp.mailgun.org]:587  [email protected]:anotherpasswd

修复后的 sasl_passwd 文件:

@DomainB.name        [email protected]:somepassword
#Fallback
[smtp.mailgun.org]:587  [email protected]:anotherpasswd

问题在于虚拟 DomainB 之前缺少一个“@”字符。回退条目是调试此问题如此困难的原因,因为当 Postfix 无法匹配任何其他条目时,所有邮件都会通过此路由传递。

由于它可能很有用,因此当我的中继主机配置开始正常工作时,我还会包含我的规范地图文件的设置:

/(.*@)DomainB.name/ ${1}DomainB.name
/(.*@)DomainA.com/ ${1}DomainA.com

上述正则表达式确保信封发件人已更新以匹配发件人,从而避免在我的电子邮件客户端中出现任何“通过 DomainA”。

附言一下,事实证明在 Ubuntu 14.04 中,仅在 main.cf 中有以下几行是不够的:

canonical_maps = regexp:/etc/postfix/canonical
canonical_classes = envelope_sender, header_sender

还必须包含以下行:

sender_canonical_maps = regexp:/etc/postfix/canonical_sender

第二个文件的内容可以与第一个文件相同,但它必须存在,以避免在 Ubuntu 中中继电子邮件时出现“通过域”标头。

相关内容