I have been running a postfix/dovecot mail server with no issue for several years using SSL/TLS and Let's Encrypt issued server certificates:
/etc/dovecot/conf.d/10-ssl.conf
ssl = required
# Bundle containing the public server certificate followed by the chain of intermediate Let's encrypt CA certificates
ssl_cert = </etc/ssl/fullchain.pem
ssl_key = </etc/ssl/key.pem
I'm trying now to modify dovecot setup to accept only client certificates created with a private CA since, as you probably already know, let's encrypt does not issue client certificates:
/etc/dovecot/conf.d/10-auth.conf
auth_ssl_require_client_cert = yes
/etc/dovecot/conf.d/10-ssl.conf
ssl_verify_client_cert = yes
# Bundle containing the private CA certificate followed by the matching CRL
ssl_ca = </etc/ssl/CA_Certificate_CRL_bundle.pem
When I try to connect to the server with a client (evolution), I get a
connection error: Client did not present valid SSL certificate
, except that it is valid:
openssl x509 -enddate -noout -in client.crt
notAfter=Jul 22 16:21:07 2032 GMT
When I try to test manually the connection, I get a Verification: OK
:
openssl s_client -connect ${fqdn}:993 -cert client.crt -key client_key.pem -CApath /etc/ssl/certs -state -debug
Enter pass phrase for client_key.pem:
CONNECTED(00000003)
SSL_connect:before SSL initialization
...
SSL_connect:SSLv3/TLS write client hello
...
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
SSL_connect:SSLv3/TLS write change cipher spec
...
SSL_connect:SSLv3/TLS write client hello
...
SSL_connect:SSLv3/TLS write client hello
...
SSL_connect:SSLv3/TLS read server hello
...
SSL_connect:TLSv1.3 read encrypted extensions
...
SSL_connect:SSLv3/TLS read server certificate request
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = *.<domain>
verify return:1
...
SSL_connect:SSLv3/TLS read server certificate
SSL_connect:TLSv1.3 read server certificate verify
SSL_connect:SSLv3/TLS read finished
SSL_connect:SSLv3/TLS write client certificate
SSL_connect:SSLv3/TLS write certificate verify
...
SSL_connect:SSLv3/TLS write finished
---
Certificate chain
0 s:CN = *.<domain>
i:C = US, O = Let's Encrypt, CN = R3
a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
v:NotBefore: Jul 2 10:04:12 2022 GMT; NotAfter: Sep 30 10:04:11 2022 GMT
1 s:C = US, O = Let's Encrypt, CN = R3
i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Sep 4 00:00:00 2020 GMT; NotAfter: Sep 15 16:00:00 2025 GMT
2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
i:O = Digital Signature Trust Co., CN = DST Root CA X3
a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
v:NotBefore: Jan 20 19:14:03 2021 GMT; NotAfter: Sep 30 18:14:03 2024 GMT
---
Server certificate
...
subject=CN = *.<domain>
issuer=C = US, O = Let's Encrypt, CN = R3
---
Acceptable client certificate CA names
C = <country>, ST = <region>, O = <org>
Requested Signature Algorithms: ...
Shared Requested Signature Algorithms: ...
Peer signing digest: ...
Peer signature type: ...
Server Temp Key: ...
---
SSL handshake has read 5418 bytes and written 2986 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 4096 bit
...
Verify return code: 0 (ok)
...
SSL_connect:SSL negotiation finished successfully
SSL_connect:SSL negotiation finished successfully
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
...
---
SSL_connect:SSLv3/TLS read server session ticket
...
SSL_connect:SSL negotiation finished successfully
SSL_connect:SSL negotiation finished successfully
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
...
---
SSL_connect:SSLv3/TLS read server session ticket
...
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN] Dovecot (Ubuntu) ready.
DONE
...
Am I missing something?
EDIT:
Despite the fact that openssl s_client
returns Verification: OK
, dovecot is not happy with the client certificate:
dovecot: auth: plain(?,<IP address>,<ID>): Client didn't present valid SSL certificate
dovecot: auth: Debug: client passdb out: FAIL#0111#011reason=Client didn't present valid SSL certificate
This is the same errors that dovecot throws when trying to connect from:
- openssl
- evolution
- thunderbird.
I have been able to successfully validate locally the PKCS#12 equivalent of client.crt:
openssl pkcs12 -info -in client.pfx
I don't know how to validate locally the client certificate against the self-signed CA certificate with openssl.
It seems that there is an issue with dovecot.
Has anyone been able to successfully configure such a setup - a public certificate for the IMAPs server alongside a private self-signed CA for the client certificates?