Please Help: Dovecot ssl_ca selection based on remote IP address filtering not working.
Hi All,
I hope this is the correct place to post this. If not, apologies.
I am in the process of updating my company's email servers and am trying to put Dovecot into an Alpine Linux container, hosted on ProxMox.
In my setup, local mail deliveries via LMTP can come from the MSA (for intra-company mail) and an MTA (for inbound mail).
The LMTP data is sent over IPv4 and is protected by TLS. Client certificates are used to authenticate sources.
I wanted to prevent Dovecot from accepting LMTP from any other source and the method I came up with to do this was to use filtering on the "remote" address.
I would create a "Fake" CA that had never signed a certificate and use that to evaluate the certificate presented by incoming connections from addresses other than the two legitimate sources.
This would cause all connections from "bad" addresses to be rejected. This seemed simple enough on paper but Dovecot just isn't playing along.
It seems that no matter what I do, I cannot get "remote" filtering to switch the "ssl_ca" parameter. I have put together a test bed to demonstrate.
I then use openssl s_client to attempt to connect to the test bed container.
I've attached the instructions to build the test bed from scratch.
In all cases s_client reports "Acceptable client certificate CA names" "CN = Fake CA"
I.e. it want's a certificate from the CA that has never signed a certificate and never will.
Why not do the obvious thing?
I use LDAP to authenticate individual users and the user name will be reported over LMTP.
So to use the normal authentication mechanisms to authenticate the connection source, I would need to do two LDAP lookups, one for the connecting machine and one for the mail recipient.
It is not clear if this is possible from the documentation..
*Questions:*
Is config file filtering broken or am I doing it wrong?
Is it possible to provide a different "ssl_ca" based on the remote IP address?
Is there an easier way to restrict LMTP connections to specific remote IP addresses?
p.s.
Filtering just doesn't work like it's supposed to. Someone should look at that (especially multi-level) ..
See this: https://dovecot.org/pipermail/dovecot/2016-June/104770.html
Any help would be greatly appreciated. I am at my wits' end with this.
-- This email has been checked for viruses by AVG antivirus software. www.avg.com
To follow up on my previous email,
It seems the lmtp deamon does NOT support ssl_ca selection based on remote IP. It also does NOT seem to support authorization. The solution I arrived at was to create a separate CA, used solely for the purpose of authorizing LDAP clients.
openssl genpkey-algorithm rsa-pkeyopt rsa_keygen_bits:4096 -out /etc/ssl/private/ca_dovecot_lmtps.key openssl req-x509 -new -subj '/CN=Dovecot LMTP Authorization CA' -key /etc/ssl/private/ca_dovecot_lmtps.key-nodes -sha256 -days 3650 -addext 'keyUsage=keyCertSign,cRLSign' -out /etc/ssl/private/ca_dovecot_lmtps.pem
This CA can then be used to sign certificates for LMTP clients to use when delivering mail.
export lmtpsrc=msa openssl genpkey-algorithm rsa-pkeyopt rsa_keygen_bits:2048 -out /etc/ssl/private/_lmtp.${lmtpsrc}.example.com.key openssl req-new -nodes -key /etc/ssl/private/_lmtp.${lmtpsrc}.example.com.key-sha256 -out /etc/ssl/private/_lmtp.${lmtpsrc}.example.com.csr-subj "/CN=${lmtpsrc}.example.com" cat <<EOF >/etc/ssl/private/_lmtp.${lmtpsrc}.example.com.ext basicConstraints = critical, CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = DNS:${lmtpsrc}.example.com subjectKeyIdentifier =hash authorityKeyIdentifier = keyid:always, issuer:always EOF openssl x509-req -CA /etc/ssl/private/ca_dovecot_lmtp.pem-CAkey /etc/ssl/private/ca_dovecot_lmtp.key-sha256 -days 3650 -in /etc/ssl/private/_lmtp.${lmtpsrc}.example.com.csr-extfile /etc/ssl/private/_lmtp.${lmtpsrc}.example.com.ext-out /etc/ssl/private/_lmtp.${lmtpsrc}.example.com.pem
The Dovecot configuration looks like this
protocol lmtp { mail_uid = nobody auth_ssl_require_client_cert = yes ssl_verify_client_cert = yes ssl_ca = </etc/ssl/private/ca_dovecot_lmtps.pem
ssl = required ssl_cert = </etc/ssl/mda.example.com-chain.pem ssl_key = </etc/ssl/private/mda.example.com.key ssl_require_crl = no }
This solution seems secure and manageable so long as the number of LMTP sources stays small, but overall, feels very unsatisfactory.
I would regard Dovecot's inability to inspect the LMTP certificate's subject name as a BUG that should be prioritized.
As it stands, I would not be surprised to find real-world deployments of Dovecot that are insecure, as _ANY_ host with a valid certificate could originate mail. As a quick illustration, I created another certificate with an invalid name from my "/CN=Dovecot LMTP Authorization CA" authority. The mail was accepted without complaint. In "normal" setups, a certificate from any public CA would be accepted.
Feb 11 14:29:52 imaps mail.info dovecot: lmtp(16386): Received valid SSL certificate: /CN=Dovecot LMTP Authorization CA Feb 11 14:29:52 imaps mail.info dovecot: lmtp(16386): Received valid SSL certificate: /CN=evil.example.com Feb 11 14:29:52 imaps mail.debug dovecot: lmtp(16386): Debug: SSL: where=0x2001, ret=1: SSLv3/TLS read client certificate Feb 11 14:29:52 imaps mail.debug dovecot: lmtp(16386): Debug: SSL: where=0x2001, ret=1: SSLv3/TLS read certificate verify Feb 11 14:29:52 imaps mail.debug dovecot: lmtp(16386): Debug: SSL: where=0x2001, ret=1: SSLv3/TLS read finished Feb 11 14:29:52 imaps mail.debug dovecot: lmtp(16386): Debug: SSL: where=0x20, ret=1: SSLv3/TLS write session ticket Feb 11 14:29:52 imaps mail.debug dovecot: lmtp(16386): Debug: SSL: where=0x2001, ret=1: SSLv3/TLS write session ticket Feb 11 14:29:52 imaps mail.debug dovecot: lmtp(16386): Debug: SSL: where=0x2001, ret=1: SSLv3/TLS write session ticket Feb 11 14:29:52 imaps mail.debug dovecot: lmtp(16386): Debug: SSL: where=0x2002, ret=1: SSL negotiation finished successfully
-- This email has been checked for viruses by AVG antivirus software. www.avg.com
participants (1)
-
Sean Gallagher