Полное название должно быть «PHP - отправка сообщений электронной почты: fwrite (): операция SSL не выполнена с кодом 1. Сообщения об ошибках OpenSSL: ошибка: 1420C0CF: процедуры SSL: ssl_write_internal: протокол выключен - проанализируйте stream_socket_enable_crypto, возвращая false». Но это было слишком долго для 150 символов заголовка.
Мы пытаемся отправить электронное письмо в сценарии PHP, и мы получаем
Warning: fwrite(): SSL operation failed with code 1. OpenSSL Error messages:error:1420C0CF:SSL routines:ssl_write_internal:protocol is shutdown in <...>/vendor/recolize/zendframework1/library/Zend/Mail/Protocol/Abstract.php on line 324
Как видно выше, мы использование версии адаптации давно устаревшего zendframework1, но это не проблема, так как это работает на двух других хостерах.
Поскольку проблема не детерминирована c, у нас нет способа воспроизвести ее правильно сейчас.
Однако у нас есть тестовый скрипт, который позволяет провести некоторый анализ, но мне нужна помощь, чтобы понять, в чем может быть проблема.
Без лишних слов:
Мы используя сценарий из ответа на этот стек: Как проверить, действителен ли сертификат TLS SMTP в PHP? - Ответ 1
Важная часть заключается в следующем:
// Establish the connection
$smtp = fsockopen( "tcp://$server", 25, $errno, $errstr );
fread( $smtp, 512 );
// Here you can check the usual banner from $server (or in general,
// check whether it contains $server's domain name, or whether the
// domain it advertises has $server among its MX's.
// But yet again, Google fails both these tests.
fwrite($smtp,"HELO $myself\r\n");
fread($smtp, 512);
// Switch to TLS
fwrite($smtp,"STARTTLS\r\n");
fread($smtp, 512);
stream_set_blocking($smtp, true);
stream_context_set_option($smtp, 'ssl', 'verify_peer', true);
stream_context_set_option($smtp, 'ssl', 'allow_self_signed', true);
stream_context_set_option($smtp, 'ssl', 'capture_peer_cert', true);
stream_context_set_option($smtp, 'ssl', 'cafile', $cabundle);
// Necessary block to circumvent https://www.php.net/manual/en/function.stream-socket-enable-crypto.php#119122
$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
}
$secure = stream_socket_enable_crypto($smtp, true, $crypto_method);
// $secure = stream_socket_enable_crypto($smtp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT );
var_dump($secure);
die;
Установлен сокет, установлено блокирование, заданы параметры SSL и сделана попытка запустить шифрование с использованием PHP s stream_socket_enable_crypto .
stream_socket_enable_crypto, однако возвращает bool (false) и никакой информации о том, почему он не работает.
В настоящее время мы подозреваем, что проверка сертификата почтового сервера не удается, но мы не можем проанализировать его.
Как получить дополнительную информацию, почему stream_socket_enable_crypto возвращает false?
edit1:
Адаптирован код блок выше, чтобы отразить специальность STREAM_CRYPTO_METHOD_TLS_CLIENT, начиная с PHP 5.6.7 , как указано @Dilek ниже. Спасибо за ответ! К сожалению, это не изменило общий результат. $ secure остается bool (false).
edit2:
В ответ на ОБНОВЛЕНИЕ @ Dilek:
$ php ssl_test.php
Array
(
[ssl] => Array
(
[verify_host] => 1
[verify_peer] => 1
[allow_self_signed] =>
[cafile] => /etc/ssl/cert.pem
)
)
failed to connect securely
Я убедился, что кафе существует :
$ ll /etc/ssl/cert.pem
0 lrwxrwxrwx 1 root wheel 38 Dec 19 11:09 /etc/ssl/cert.pem -> /usr/local/share/certs/ca-root.crt
и быстро проверил его содержимое, которое выглядит нормально:
Certificate:
Data:
Version: ...
Serial Number:
...
Signature Algorithm: ...
Issuer: ...
...
Signature Algorithm: ...
-----BEGIN CERTIFICATE-----
MI...6EULg==
-----END CERTIFICATE-----
Certificate:
Data:
Version: ...
Serial Number:
...
etc.