带有 TLS 的 Postfix 2.6.6 - 无法接收来自 GMail(和其他几个 MTA)的电子邮件,但其他的都可以,为什么?

带有 TLS 的 Postfix 2.6.6 - 无法接收来自 GMail(和其他几个 MTA)的电子邮件,但其他的都可以,为什么?

我刚刚查看了运行 Postfix 2.6.6 的 CentOS 6 服务器,它能够向所有人发送电子邮件,但由于传入 TLS 协商问题,无法从 GMail(和其他一些 MTA)接收电子邮件。

.google.com来自SMTP 服务器(即 GMail)的连接导致以下结果:

Aug 23 19:34:29 server1 postfix/smtpd[7659]: connect from mail-lf1-f44.google.com[209.85.167.44]
Aug 23 19:34:29 server1 postfix/smtpd[7659]: setting up TLS connection from mail-lf1-f44.google.com[209.85.167.44]
Aug 23 19:34:29 server1 postfix/smtpd[7659]: SSL_accept error from mail-lf1-f44.google.com[209.85.167.44]: -1
Aug 23 19:34:29 server1 postfix/smtpd[7659]: warning: TLS library problem: 7659:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1387:
Aug 23 19:34:29 server1 postfix/smtpd[7659]: lost connection after STARTTLS from mail-lf1-f44.google.com[209.85.167.44]
Aug 23 19:34:29 server1 postfix/smtpd[7659]: disconnect from mail-lf1-f44.google.com[209.85.167.44]

增加 TLS 日志详细程度:

Aug 23 21:56:15 server1 postfix/smtpd[18103]: initializing the server-side TLS engine
Aug 23 21:56:15 server1 postfix/smtpd[18103]: connect from mail-lf1-f47.google.com[209.85.167.47]
Aug 23 21:56:15 server1 postfix/smtpd[18103]: setting up TLS connection from mail-lf1-f47.google.com[209.85.167.47]
Aug 23 21:56:15 server1 postfix/smtpd[18103]: mail-lf1-f47.google.com[209.85.167.47]: TLS cipher list "ALL:+RC4:@STRENGTH:!aNULL:!LOW:!EXP:!MEDIUM:!ADH:!AECDH:!MD5:!DSS:!ECDSA:!CAMELLIA128:!3DES:!CAMELLIA256:!RSA+AES:!eNULL"
Aug 23 21:56:15 server1 postfix/smtpd[18103]: SSL_accept:before/accept initialization
Aug 23 21:56:15 server1 postfix/smtpd[18103]: SSL3 alert write:fatal:handshake failure
Aug 23 21:56:15 server1 postfix/smtpd[18103]: SSL_accept:error in SSLv3 read client hello C
Aug 23 21:56:15 server1 postfix/smtpd[18103]: SSL_accept error from mail-lf1-f47.google.com[209.85.167.47]: -1
Aug 23 21:56:15 server1 postfix/smtpd[18103]: warning: TLS library problem: 18103:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1387:
Aug 23 21:56:15 server1 postfix/smtpd[18103]: lost connection after STARTTLS from mail-lf1-f47.google.com[209.85.167.47]
Aug 23 21:56:15 server1 postfix/smtpd[18103]: disconnect from mail-lf1-f47.google.com[209.85.167.47]

没有共享密码?!

TLS 已启用(尽管是自签名的)服务器证书;客户端已成功连接并通过带有 SASL 的 IMAP/POP 发送和接收邮件。

我查阅了导致1408A0C1后缀错误的常见原因,但似乎没有一个适用于这种情况。我运行的一些检查产生的结果似乎与我的预期相矛盾;

postconf -d | grep cipherlist有一个相当简短的排除列表:

tls_export_cipherlist = ALL:+RC4:@STRENGTH
tls_high_cipherlist = ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH
tls_low_cipherlist = ALL:!EXPORT:+RC4:@STRENGTH
tls_medium_cipherlist = ALL:!EXPORT:!LOW:+RC4:@STRENGTH
tls_null_cipherlist = eNULL:!aNULL

