PHP – Swiftmailer usando STARTTLS y certificados autofirmados

Estoy intentando enviar un correo electrónico con php y swiftmailer, usando STARTTLS, pero obtengo un error de certificado. Tengo acceso de root al servidor SMTP, y el certificado utilizado es autofirmado. Estoy usando Debian en ambas máquinas (servidor web y servidor 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

¿Debo agregar mi propio certificado en alguna parte para que sea aceptado? ¿O es este un error de configuración de OpenSSL?

Swiftmailer ahora se ha actualizado para incluir una opción para esto. Ahora se puede resolver utilizando el método setStreamOptions de su instancia de Swift_SmtpTransport lugar de editar la clase 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))); 

Tengo el mismo problema al usar Swiftmailer en Laravel.

Parece que no hay otra opción para esto en Swiftmailer. La solución limpia sería agregar su propia CA raíz a su servidor y firmar su certificado de servidor de correo con esta CA. El certificado sería válido después de esto. Ver por ejemplo este tutorial .

De todos modos, un truco rápido y sucio que no deberías usar sería editar swiftmailer\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php . En _establishSocketConnection() línea 253 reemplazar:

 $options = array(); 

con algo como esto:

 $options = array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false)); 

Esto cambiará las opciones de SSL de stream_context_create () (unas pocas líneas debajo de $options ):

 $this->_stream = @stream_socket_client($host.':'.$this->_params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options)); 

No necesita editar /vendor archivos. Puede especificar las opciones (no documentadas) en su archivo config/mail.php :

 'stream' => [ 'ssl' => [ 'allow_self_signed' => true, 'verify_peer' => false, 'verify_peer_name' => false, ], ], 

Puede verificarlo usted mismo en el vendor/laravel/framework/src/Illuminate/Mail/TransportManager.php en la línea ~ 50:

 ... if (isset($config['stream'])) { $transport->setStreamOptions($config['stream']); } ... 
Intereting Posts