STARTTLSを使用して、phpとswiftmailerでメールを送信しようとしていますが、証明書エラーが発生します。 SMTPサーバーへのルートアクセス権があり、使用される証明書は自己署名されています。両方のマシン(WebサーバーとSMTPサーバー)でDebianを使用しています
PHP message: PHP Warning: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in [..]/lib/classes/Swift/Transport/StreamBuffer.php on line 97 PHP message: PHP Fatal error: Uncaught exception 'Swift_TransportException' with message 'Unable to connect with TLS encryption' in [..]/lib/classes/Swift/Transport/EsmtpTransport.php:294
自分の証明書をどこかに追加して承認を受ける必要がありますか?または、これはOpenSSL構成エラーですか?
Swiftmailerが更新され、このオプションが含まれるようになりました。 Swiftクラスを編集するのではなく、Swift_SmtpTransport
インスタンスのsetStreamOptions
メソッドを使用して解決できるようになりました。
$transport = Swift_SmtpTransport::newInstance('smtp.server.com', 123, 'tls')
->setUsername('username')
->setPassword('password')
->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false)));
LaravelでSwiftmailerを使用しても同じ問題が発生しました。
Swiftmailerにはこのオプションがないようです。クリーンなソリューションは、独自の ルートCA をサーバーに追加し、このCAでメールサーバー証明書に署名することです。この後、証明書は有効になります。たとえば このチュートリアル を参照してください。
とにかく、使用してはいけない簡単なハックは、_swiftmailer\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php
_を編集することです。 _establishSocketConnection()
253行目で以下を置き換えます。
_$options = array();
_
このようなもので:
_$options = array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false));
_
stream_context_create() の sslオプション が変更されます(_$options
_の下の数行):
_$this->_stream = @stream_socket_client($Host.':'.$this->_params['port'], $errno,
$errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options));
_
/vendor
ファイルを編集する必要はありません。 config/mail.php
ファイルで(ドキュメント化されていない)オプションを指定できます。
'stream' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
],
vendor/laravel/framework/src/Illuminate/Mail/TransportManager.php
の50行目で自分で確認できます。
...
if (isset($config['stream'])) {
$transport->setStreamOptions($config['stream']);
}
...
私にとっては、Mailer.phpファイルに$transport->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false, 'verify_peer_name' => false)));
を追加する必要がありました。以下を参照してください:
/**
* Returns the SMTP transport
*
* @return \Swift_SmtpTransport
*/
protected function getSmtpInstance(): \Swift_SmtpTransport {
$transport = new \Swift_SmtpTransport();
$transport->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10));
$transport->setHost($this->config->getSystemValue('mail_smtphost', '127.0.0.1'));
$transport->setPort($this->config->getSystemValue('mail_smtpport', 25));
if ($this->config->getSystemValue('mail_smtpauth', false)) {
$transport->setUsername($this->config->getSystemValue('mail_smtpname', ''));
$transport->setPassword($this->config->getSystemValue('mail_smtppassword', ''));
$transport->setAuthMode($this->config->getSystemValue('mail_smtpauthtype', 'LOGIN'));
}
$smtpSecurity = $this->config->getSystemValue('mail_smtpsecure', '');
if (!empty($smtpSecurity)) {
$transport->setEncryption($smtpSecurity);
}
$streamingOptions = $this->config->getSystemValue('mail_smtpstreamoptions', []);
if (is_array($streamingOptions) && !empty($streamingOptions)) {
$transport->setStreamOptions($streamingOptions);
}
/* EDIT - allow self-signed mail cert */
$transport->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false, 'verify_peer_name' => false)));
/* EDIT end */
return $transport;
}
これは別のリンクから取得しましたが、今は見つかりません。
私が他の答えに追加したと思う人は、'verify_peer_name' => false