Re: [exim] Something like "domains_require_tls"

Top Page
Delete this message
Reply to this message
Author: Mike Tubby
Date:  
To: exim-users
Subject: Re: [exim] Something like "domains_require_tls"
Hi Olaf,

I had a similar problem several years ago, but had to ensure TLS in and
TLS out to potentially hundreds of domains so implemented in in our mail
relay servers using a MySQL database:

CREATE TABLE `tls_force_remote_domains` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `domain` varchar(100) NOT NULL,
  `active` tinyint(1) unsigned NOT NULL DEFAULT 0,
  `description` varchar(250) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `domain` (`domain`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_general_ci COMMENT='Domains for which TLS must be used
for sending and receiving email'

and domain_lists:

TLS_FORCE_REMOTE_DOMAINS = SELECT domain FROM tls_force_remote_domains
WHERE active=1;
domainlist tls_force_remote_domains = ${lookup
mysql{TLS_FORCE_REMOTE_DOMAINS}{${sg{$value}{\\n}{ : }} }}

TLS_FORCE_LOCAL_DOMAINS = SELECT domain FROM domains WHERE active=1 AND
force_tls=1;
domainlist tls_force_local_domains = ${lookup
mysql{TLS_FORCE_LOCAL_DOMAINS}{${sg{$value}{\\n}{ : }} }}


I put this snippet at the bottom of acl_check_mail:

        #
        # TLS during MAIL command
        #

        #
        # first, log the connection status
        #
        warn    log_message = MAIL: TLS-STATUS Sender
domain=$sender_address_domain Host=$sender_fullhost using TLS
cipher=$tls_in_cipher
                encrypted = *

        warn    log_message = MAIL: TLS-STATUS Sender
domain=$sender_address_domain Host=$sender_fullhost NOT using TLS
                ! encrypted = *

        #
        # second, log if a specific sender domain is in force TLS list
        #
        warn    log_message = MAIL: TLS-REQUIRED Domain
$sender_address_domain requires a TLS connection
                sender_domains = +tls_force_remote_domains

        #
        # next, accept all MAIL commands for which the connection is
encrypted with TLS
        #
        accept  log_message = MAIL: TLS-ACCEPT encrypted session -
cipher=$tls_in_cipher
                encrypted = *

        #
        # now, check for domains that must use TLS and might not be - in
        # which case we should reject
        #
        deny    log_message = MAIL: TLS-REJECT mail from domain
$sender_address_domain requires a TLS connection
                message = TLS encryption required for mail from this domain
                sender_domains = +tls_force_remote_domains
                ! encrypted = *

        #
        # finally, accept everything else without TLS
        #
        accept  log_message = MAIL: NON-TLS-ACCEPT Accept unencrypted
email from: $sender_address host: $sender_fullhost


and made this my last-but-one router:

#
# if the destination domain is in the tls_force_remote_domains list then set
# the transport to remote_smtp_force_tls to force the selection of TLS
#
outbound_force_tls:
        driver = dnslookup
        domains = +tls_force_remote_domains
        transport = remote_smtp_force_tls


before:

#
# if we fall through to here then we're not forcing TLS on a listed domain,
# so do a normal delivery for all non-local domains. This may still use TLS
# if advertised but its not forced.
#
outbound_lookup:
        driver = dnslookup
        domains = ! +local_domains
        transport = remote_smtp
        ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
        no_more


and then this in my transports:

#
# This transport is used for delivering messages over SMTP connections
# where TLS is optional (not forced), so no hosts require TLS (but it may be
# negotiated if the far end advertises STARTTLS) and no cipher suite is
# specified.
#
remote_smtp:
  driver = smtp

#
# This transport is used for delivering messages over SMTP connections
# where TLS is mandatory (forced) with high cipher strength.  NB. this
# transport is selected based on the destination domain, so the hosts that
# at this point the host(s) that require TLS are 'any' (wildcard) because we
# don't care who we're talking to it must use TLS.
#
remote_smtp_force_tls:
  driver = smtp
  hosts_require_tls = *
  hosts_try_fastopen = !*.l.google.com
  tls_require_ciphers = HIGH:!SRP:!PSK:!SHA:@STRENGTH


My approach is a bit long-winded and not condensed as you ask, but it
lets me control forced TLS in either direction (if I want to) with only
a minor tweek and I don't case too much about what is under the hood as
I simply add or remove domains to/from the "tls_force_remote_domains"
MySQL table and Exim and this config takes care of it.


Mike




On 23/03/2023 15:30, Olaf Hopp (SCC) via Exim-users wrote:
> Hi,
> for legal reasons I have a list of domains, where I *must* send via TLS
> Currently, I have two routers and transports:
>
> router_A:
>     domains: +domainlist-with-TLS-Domains
>     transport: tlssmtp
> router_B:
>     domains: *
>     transport: smtp
>
> tlssmtp:
>     hosts_require_tls = *
>     driver = smtp
> smtp:
>     driver smtp
>
>
> in reality two routers and transports are much more complicated but
> almost
> identical. The same is true for the transports.
>
> Is it somehow possible to consolidate this into one router and one
> transport
> and lets have in the transport "something like"
>
>  domains_require_tls = +domainlist-with-TLS-Domains
>
> I now that this option does not exist, but is it possible to configure
> one router and one transport that act like that ?
>
> Regards, Olaf
>
>