Sendmail MSP with Verified TLS

by J. Edward Durrett

On machines that do not need to listen for mail (smtp), it is a best practive to run sendmail as a non root user using the
mail submission protocol queue runner. This allows for client delivery to a relay or smarthost without running a full blown
sendmail instance. The process is run by the user smmsp. It is not necessary to have the client queue running, as sendmail
will start a new process to deliver mail to a relay or smarthost, but having it run ensures that all mail gets submitted and
nothing is left behind in the queue [1]. For FreeBSD, this can be accomplished with the following lines in rc.conf:


On most systems, the sendmail installation will install dummy certificates in the /etc/mail/certs directory. In order for tls
to be verified, real signed certificates need to be used (see my previous article for an outline on
how to set up, configure and automate an internal Certificate Authority)
. If a self-signed certificate is used, something
like this will appear in the logs:

Sep 28 19:28:11 host sendmail[7746]: STARTTLS=client,, version=TLSv1.2, verify=FAIL, cipher=DHE-RSA-AES256-GCM-SHA384, bits=256/256

Notice the "verify=FAIL" in the above line. It could also say "verify=NO" which means that no certificate was sent [2]. For a
proper setup, "verify=OK" will be in the logs, like this:

Sep 28 20:43:44 host sendmail[11850]: STARTTLS=client,, version=TLSv1.2, verify=OK, cipher=DHE-RSA-AES256-GCM-SHA384, bits=256/256

In order to get to the point where sendmail is successfully verifying certificates, we need to tell sendmail where the
certificates are and where the CA certificate is. Since we are using MSP, the relevant configuration file is
/etc/mail/ ( Adding these limes to the file will let sendmail know where to look:

define(`CERT_DIR', `/etc/mail/certs')dnl
define(`confSERVER_CERT', `CERT_DIR/host.cert')dnl
define(`confSERVER_KEY', `CERT_DIR/host.key')dnl
define(`confCLIENT_CERT', `CERT_DIR/host.cert')dnl
define(`confCLIENT_KEY', `CERT_DIR/host.key')dnl
define(`confCACERT', `CERT_DIR/cacert.pem')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl

However, issuing a make install restart at this point won’t work. Remember the process is run by the user smmsp, not root
as sendmail generally is. That user has to be able to read the certificates. So, first the certificates have to be readable by
the smmsp user and then the new configuration files can be generated and the queue runner restarted:

chown -R smmsp /etc/mail/certs
make install restart

I like to name my certificates for the host they are running on so they are easier to identify in cases where I need to do
something like restore from backups. Of course I could just read them with openssl, but I find worth in being able to quickly
identify them. Since I manage dozens upon dozens of machines, as I would assume so does anyone looking to have properly configured
and verified TLS certificates, it would take forever to mody each configuration by hand. So, first I create a skeleton and
then use a a small script to customize each mc file as it is installed on the host as this snippet shows:


sed -i -e 's/host.key/'${HOSTNAME}'.key/g'
sed -i -e 's/host.cert/'${HOSTNAME}'.cert/g'

Configuring sendmail to use properly singed certificates is just a matter of following the steps above. The advantages over
using self singed certificates is better verification and confidentiality of traffic. It is also possible to use the
certificates to control relaying. The biggest advantage from a network security analyst's point of view, is now all the
good traffic between sendmail hosts can be identified and any traffic without a signed certificate from the internal
certificate authority can be flagged as potentially bad.


Copyright (c) 2019, Jason Edward Durrett - All content on this site, unless otherwise noted, is subject to this license.

Please contact me if any errors, such as erroneous / misleading content or missing / incomplete attribution, are found.