Php – Roundcube + Dovecot: SSL errors when trying to log in

imapPHProundcubessl

I'm setting up a mailserver using Dovecot 2.2.13, Postfix 2.11.3, and with Roundcube 1.1.1 connecting to it. Roundcube is running on a different server in nginx/php-fpm. Both servers are running Debian Jessie with the latest updates and can ping eachother. A nmap from Roundcube's host shows port 993 open and accessible. Also, I seem to get a connection on the right ports, but I cannot seem to get Roundcube to connect to Dovecot successfully.

Dovecot is configured with the following SSL settings running on port 993:

/etc/dovecot/conf.d/10-ssl.conf

ssl_protocols = TLSv1.2 TLSv1.1 TLSv1 !SSLv2 !SSLv3
ssl_cipher_list = ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES128:DH+AES:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5

/etc/dovecot/dovecot.conf

auth_verbose=yes
auth_debug=yes
auth_debug_passwords=yes
mail_debug=yes
verbose_ssl=yes
auth_verbose_passwords=plain

With these settings I'm able to get a TLS connection from the Android mail app and recieve mails so I know Dovecot is listening and capable of communicating. Roundcube is hosted on a different server from Dovecot and is configured with the following settings with regard to IMAPS.

$config['default_host'] = 'tls://mail.domain.tld';
$config['imap_conn_options'] => array(
    'ssl' => array(
        'ciphers' => 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES128:DH+AES:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5',
    ),
);

The successful login looks something like this in mail.log:

dovecot: imap-login: Debug: SSL: elliptic curve secp384r1 will be used for ECDH and ECDHE key exchanges
dovecot: imap-login: Debug: SSL: elliptic curve secp384r1 will be used for ECDH and ECDHE key exchanges
dovecot: imap-login: Debug: SSL: where=0x10, ret=1: before/accept initialization [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: before/accept initialization [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2002, ret=-1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2002, ret=-1: unknown state [zzz.zzz.zzz.zzz]
dovecot: auth: Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth
dovecot: auth: Debug: Read auth token secret from /var/run/dovecot/auth-token-secret.dat
dovecot: auth: Debug: auth client connected (pid=5986)
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: unknown state [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x20, ret=1: SSL negotiation finished successfully [zzz.zzz.zzz.zzz]
dovecot: imap-login: Debug: SSL: where=0x2002, ret=1: SSL negotiation finished successfully [zzz.zzz.zzz.zzz]

Whereas an unsuccessful one looks like this in mail.log:

dovecot: imap-login: Debug: SSL: elliptic curve secp384r1 will be used for ECDH and ECDHE key exchanges
dovecot: imap-login: Debug: SSL: elliptic curve secp384r1 will be used for ECDH and ECDHE key exchanges
dovecot: auth: Debug: auth client connected (pid=5993)
dovecot: imap-login: Debug: SSL: where=0x10, ret=1: before/accept initialization [xxx.xxx.xxx.xxx]
dovecot: imap-login: Debug: SSL: where=0x2001, ret=1: before/accept initialization [xxx.xxx.xxx.xxx]
dovecot: imap-login: Debug: SSL: where=0x202, ret=-1: SSLv2/v3 read client hello A [xxx.xxx.xxx.xxx]
dovecot: imap-login: Disconnected (no auth attempts in 60 secs): user=<> rip=xxx.xxx.xxx.xxx, lip=yyy.yyy.yyy.yyy, TLS handshaking: Disconnected, session=<xxxxxxxxxxxxxx>

The error that Roundcube logs is:

<sj148mqa> IMAP Error: Login failed for firstname.lastname@domain.tld from xxx.xxx.xxx.xxx. Empty startup greeting (mail.domain.tld:993) in /var/www/roundcube/program/lib/Roundcube/rcube_imap.php on line 198 (POST /roundcube/?_task=login?_task=login&_action=login)

What it seems like is that Roundcube is ignoring my tls:// directive and trying to connect to Dovecot using SSLv2/v3 which Dovecot is set to ignore. So while Dovecot waits for Roundcube to start TLS handshaking, Roundcube is waiting for a server greeting that is never coming. Is there any way to configure Roundcube to connect successfully? Have I missed something very simple in my configuration setup?

EDIT:

At Paul's suggestion I tried opening port 143 and allowing Roundcube to use STARTTLS. I was able to get a connection but only if verify_peer was disabled. Changing the values of verify_peer_name and adding the path to both the CA chain associated with the mailserver and the chained mailserver certificate did not allow me to get a connection with verify_peer=true.

I believe this means that there's an issue with my SSL certificate matching my hostname. There are two DNS entries for the mailserver pointing to the same address one for hostname.domain.tld and one for mail.domain.tld. Could this be causing the peer verification to fail?

Best Answer

The different meaning of tls:// and ssl:// in $config['default_host'] is unfortunately not documented.

  • tls:// means usage of STARTTLS, thus usually port 143
  • ssl:// means usage of TLS, thus usually port 993

  • The same is valid for $config['smtp_server'] and ports 25 and 587 for tls://, ports 465 for ssl://.

Can't give any source for this information, as I (and some others) got it empirically.


And for the verify_peer issue, first look at the cert that is served. E.g. using this command from the connecting machine:

echo | openssl s_client -connect mail.fizeau.net:143 -starttls imap -showcerts 2>&1 | openssl x509 -noout -text | egrep 'Subject: |DNS:'

This will show you the domains, the cert was issued for.