Я пытаюсь использовать PHPMailer для отправки писем по SMTP через TLS.
Я обнаружил, что, когда PHPMailer пытается подключиться к SMTP-серверу и вызывается STARTTLS, соединение сразу прерывается — если я не установлю PHP SSL контекстная переменная verify_peer_name => false
при открытии SMTP-соединения.
SMTP-сервер, к которому я подключаюсь, prefix.myredactedcompany.mailguard.com.au:2525
, Глядя на логи SMTP, я вижу, что когда я прошу подключиться к prefix.myredactedcompany.mailguard.com.au:2525
Я на самом деле подключаюсь к someotherhost.mailguard.com.au
, Я предполагаю, что это результат балансировки нагрузки или другой кластерной установки.
Когда я следую руководству по устранению неполадок PHPMailer, проверить соединение OpenSSL вне PHP запустив команду echo QUIT | .\openssl.exe s_client -starttls smtp -crlf -connect prefix.myredactedcompany.mailguard.com.au:2525
Я получаю следующие результаты:
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: невозможно получить сертификат локального эмитента чтобы настроить локальный корневой CA-пакет. Кажется, сейчас это работает. Когда я запускаю тестовую команду OpenSSL, приведенную выше, и добавляю -CAfile C:\xampp\extras\cacert.pem
, конечный результат сейчас Verify return code: 0 (ok)
вместо Verify return code: 20 (unable to get local issuer certificate)
,
Я перезапустил Apache и проверил значение openssl.cafile
в phpinfo () это хорошо. Но PHPMailer по-прежнему не будет успешно STARTTLS. Симптомы те же, что и раньше — если я устанавливаю переменную контекста SSL verify_peer_name
в false PHPMailer успешно подключается. Если я уйду verify_peer_name
включен, соединение разрывается во время STARTTLS.
Мне все еще интересно знать:
verify_peer_name
? Я предполагаю, что это облегчит MITM соединение.Это может быть потому, что подстановочные знаки совпадают только на одном уровне, т.е. prefix.myredactedcompany.mailguard.com.au
не совпадает *.mailguard.com.au
, Использование указанного имени (видно при подключении) должно помочь решить эту проблему.
В качестве альтернативы это может быть связано с набором сертификатов CA, который использует PHP, что означает, что с сервером все в порядке, но вы не можете правильно проверить его сертификаты — это часто трудно диагностировать, потому что может быть сложно определить, где в вашей цепочке находится проверка не проходит. Например, если ваша цепочка:
host cert -> intermediate cert -> root (CA) cert
Ошибка проверки в любом из них приведет к ошибке проверки, но может быть неясно, какой из них неправильный.
Вам может потребоваться получить копию последнего пакета сертификатов CA и сказать PHP использовать его (как описано в руководство по устранению неполадок PHPMailer), или используйте пакет как уверенность управлять им из вашего приложения.
Также может быть, что ваши промежуточные сертификаты находятся в неправильном порядке.
Других решений пока нет …