Dovecot dsync tcps sends incomplete certificate chain
Juri
juri+dovecot at dividebyzero.it
Thu Jan 5 19:55:54 UTC 2017
5 Gennaio 2017 01:21, "John Fawcett" <john at voipsupport.it> wrote:
> On 01/04/2017 08:40 PM, Juri wrote:
>
>> Hi,
>> I'm trying to configure a Dovecot dsync service between two servers, using a tcp+ssl connection and
>> a valid Let's Encrypt certificate.
>> I followed the guide on the wiki (http://wiki.dovecot.org/Replication) using the tcps method, but
>> when I launch the replication it fails writing on the log (/var/log/mail.err):
>> (Server 1 - sync "client" )| Error: sync: Disconnected from remote: Received invalid SSL
>> certificate: unable to get local issuer certificate: /CN=mail.dividebyzero.it
>> (Server 2 - sync "server")| Error: doveadm client disconnected before handshake: <no error>
>>
>> If I try to connect to the server using openssl s_client, on the port 993 (imaps) the server
>> correctly sends the full chain:
>> $ openssl s_client -connect server1.fqdn:993
>> CONNECTED(00000003)
>> depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
>> verify return:1
>> depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
>> verify return:1
>> depth=0 CN = mail.dividebyzero.it
>> verify return:1
>> ---
>> Certificate chain
>> 0 s:/CN=mail.dividebyzero.it
>> i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
>> 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
>> i:/O=Digital Signature Trust Co./CN=DST Root CA X3
>> ...
>>
>> while on the doveadm port it fails:
>> $ openssl s_client -connect server1.fqdn:7557
>> CONNECTED(00000003)
>> depth=0 CN = mail.dividebyzero.it
>> verify error:num=20:unable to get local issuer certificate
>> verify return:1
>> depth=0 CN = mail.dividebyzero.it
>> verify error:num=21:unable to verify the first certificate
>> verify return:1
>> ---
>> Certificate chain
>> 0 s:/CN=mail.dividebyzero.it
>> i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
>> ...
>>
>> I run Dovecot 2.2.13 on Debian 8.6:
>> $ dovecot -n
>> # 2.2.13: /etc/dovecot/dovecot.conf
>> # OS: Linux 3.16.0-4-amd64 x86_64 Debian 8.6
>> auth_default_realm = dividebyzero.it
>> auth_mechanisms = plain login
>> doveadm_password = (redacted)
>> doveadm_port = 7557
>> mail_location = maildir:~/Maildir
>> mail_plugins = " notify replication"
>> namespace inbox { (removed) }
>> passdb {
>> driver = pam
>> }
>> passdb {
>> args = username_format=%n /etc/vmail/%d/passwd
>> driver = passwd-file
>> }
>> plugin {
>> mail_replica = tcps:otherserver.fqdn
>> }
>> protocols = " imap lmtp"
>> service aggregator {
>> fifo_listener replication-notify-fifo {
>> user = dovecot
>> }
>> unix_listener replication-notify {
>> user = dovecot
>> }
>> }
>> service auth {
>> unix_listener auth-client {
>> group = Debian-exim
>> mode = 0660
>> }
>> unix_listener auth-userdb {
>> user = vmail
>> }
>> }
>> service doveadm {
>> inet_listener {
>> port = 7557
>> ssl = yes
>> }
>> }
>> service imap-login {
>> inet_listener imap {
>> port = 143
>> }
>> inet_listener imaps {
>> port = 993
>> ssl = yes
>> }
>> }
>> service replicator {
>> process_min_avail = 1
>> unix_listener replicator-doveadm {
>> mode = 0666
>> }
>> }
>> ssl = required
>> ssl_cert = </etc/letsencrypt/live/mail.dividebyzero.it/fullchain.pem
>> ssl_client_ca_file = /etc/letsencrypt/live/mail.dividebyzero.it/chain.pem
>> ssl_key = </etc/letsencrypt/live/mail.dividebyzero.it/privkey.pem
>> userdb {
>> driver = passwd
>> }
>> userdb {
>> args = uid=vmail gid=vmail home=/var/local/vmail/%d/%n
>> driver = static
>> }
>>
>> Is it a known problem, or has it been resolved in a subsequent version?
>> If it is not, can you suggest me a workaround in the meantime?
>> Thank you.
>
> I would do those test using the -CAfile parameter to be sure of the
> local certificate file being used:
>
> openssl s_client -connect server1.fqdn:993 -CAfile
> /etc/letsencrypt/live/mail.dividebyzero.it/chain.pem
> openssl s_client -connect server1.fqdn:7557 -CAfile
> /etc/letsencrypt/live/mail.dividebyzero.it/chain.pem
>
> You should also be able to see the problem using the verify command directly (on the cert copied
> from the remote server)
> openssl verify -CAfile /etc/letsencrypt/live/mail.dividebyzero.it/chain.pem
> fullchain_copied_from_remote_server.pem
>
> This error happens when the local CA file or directory that is specified
> does not contain the root certificate or the root certificate and
> intermediate ones in the case that the intermediates are not supplied by
> the server. My understanding is that Dovecot supplies the intermediate
> certificates both for replication and imap services if they are in the
> server certificate file. So you should be able to solve this by making
> the root certificate available to Dovecot (parameter
> ssl_client_ca_file). In the worst case you can concatenate the
> intermediate and root certificates.
>
> The certificate you are likely missing is the root certificate:
>
> /O=Digital Signature Trust Co./CN=DST Root CA X3
>
> You can follow the link on this page for it: https://letsencrypt.org/certificates
> (link DST Root CA X3.)
>
> I recently set up replication following the wiki and I think you
> deviated from the instructions at this point:
> "The client must be able to verify that the SSL certificate is valid, so
> you need to specify the directory/file containing valid SSL CA roots:
>
> ssl_client_ca_dir = /etc/ssl/certs # Debian/Ubuntu
> ssl_client_ca_file = /etc/pki/tls/cert.pem # RedHat"
>
> At least when I followed this for Centos using the Redhat setting it worked. The DST root
> certification was already in that file. You might have the same luck by following the indications
> for Debian:
> ssl_client_ca_dir = /etc/ssl/certs (and removing your ssl_client_ca_file setting). If not putting
> the right root or chain into the file is your alternative option.
>
> John
Thank you.
In fact I tried both settings, that is
|ssl_client_ca_dir = /etc/ssl/certs
|ssl_client_ca_file = /etc/letsencrypt/live/mail.dividebyzero.it/chain.pem
but with no luck.
Actually, I noticed that with the two settings I get a slightly different error message (it took me
quite a bit to notice it!), that is:
|Error: sync: Disconnected from remote: Received invalid SSL certificate: unable to get issuer
certificate: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
|Error: sync: Disconnected from remote: Received invalid SSL certificate: unable to get *local*
issuer certificate: /CN=mail.dividebyzero.it
(emphasis mine).
I suppose that in the first case - as the server is sending only the last certificate on the chain
- the client is unable to find the intermediate, while in the second case it won't find the root
one.
I then tried, as you suggested me, to concatenate both the intermediate and the root certificate in
a single file, and it finally worked.
In any case the original point still stands: in the sync mode - at least on my version (2.2.13) -
the server sends only the last cert, so the client has to have the rest of the chain, instead of
needing to have only the root certificate.
May I ask you which is the version of Dovecot bundled with CentOS, to know if this may be a bug
fixed in a newer version?
Juri
More information about the dovecot
mailing list