TLS 协议也相当宽松:

smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtp_tls_mandatory_protocols  = !SSLv2, !SSLv3
smtpd_tls_protocols           = !SSLv2, !SSLv3
smtp_tls_protocols            = !SSLv2, !SSLv3

那么为什么它无法协商密码呢?

我首先着手更新 OpenSSL(这是OpenSSL 1.0.1e-fips 11 Feb 2013可通过 获得的最新版本yum);我做了按照本文所述结果盒子运行了OpenSSL 1.0.2p 14 Aug 2018

但 GMail 接收问题仍然存在......

我保留它们原样,以便所有可能的 TLS 变体都有机会成功,并更详细地研究了密码。

禁用全部密码排除,我从我的 Gmail 发送了一封测试电子邮件,并且不出所料它成功通过了:

Aug 23 23:39:52 server1 postfix/smtpd[6036]: connect from mail-lj1-f171.google.com[209.85.208.171]
Aug 23 23:39:52 server1 postfix/smtpd[6036]: setting up TLS connection from mail-lj1-f171.google.com[209.85.208.171]
Aug 23 23:39:52 server1 postfix/smtpd[6036]: mail-lj1-f171.google.com[209.85.208.171]: TLS cipher list "ALL:+RC4:@STRENGTH"
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:before/accept initialization
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 read client hello B
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 write server hello A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 write certificate A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 write server done A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 flush data
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 read client key exchange A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 read finished A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 write session ticket A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 write change cipher spec A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 write finished A
Aug 23 23:39:52 server1 postfix/smtpd[6036]: SSL_accept:SSLv3 flush data
Aug 23 23:39:52 server1 postfix/smtpd[6036]: Anonymous TLS connection established from mail-lj1-f171.google.com[209.85.208.171]: TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)
Aug 23 23:39:52 server1 postfix/smtpd[6036]: 66BB15DC6: client=mail-lj1-f171.google.com[209.85.208.171]
Aug 23 23:39:52 server1 postfix/cleanup[6424]: 66BB15DC6: message-id=<CAK9Gk9r+6gt7g_U987A0XaGdKJGY=80n0rK595mqrmfGaL5LKQ@mail.gmail.com>
Aug 23 23:39:52 server1 opendkim[6890]: 66BB15DC6: mail-lj1-f171.google.com [209.85.208.171] not internal
Aug 23 23:39:52 server1 opendkim[6890]: 66BB15DC6: not authenticated
Aug 23 23:39:52 server1 opendkim[6890]: 66BB15DC6: DKIM verification successful
Aug 23 23:39:52 server1 postfix/qmgr[6032]: 66BB15DC6: from=<gmailaddress>, size=3988, nrcpt=1 (queue active)
Aug 23 23:39:52 server1 postfix/smtpd[6036]: disconnect from mail-lj1-f171.google.com[209.85.208.171]
Aug 23 23:39:52 server1 postfix/pipe[6425]: 66BB15DC6: to=<myinbox>, relay=dovecot, delay=0.48, delays=0.29/0.01/0/0.18, dsn=2.0.0, status=sent (delivered via dovecot service)

那么如果 GMailAES128-GCM-SHA256通过 TLSv1.2 进行协商——为什么以前不起作用?特别是因为他们的密码列表似乎是任何可能的匹配,末尾是 RC4,按强度排序?


为了进行测试,我采用了一个特定的密码列表,在前面添加了 AES128 哈希深度(斜体) - ECDHE 和 DHE 方法 - 并在后缀中明确声明了它,这样做有效:

tls_high_cipherlist=ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA

但我不想不断更新密码列表配方,所以注释掉了该tls_high_cipherlist声明。

然后我做了一些事情。

master.cf按照建议,我在 postfix 中添加了-o smtp_tls_mandatory_protocols=TLSv1smtpd 部分。

