直到最近,我还没有遇到过 Postfix 通过 Sparkpost 进行中继和转发的问题。现在我收到身份验证错误 530 5.7.1。服务器正在运行 Debian Stretch。Postfix main.cf 中的设置按照 Sparkpost 的建议进行设置。
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
smtp_sasl_password_maps = static:SMTP_Injection:My_API_key
我有一个邮箱,[电子邮件保护]转发至[电子邮件保护]. 消息被发送到[电子邮件保护],但邮件日志显示转发内容如下:
Dec 31 11:19:48 example postfix/smtp[19188]: 66AA357DD2: to=<[email protected]>, relay=smtp.sparkpostmail.com[52.26.175.191]:587, delay=0.38, delays=0.1/0.01/0.21/0.06, dsn=5.7.1, status=bounced (host smtp.sparkpostmail.com[52.26.175.191] said: 530 5.7.1 Authorization required. Ref. https://developers.sparkpost.com/api/index#header-smtp-relay-endpoints (in reply to MAIL FROM command))
Dec 31 11:19:48 example postfix/cleanup[19176]: EAB4957DD0: message-id=<[email protected]>
Dec 31 11:19:49 example postfix/bounce[19189]: 66AA357DD2: sender non-delivery notification: EAB4957DD0
Dec 31 11:19:49 example postfix/qmgr[19147]: EAB4957DD0: from=<>, size=7611, nrcpt=1 (queue active)
Dec 31 11:19:49 example postfix/cleanup[19176]: 5777A57DD4: message-id=<[email protected]>
Dec 31 11:19:49 example postfix/bounce[19189]: 66AA357DD2: postmaster non-delivery notification: 5777A57DD4
我知道证书正在运行,因为我运行时没有看到任何错误
openssl s_client -connect mail.example.com:587 -starttls smtp
输出:
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = example.com
verify return:1
---
Certificate chain
0 s:/CN=example.com
i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGUjCCBTqgAwIBAgISBMCBEL46Fp5eG+d54abyrZxXMA0GCSqGSIb3DQEBCwUA
...
qFl1JeXAxKBW9nE9E5+ZuC+8SNF7LlqiN2bi5BMA1x0wiVXZk+fTAk3vRsTTr0CM
svdtByn4XF3UbPoBhnHv8IGXx0ZqXUWt141ZxkV2Mxaak2TyyK7IeVCqlWGIMC1z
pgOO7fdZMY1xC/TEDdxcMOyTf7C7Ih539kPoeM7wHdWNXsipbc3r6NWQ9440dCd1
yPXKfWzAPBhtqFF+T3SOFqQHr6twNRLT8ITu/PtiipxUAvO+wQrdLIrKzfpNeJW4
GXXXeV+crpGdvJa/EdYLZgx5O2DWX67VKerlVWTdcAGwvU3Jia8=
-----END CERTIFICATE-----
subject=/CN=example.com
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3733 bytes and written 335 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 3987DBFA6A51B83864E89C0E8E7C24EB9536355130F8ADE266033CEAE264B6B2
Session-ID-ctx:
Master-Key: DA5D77AFF4C3B173144402101F9E59AE809C120679BDA9CE577D963148E5F405F205BB4898D3754BE6608863E9A7E5C0
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - 16 25 d2 8c f4 00 d3 b2-de b8 23 a8 7d 9a 07 ed .%........#.}...
0010 - 45 2b e1 9d 15 94 6e 9a-b7 90 4b 8b cb c8 d9 98 E+....n...K.....
0020 - 27 b6 31 ef 65 18 de db-05 e5 f1 90 1a a9 c2 dc '.1.e...........
0030 - 8b c0 2b 38 21 be fd ff-85 8c a2 7a af 86 bc 72 ..+8!......z...r
0040 - 72 22 ed 67 04 3b 25 92-45 5d 83 ba 85 0e 27 c2 r".g.;%.E]....'.
0050 - 71 01 ba ea f5 58 11 42-81 70 08 5d e2 22 d0 63 q....X.B.p.].".c
0060 - 59 08 4c 53 c5 a8 27 37-b2 79 eb 88 55 81 c7 1d Y.LS..'7.y..U...
0070 - 0e 69 b2 05 b3 83 05 41-16 e5 18 ad 25 2a 80 2f .i.....A....%*./
0080 - 50 c5 d6 95 e8 d4 5a 19-68 7e a0 91 f0 21 ca d2 P.....Z.h~...!..
0090 - b5 d9 56 58 15 7f d9 71-3a 71 ae 3f 47 a3 99 e2 ..VX...q:q.?G...
00a0 - 7f 6e 1c 5a ea 85 bb 98-d6 bb a3 6e 40 7f 34 07 [email protected].
Start Time: 1546272800
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: yes
---
250 SMTPUTF8
我怎样才能解决这个问题?
答案1
也许我应该一开始就意识到这一点,这样就可以省去在黑暗中摸索的几个小时。当一封电子邮件到达本地邮箱并被转发时,它会在转发过程中保留原始发件人地址。换句话说,一封来自[电子邮件保护]->[电子邮件保护]转发至[电子邮件保护]到达 smtp.sparkpostmail.com 及其原始发件人地址,[电子邮件保护]。然后 Sparkpost 会退回电子邮件,因为 elsei.com 不是它识别的发送域。正确的错误消息是 550 5.7.1,应该将 elsei.com 标识为配置问题。
我最终找到的解决方案是配置 postfix,使其根据发件人地址使用不同的传输和身份验证凭据。为此,您需要创建两个数据文件,或者如果您使用 postfix 的 mysql 数据库,则创建一个数据文件并编辑 postfix.transport 表。
/etc/postfix/sasl_passwd 包含本地发送域和 Sparkpost 登录凭据:
@example.com SMTP_Injection:<API key for example.com>
@example2.com SMTP_Injection:<API key for example2.com>
/etc/postfix/relayhosts 包含具有 Sparkpost 中继主机的本地域,以及通过服务器的转发邮件的捕获器:
@example.com [smtp.sparkpostmail.com]:587
@example2.com [smtp.sparkpostmail.com]:587
* smtps
不要忘记 postmap /etc/postfix/sasl_passwd 和 postmap /etc/postfix/relayhosts。
如果使用 mysql,请编辑 postfix.transport 表,在每个使用 sparkpost 的本地域的传输字段中添加 [smtp.sparkpostmail.com]:587。如果您有不使用 sparkpost 的本地域,请在传输字段中添加“smtps”。创建 /etc/postfix/virtual_forward.cf 以从 mysql db 中的传输表中提取相同的数据:
hosts = 127.0.0.1 (or localhost)
user = mysql-login
password = mysql-pw
dbname = postfix
query = SELECT transport FROM transport WHERE domain='%s' AND LENGTH(transport) > 0
再次,您必须添加一个 catch-all 传输作为表中的最后一条记录:
* smtps
据我了解,smtps 使用 master.cf 中定义的端口 465,并从本地服务器发送,而不是 master.cf 中定义的提交(smtpd),它使用端口 587 通过 Sparkpost 发送。
为了使所有这些工作正常,您需要向 main.cf 添加一些设置
#Unless the next line has no value, postfix cannot send from localhost
relayhost =
#Using the relayhosts file
sender_dependent_relayhosts_maps = hash:/etc/postfix/relayhosts
#Using mysql
sender_dependent_relayhosts_maps = mysql:/etc/postfix/virtual_forward.cf
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
#Not sure the next 2 lines are absolutely necessary, but I assume they are because they relate to smtp, rather than smtpd (submission)
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sender_dependent_authentication = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
我希望这个解释可以让其他人免于花费数小时来探究邮件服务器的奥秘。