Sean Gallagher
2023-Feb-09 05:23 UTC
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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <https://dovecot.org/pipermail/dovecot/attachments/20230209/3de76c26/attachment.htm> -------------- next part -------------- Reference: https://dovecot.org/pipermail/dovecot/2016-June/104770.html Create ProxMox container vmid=114 "dove" with IP address 192.168.61.214/24 Alpine Linux: alpine-3.15-default_20211202_amd64.tar.xz # n.b. this mirror has dovecot 2.3.20 /sbin/setup-apkrepos http://mirror.aarnet.edu.au/pub/alpine/latest-stable/main/ http://mirror.aarnet.edu.au/pub/alpine/latest-stable/community/ apk -U upgrade apk add dovecot dovecot-lmtpd uname -a Linux dove 5.4.162-1-pve #1 SMP PVE 5.4.162-2 (Thu, 20 Jan 2022 16:38:53 +0100) x86_64 Linux cat /etc/alpine-release 3.17.1 dovecot --version 2.3.20 (80a5ac675d) # Create Real and Fake certificate authorities and have the Real CA sign certificates for dove.example.com and smtp.example.com cd /etc/ssl/dovecot/ openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out ca_fake.key openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out ca_real.key openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out imap.key openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out smtp.key openssl req -x509 -new -subj '/CN=Fake CA' -key ca_fake.key -nodes -sha256 -days 3650 -addext 'basicConstraints=critical,CA:TRUE' -addext 'keyUsage=keyCertSign,cRLSign' -out ca_fake.pem openssl req -x509 -new -subj '/CN=Real CA' -key ca_real.key -nodes -sha256 -days 3650 -addext 'basicConstraints=critical,CA:TRUE' -addext 'keyUsage=keyCertSign,cRLSign' -out ca_real.pem openssl req -new -nodes -key imap.key -sha256 -out imap.csr -subj '/CN=imap.example.com' cat <<\EOF >imap.ext basicConstraints = critical, CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = DNS:imap.example.com EOF openssl x509 -req -CA ca_real.pem -CAkey ca_real.key -sha256 -days 365 -in imap.csr -extfile imap.ext -out imap.pem openssl req -new -nodes -key smtp.key -sha256 -out smtp.csr -subj '/CN=smtp.example.com' cat <<\EOF >smtp.ext basicConstraints = critical, CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = DNS:smtp.example.com EOF openssl x509 -req -CA ca_real.pem -CAkey ca_real.key -sha256 -days 365 -in smtp.csr -extfile smtp.ext -out smtp.pem # Dovecot Absolute Minimum Config cd /etc/dovecot mv dovecot.conf dovecot.conf.orig cat <<\END_CONF >dovecot.conf protocols = lmtp listen = 192.168.61.214 service lmtp { inet_listener lmtp { address = 192.168.61.214 port = 24 ssl = yes } } ssl = required ssl_cert = </etc/ssl/dovecot/imap.pem ssl_key = </etc/ssl/dovecot/imap.key ssl_client_ca_file = /etc/ssl/dovecot/ca_real.pem ssl_client_cert = </etc/ssl/dovecot/imap.pem ssl_client_key = </etc/ssl/dovecot/imap.key ssl_require_crl = no auth_ssl_require_client_cert = yes # multi-level filters appear to be broken. Not a huge problem # the MTA will never talk IMAP and MUAs will never talk LMTP # but still annoying :(( remote 192.168.61.214/0 { #protocol lmtp { ssl_verify_client_cert = yes ssl_ca = </etc/ssl/dovecot/ca_fake.pem #} } remote 192.168.61.207 { #protocol lmtp { ssl_verify_client_cert = yes ssl_ca = </etc/ssl/dovecot/ca_real.pem #} } END_CONF doveconf -n # 2.3.20 (80a5ac675d): /etc/dovecot/dovecot.conf # OS: Linux 5.4.162-1-pve x86_64 # Hostname: dove.teletech.com.au auth_ssl_require_client_cert = yes listen = 192.168.61.214 protocols = lmtp service lmtp { inet_listener lmtp { address = 192.168.61.214 port = 24 ssl = yes } } ssl = required ssl_ca = </etc/ssl/dovecot/ca_fake.pem ssl_cert = </etc/ssl/dovecot/imap.pem ssl_client_ca_file = /etc/ssl/dovecot/ca_real.pem ssl_client_cert = </etc/ssl/dovecot/imap.pem ssl_client_key = # hidden, use -P to show it ssl_key = # hidden, use -P to show it ssl_require_crl = no ssl_verify_client_cert = yes ssl_ca = </etc/ssl/dovecot/ca_fake.pem ssl_verify_client_cert = yes remote 192.168.61.207 { ssl_ca = </etc/ssl/dovecot/ca_real.pem ssl_verify_client_cert = yes } doveconf -f remote=192.168.61.207 ssl_ca ssl_ca = </etc/ssl/dovecot/ca_real.pem doveconf -f remote=192.168.61.208 ssl_ca ssl_ca = </etc/ssl/dovecot/ca_fake.pem /usr/sbin/dovecot ========================================================On 192.168.61.207 copy accross //192.168.61.214/etc/ssl/dovecot/smtp.pem to //192.168.61.207/tmp/smtp.pem copy accross //192.168.61.214/etc/ssl/dovecot/smtp.key to //192.168.61.207/tmp/smtp.key copy accross //192.168.61.214/etc/ssl/dovecot/ca_real.pem to //192.168.61.207/tmp/ca_real.pem ifconfig eth0 eth0 ... inet addr:192.168.61.207 Bcast:0.0.0.0 Mask:255.255.255.0 ... cd /tmp openssl s_client -connect 192.168.61.214:24 -key smtp.key -cert smtp.pem -CAfile ca_real.pem Acceptable client certificate CA names CN = Fake CA <<<<<<<<<<<<<<<<<<<<<<<< FATAL <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< =========================================================
Sean Gallagher
2023-Feb-11 03:44 UTC
Please Help: Dovecot ssl_ca selection based on remote IP address filtering not working.
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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <https://dovecot.org/pipermail/dovecot/attachments/20230211/d87f3c2d/attachment-0001.htm>