我想通过使用以下声明来改进 TLS 协议https://blog.kruyt.org/postfix-and-tls-encryption/,它明确批准 TLSv1.2 和 TLSv1.1,然后排除较旧的版本。但是对于 postfix 2.6.6,这不起作用;我在重新加载/重启后不久在日志中看到了这一点:

warning: Invalid TLS protocol list "TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3": disabling TLS support

如果我将排除规则与包含规则混合在一起,就会发生这种情况,因此我恢复了明确的排除格式:

smtpd_tls_protocols = !TLSv1, !SSLv2, !SSLv3
smtp_tls_protocols = !TLSv1, !SSLv2, !SSLv3
smtp_tls_ciphers = high
smtpd_tls_ciphers = high
smtpd_tls_mandatory_protocols = !TLSv1, !SSLv2, !SSLv3
smtp_tls_mandatory_protocols = !TLSv1, !SSLv2, !SSLv3
smtp_tls_mandatory_ciphers = high
smtpd_tls_mandatory_ciphers = high

并且这已被 Postfix 接受。

我设置了机会性 TLS

smtp_tls_security_level = may
smtpd_tls_security_level = may

我注意到,即使解决了 GMail 投递问题,其他一些 MTA 仍然出现故障:

server1 postfix/smtpd[28167]: connect from mta3.email.secretescapes.com[198.245.84.110]
server1 postfix/smtpd[28167]: setting up TLS connection from mta3.email.secretescapes.com[198.245.84.110]
server1 postfix/smtpd[28167]: mta3.email.secretescapes.com[198.245.84.110]: TLS cipher list "ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH:!MD5:!DES:!ADH:!RC4:!PSD:!SRP:!3DES:!eNULL:!aNULL"
server1 postfix/smtpd[28167]: SSL_accept:before/accept initialization
server1 postfix/smtpd[28167]: SSL_accept:error in SSLv2/v3 read client hello A
server1 postfix/smtpd[28167]: SSL_accept error from mta3.email.secretescapes.com[198.245.84.110]: -1
server1 postfix/smtpd[28167]: warning: TLS library problem: 28167:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr.c:647:
server1 postfix/smtpd[28167]: lost connection after STARTTLS from mta3.email.secretescapes.com[198.245.84.110]
server1 postfix/smtpd[28167]: disconnect from mta3.email.secretescapes.com[198.245.84.110]

-

server1 postfix/smtpd[1451]: initializing the server-side TLS engine
server1 postfix/smtpd[1451]: connect from mta.email.bbc.com[198.245.84.99]
server1 postfix/smtpd[1451]: setting up TLS connection from mta.email.bbc.com[198.245.84.99]
server1 postfix/smtpd[1451]: mta.email.bbc.com[198.245.84.99]: TLS cipher list "ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH:!MD5:!aDSS:!kECDH:!kDH:!SEED:!IDEA:!DES:!ADH:!RC2:!RC4:!RC5:!PSD:!SRP:!3DES:!eNULL:!aNULL"
server1 postfix/smtpd[1451]: SSL_accept:before/accept initialization
server1 postfix/smtpd[1451]: SSL_accept:error in SSLv2/v3 read client hello A
server1 postfix/smtpd[1451]: SSL_accept error from mta.email.bbc.com[198.245.84.99]: -1
server1 postfix/smtpd[1451]: warning: TLS library problem: 1451:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr.c:647:
server1 postfix/smtpd[1451]: lost connection after STARTTLS from mta.email.bbc.com[198.245.84.99]
server1 postfix/smtpd[1451]: disconnect from mta.email.bbc.com[198.245.84.99]
server1 postfix/smtpd[1451]: connect from unknown[107.174.30.57]
server1 postfix/smtpd[1451]: 4F6D0629C: client=unknown[107.174.30.57]

然后我尝试了 tls_high_cipherlist 的一些排列,最后使用bettercrypto.org 推荐列表

