我正在尝试使用PHPMailer通过TLS上的SMTP发送电子邮件。
我发现,当PHPMailer尝试连接到SMTP服务器并调用STARTTLS时,连接会立即失败-除非我在打开SMTP连接时设置PHP SSL context variable verify_peer_name => false
。
我要连接的SMTP服务器是prefix.myredactedcompany.mailguard.com.au:2525
。查看SMTP日志,我发现当我要求连接到prefix.myredactedcompany.mailguard.com.au:2525
时,实际上已经连接到someotherhost.mailguard.com.au
。我认为这是负载均衡器或其他群集设置的结果。
当我通过运行命令echo QUIT | .\openssl.exe s_client -starttls smtp -crlf -connect prefix.myredactedcompany.mailguard.com.au:2525
按照PHPMailer故障排除指南对test the OpenSSL connection outside of PHP进行操作时,会得到以下结果:
CONNECTED(000001E0)
---
Certificate chain
0 s:/C=AU/postalCode=3006/ST=VIC/L=SOUTHBANK/street=198 NORMANBY RD/O=MailGuard Pty Ltd/OU=Netops/OU=PremiumSSL Wildcard/CN=*.mailguard.com.au
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIF0jCCBLqgAwIBAgIQI1raes2jQvcAbHxOBIAtqTANBgkqhkiG9w0BAQsFADCB
... snip ...
pYwh4eDZtcm4tZQfc71R1KhA9ci5A0G9ewPLmZUYoDlguNdlNlVf07aus54EV6XI
1wHfJ/xs
-----END CERTIFICATE-----
subject=/C=AU/postalCode=3006/ST=VIC/L=SOUTHBANK/street=198 NORMANBY RD/O=MailGuard Pty Ltd/OU=Netops/OU=PremiumSSL Wildcard/CN=*.mailguard.com.au
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5395 bytes and written 468 bytes
---
New, TLSv1/SSLv3, 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: redacted
Session-ID-ctx:
Master-Key: redacted
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - 18 ad e7 c2 c9 46 ab 96-5f 58 03 81 fc 48 3c 18 .....F.._X...H<.
... snip ...
0090 - 41 47 9b f2 60 c4 41 5f-0d fc ea 2b 40 0c 25 3b AG..`.A_...+@.%;
Start Time: 1549441609
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---
PHPMailer故障排除指南指出,在这种情况下
verify error:num=20:unable to get local issuer certificate
没问题。
对于我来说,这似乎是mailguard.com.au
的所有子域的有效通配符证书。为什么PHPMailer / OpenSSL拒绝它,除非我关闭对等名称验证?是因为实际的SMTP主机名与我在建立出站连接时使用的DNS名称不匹配吗?
如果我关闭对等名称验证,那会使我面临哪些安全风险?
版本:
一个评论者询问当直接连接到池中的主机之一时,openssl连接的结果如何。极为相似:
CONNECTED(000001F8)
---
Certificate chain
0 s:/C=AU/postalCode=3006/ST=VIC/L=SOUTHBANK/street=198 NORMANBY RD/O=MailGuard Pty Ltd/OU=Netops/OU=PremiumSSL Wildcard/CN=*.mailguard.com.au
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIF0jCCBLqgAwIBAgIQI1raes2jQvcAbHxOBIAtqTANBgkqhkiG9w0BAQsFADCB
...snip...
pYwh4eDZtcm4tZQfc71R1KhA9ci5A0G9ewPLmZUYoDlguNdlNlVf07aus54EV6XI
1wHfJ/xs
-----END CERTIFICATE-----
subject=/C=AU/postalCode=3006/ST=VIC/L=SOUTHBANK/street=198 NORMANBY RD/O=MailGuard Pty Ltd/OU=Netops/OU=PremiumSSL Wildcard/CN=*.mailguard.com.au
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5399 bytes and written 468 bytes
---
New, TLSv1/SSLv3, 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: redacted
Session-ID-ctx:
Master-Key: redacted
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - 6d bd 68 e7 44 29 72 ea-99 00 c8 84 a6 cc 45 76 m.h.D)r.......Ev
... snip ...
0090 - 28 73 65 a4 a1 24 fd c6-18 ad fb 13 26 ec 6f b9 (se..$......&.o.
Start Time: 1549519771
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---
好吧,因此php.ini
中的注释说空的openssl.cafile
设置将导致PHP使用操作系统管理的证书存储。在Windows上,这似乎是不正确的,因为OpenSSL不具有对Windows证书存储的内置支持。因此,我按照PHP - SSL certificate error: unable to get local issuer certificate中的说明进行了操作,以建立本地根CA捆绑包。这似乎现在正在工作。当我运行上面给出的OpenSSL测试命令并附加-CAfile C:\xampp\extras\cacert.pem
时,最终结果现在是Verify return code: 0 (ok)
而不是Verify return code: 20 (unable to get local issuer certificate)
。
我重新启动了Apache,并检查了phpinfo()中openssl.cafile
的值是否正确。但是PHPMailer仍然无法成功启动STARTTLS。症状与以前相同-如果我将SSL上下文变量verify_peer_name
设置为false,则PHPMailer成功连接。如果我将verify_peer_name
保持打开状态,则在STARTTLS期间连接会失败。
我仍然想知道:
verify_peer_name
对安全有何影响?我假设这将使MITM连接变得容易。答案 0 :(得分:1)
可能是因为通配符仅在单个级别上匹配,即prefix.myredactedcompany.mailguard.com.au
与*.mailguard.com.au
不匹配。使用报告的名称(在连接时看到)可以帮助解决该问题。
或者,这可能取决于PHP使用的CA证书捆绑包,这意味着服务器可以正常运行,但是您无法正确验证其证书-这通常很难诊断,因为它可能很容易分辨出其中的位置您的连锁店验证失败。例如,如果您的连锁店是:
host cert -> intermediate cert -> root (CA) cert
其中任何一个验证失败都会导致验证失败,但是可能不清楚哪个是错误的。
您可能需要获取最新的CA证书包的副本,并告诉PHP使用它(如the PHPMailer troubleshooting guide中所述),或使用Certainty之类的包从您的应用程序中对其进行管理。
也可能是您的中间证书顺序错误。