Jump to Navigation

Sendmail: Using TLS for authentication

Symptoms

You have a laptop or other mobile device running Debian. You have your own Sendmail server, also running Debian. You want to send email from your laptop, but your Sendmail server does not accept your emails if you are not on your local network.

Solution

You have to allow relaying on your Sendmail server, but of course only for email sent by your laptop. There are several ways to do this; one of them is to use TLS. As a side effect, email in transit from your laptop to your server is encrypted, which is always a good thing if you are on some random non-trusted network.

Assumptions

  • You are running Debian both on the server and the client;
  • You have sendmail running on your server and are able to send mail through it;
  • You have sendmail running on your client;
  • Your client uses your server as its smarthost;
  • You are able to send email from your client when you are on your local network, but not when your are elsewehere.

Theory

TLS (Transport Layer Security) is a way to encrypt traffic from one computer to another. It is often seen as the successor to SSL. When using it with email, you do not have to assign a separate port for the encrypted traffic. STARTTLS will be used, which upgrades an unencrypted connection to an encrypted one1.

To get TLS to work, both the client side and the server side must have a certificate. These can be (and usually should be) different. Optionally, you can tell on the server side to check whether the certificate the client offers is acceptable; that is what we will use to identify the client and allow it to relay email. Of course, it is also possible for the client to check whether the server offers an acceptable certificate.

To determine whether a certificate is acceptable, we will check who has signed it. Each certificate is signed by another certificate. This signing process forms a certificate chain: a certificate A is signed by certificate B, that in turn is signed by certificate C, which is signed by certificate D, and so on. Somewhere this has to stop: the top level certificate is signed by itself.

To use a certificate to sign anything, or to initiate a connection with it, you also need the corresponding certificate key.  You only need the certificate, and not its key, to check a signature. The certificate key is also called the private part for this reason, while the certificate itself is the public part.

Sendmail implementation

To configure Sendmail to use TLS you have to provide several variables, the most important of which are:

  • confSERVER_CERT, confSERVER_KEY (server2):
    The location of files which contain a certificate and the certificate key. Sendmail will use these when it is acting as a server.
  • confCLIENT_CERT, confCLIENT_KEY (client3):
    The location of files which contain a certificate and the certificate key. Sendmail will use these when it is acting as a client.
  • confCACERT_PATH (server and client):
    The location of a directory which contains all certificates that can be used to sign other certificates. If you use self-signed certificates, they should be found here too (as they are used to sign themselves).
  • confCACERT (server):
    The location of a file that contains one or more certificates. One of these certificates must be the certificate that has been used to sign the certificate the client is using.

To keep things simple, we will use one and the same self-signed certificate for:

  • On the server side, as the certificate used for sendmail in server mode;
  • On the client side, as the certificate used for sendmail in client mode;
  • On the server side, as the certificate which should match the certificate the client offers is signed with4.

Procedure

If you are running Debian, much of the needed configuration has already be done for you.

Configuring the client

Edit /etc/mail/sendmail.mc and add the following line, just before the LOCAL_CONFIG line:

include(`/etc/mail/tls/starttls.m4')dnl

Configuring the server

Edit /etc/mail/sendmail.mc and add the following line, just before the LOCAL_CONFIG line:

include(`/etc/mail/tls/starttls.m4')dnl

Also, comment out the confTLS_SRV_OPTIONS line5:

dnl define(`confTLS_SRV_OPTIONS', `V')

Optional: recreating the certificates (server)

It is a good idea to recreate the certificates on the server, especially if your server was updated from older Debian versions. This will ensure all certificates will remain valid for ten years. You can do this later on too, provided you update the certificates on the client side too.

# as root
# You can actually remove all files in /etc/mail/tls if you want to restart with a clean slate
/usr/share/sendmail/update_tls new

This will recreate the self-signed certificates in /etc/mail/tls. These are referred to by /etc/mail/tls/starttls.m4.

You can safely do this on the client side too, even though it should not be necessary.

Copying certificates (server to client)

Copy /etc/mail/tls/sendmail-server.crt and /etc/mail/tls/sendmail-common.key from the server to /etc/mail/tls/sendmail-client.crt and /etc/mail/tls/sendmail-common.key on the client.

Though it is not actually used, on the client side you will get an error from sendmail-server.crt because the key does not match. Though this is not serious, it is ugly. To solve this, copy /etc/mail/tls/sendmail-client.crt to /etc/mail/tls/sendmail-server.crt on the client side.

Regenerate the sendmail configuration and restart sendmail (client side):

# as root
cd /etc/mail
make
service sendmail reload

Configuring the access database (server)

Determine who signed the server certificate; the name has to be encoded in a specific way. The command below should do it; run it on the server:

openssl x509 -in /etc/mail/tls/sendmail-server.crt -noout -issuer  -nameopt compat | 
   sed -e 's,^issuer= ,CERTIssuer:,' -e 's, ,+20,g' -e 's,$, RELAY,'

Now edit /etc/mail/access and add the line generated above.

Check whether you are using the access database feature in sendmail at all; the following line should be in your /etc/mail/sendmail.mc:

FEATURE(`access_db', , `skip')dnl

Regenerate the sendmail configuration and restart sendmail:

# as root
cd /etc/mail
make
service sendmail reload
  • 1. Despite its name, STARTTLS can actually be used in combination with SSL too.
  • 2. Note that you should probably provide this on clients too.
  • 3. Also provide this on servers; it will be used when Sendmail forwards a mail to another mail server.
  • 4. As this certificate is self-signed, checking for the certificate itself is the same as checking for the certificate it has been signed with.
  • 5. The V option instructs sendmail not to examine the client certificate it gets.


Technical_article | by Dr. Radut