tls_high_cipherlist=EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA

该服务器已通过各种 SSL 测试程序进行测试,包括检查TLS(100% 结果),奢侈品(A+ 成绩),htbridge 的 SSL 测试器(良好成绩)和SSL 工具

我知道您可以策略映射传出连接,但我正在寻找一种等效方法,以便我可以有选择地禁用特定 MTA 的任何排除(当我找到它们时)并找出它们正在协商的密码,然后调整我提供的密码列表。

我看不出当前 postfix TLS 配置有任何明显的缺陷。我不知道为什么某些 MTA 无法协商 TLS 密码,而其他 MTA 却能顺利处理。即使是挑剔的 GMail 现在也可以了。

有任何想法吗?:-)


我注意到这个 SE 问题是关于为什么 Google 更喜欢使用这种密码,读起来很有趣。

致谢此 Postfix 用户论坛主题中,我找到了一个有用的方法,可以快速查看所有可用密码中成功建立了多少个 TLS 连接:

egrep "TLS connection established from.*with cipher" /var/log/maillog* | awk '{printf("%s %s %s %s\n", $12, $13, $14, $15)}' | sort | uniq -c | sort -

答案1

归根结底,这个问题似乎是由于一些发件人仍然只能协商 SSLv3。这是一件坏事,但收不到电子邮件也不是一件好事。

其实就是这么简单。我对此并不满意,但如果发送 MTA 拒绝重新协商 TLS,而是一直使用 SSLv3 重试,那么我们目前能做的事情不多。

因此,暂时,我已采取允许使用 SSLv3 加密传入电子邮件的做法,但要求服务器上的所有客户端仍然必须通过 TLS 进行身份验证。

我通过放松协议否定器来实现这一点main.cf

smtpd_tls_mandatory_protocols = !TLSv1, !SSLv2
smtpd_tls_protocols = !TLSv1, !SSLv2

注意:这些smtp_tls_定义是针对从该服务器发送的邮件的,因此与客户端连接有关,因此您可以根据需要使这些定义尽可能严格(只要您愿意向每个人解释如何设置他们的电子邮件客户端):

smtp_tls_mandatory_protocols = !TLSv1, !SSLv2, !SSLv3
smtp_tls_protocols = !TLSv1, !SSLv2, !SSLv3

如果发送 MTA 无法协商 TLS(需要 SSLv3),您通常会在邮件日志中看到以下内容:

warning: TLS library problem: 364:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr.c:647:

如果你提高日志记录级别,你会看到 TLS 协商失败,并出现更多类似这样的消息

postfix/smtpd[26234]: SSL_accept:before/accept initialization
postfix/smtpd[26234]: SSL_accept:error in SSLv2/v3 read client hello A
postfix/smtpd[26234]: SSL_accept error from 201-62-89-201.life.com.br[201.62.89.201]: -1

我一直在定期测试禁止 SSLv3 连接(不可避免地,MTA 会重试很多天),因此您可以允许日志中累积一些故障,然后对其进行分析。

这个 bash 脚本帮助我分析哪些服务器正在尝试使用 SSLv3:

#!/bin/sh
egrep "SSL_accept error" /var/log/maillog | awk '{printf("%s %s %s\n", $9, $10, $11)}' | sort | uniq -c | sort -`

此变体显示协商密码 - 因此一旦您重新启用 SSLv3,您可以将其保留一段时间,然后确认 MTA 正在使用 SSLv3:

#!/bin/sh
egrep "TLS connection established from.*with cipher" /var/log/maillog | awk '{printf("%s %s %s %s\n", $12, $13, $14, $15)}' | sort | uniq -c | sort -

我还没有找到更好的答案;我想采取更细致入微的方法,并能够根据某些 MTA 的连接尝试是否因某些错误而失败,有选择地允许其使用 SSLv3 maillog。欢迎提出所有意见/建议。

相关内容