After migrating my Postfix/Dovecot/Roundcube setup to a new server, I encountered a peculiar issue where Roundcube could receive emails via IMAP but failed to send messages through SMTP. The error manifested as:
[02-Jan-2015 16:55:49 America/New_York] STARTTLS failed ():
[02-Jan-2015 16:55:49 -0500]: SMTP Error: SMTP error: Authentication failure: STARTTLS failed
The Postfix logs revealed a critical SSL handshake error:
Jan 2 17:50:01 example postfix/submission/smtpd[19959]: warning: TLS library problem:
error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1292:SSL alert number 48
This indicates the client (Roundcube) couldn't verify the server's certificate because it didn't recognize the Certificate Authority (CA). The SMTP conversation showed:
[02-Jan-2015 17:50:01 -0500]: Recv: 220 2.0.0 Ready to start TLS
[02-Jan-2015 17:50:01 -0500]: Send: RSET
[02-Jan-2015 17:50:01 -0500]: Recv: M I A…\"qhçR¸
The Postfix configuration showed:
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/ssl/private/example.net/example.net.crt
smtpd_tls_key_file = /etc/ssl/private/example.net/example.net.key
smtpd_tls_auth_only = yes
Key observations:
- The server was configured to use opportunistic TLS (security_level=may)
- No CA certificate chain was specified in the configuration
- The submission port (587) required encryption but didn't properly handle certificate verification
Here's how to properly configure Postfix for certificate verification:
# In /etc/postfix/main.cf
smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtpd_tls_cert_file = /etc/ssl/private/example.net/fullchain.pem
smtpd_tls_key_file = /etc/ssl/private/example.net/privkey.pem
smtpd_tls_security_level = encrypt
For Roundcube configuration:
$config['smtp_server'] = 'tls://localhost';
$config['smtp_port'] = 587;
$config['smtp_conn_options'] = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
For production environments, it's better to properly configure CA certificates:
- Combine your certificate and intermediate chain:
- Update Postfix configuration:
cat example.net.crt intermediate.crt > fullchain.pem
smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtpd_tls_cert_file = /etc/ssl/private/example.net/fullchain.pem
smtpd_tls_key_file = /etc/ssl/private/example.net/privkey.pem
Verify your TLS configuration using OpenSSL:
openssl s_client -connect localhost:587 -starttls smtp -showcerts
This should show the complete certificate chain being presented correctly.
For the master.cf submission service, ensure proper TLS settings:
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_auth_only=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
Remember to restart Postfix after making changes:
systemctl restart postfix
When migrating a Postfix/Dovecot/Roundcube setup to a new server, the most frustrating issue is when SMTP authentication fails with TLS errors. The key symptom appears in Postfix logs:
SSL_accept error from localhost[127.0.0.1]: 0
warning: TLS library problem: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
The "unknown ca" alert indicates the client (Roundcube) doesn't trust the certificate presented by Postfix. This typically occurs when:
- The certificate chain is incomplete
- Intermediate certificates are missing
- System CA bundle isn't properly configured
First, verify your certificate chain:
openssl verify -CApath /etc/ssl/certs /etc/ssl/private/example.net/example.net.crt
For Postfix, ensure your main.cf includes:
smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtpd_tls_CApath = /etc/ssl/certs
smtpd_tls_cert_file = /etc/ssl/private/example.net/fullchain.pem
smtpd_tls_key_file = /etc/ssl/private/example.net/privkey.pem
Modify your Roundcube config.inc.php:
$config['smtp_server'] = 'tls://localhost';
$config['smtp_port'] = 587;
$config['smtp_conn_options'] = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
Use OpenSSL to test the SMTP handshake:
openssl s_client -connect localhost:587 -starttls smtp -debug
This should show the complete certificate chain being presented. If you see "Verify return code: 20 (unable to get local issuer certificate)", you need to install intermediate certificates.
Ensure your submission service has proper TLS settings:
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=may
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_cert_file=/etc/ssl/private/example.net/fullchain.pem
-o smtpd_tls_key_file=/etc/ssl/private/example.net/privkey.pem
After making these changes, restart both Postfix and your web server, then test SMTP authentication again through Roundcube.