J'essaie d'envoyer un e-mail avec php et swiftmailer, en utilisant STARTTLS, mais je reçois une erreur de certificat. J'ai un accès root au serveur SMTP et le certificat utilisé est auto-signé. J'utilise Debian sur les deux machines (serveur web et serveur smtp)
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
Dois-je ajouter mon propre certificat quelque part pour le faire accepter? Ou s'agit-il d'une erreur de configuration OpenSSL?
Swiftmailer a maintenant été mis à jour pour inclure une option pour cela. Il peut maintenant être résolu en utilisant la méthode setStreamOptions
de votre Swift_SmtpTransport
plutôt que de modifier la classe Swift.
$transport = Swift_SmtpTransport::newInstance('smtp.server.com', 123, 'tls')
->setUsername('username')
->setPassword('password')
->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false)));
J'ai eu le même problème en utilisant Swiftmailer dans Laravel.
Il semble qu'il n'y ait aucune option pour cela dans Swiftmailer. Une solution propre serait d'ajouter votre propre autorité de certification racine à votre serveur et de signer votre certificat de serveur de messagerie avec cette autorité de certification. Le certificat serait valide après cela. Voir par exemple ce tutoriel .
Quoi qu'il en soit, un hack sale rapide que vous ne devriez pas utiliser serait de modifier swiftmailer\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php
. Dans _establishSocketConnection()
ligne 253, remplacez:
$options = array();
avec quelque chose comme ça:
$options = array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false));
Cela changera les options ssl de stream_context_create () (quelques lignes en dessous de $options
)):
$this->_stream = @stream_socket_client($Host.':'.$this->_params['port'], $errno,
$errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options));
Vous n'avez pas besoin de modifier /vendor
des dossiers. Vous pouvez spécifier des options (non documentées) dans votre config/mail.php
fichier:
'stream' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
],
Vous pouvez le vérifier vous-même dans vendor/laravel/framework/src/Illuminate/Mail/TransportManager.php
en ligne ~ 50:
...
if (isset($config['stream'])) {
$transport->setStreamOptions($config['stream']);
}
...
Pour moi, j'ai dû ajouter $transport->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false, 'verify_peer_name' => false)));
au fichier Mailer.php, voir:
/**
* 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;
}
Je l'ai obtenu d'un autre lien, je ne le trouve pas maintenant.
On pense que j'ai fait un supplément aux autres réponses était de spécifier le 'verify_peer_name' => false