Postfix TLS Configuration

Let’s discuss some things around setting up TLS support for Postfix mail server, here running on a Debian/Linux server.

Configuration

Modern Postfix versions support the STARTTLS extension that allows the POP, IMAP and SMTP plain text protocols to upgrade to an encrypted TLS or SSL connection on the same port, avoiding the need to switch to a separate port for explicit encrypted communication. This upgrade is however optional and it is not a security feature that should be assumed to be applied. STARTTLS for IMAP and POP3 is defined in RFC 2595, for SMTP in RFC 3207. Note that SSL should not be used anymore, even not version SSL3. TLS is the protocol to employ.

We start with generating a public key, ie. the public certificate, and an associated private key. The key must be in PEM (Privacy Enhanced Mail) format.

Before starting, click here to open the Postfix documentation in a different browser tab :)

root@arakeen:/etc> openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/mailcert.pem -keyout /etc/ssl/private/mailcert.key
 
Generating a 2048 bit RSA private key
................................................+++
............................................+++
writing new private key to '/etc/ssl/private/mailcert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]: BE
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

These files have to be configured in the main.cf file (comments added by me and they can be omitted):

root@arakeen:/etc/postfix# vi main.cf
:
# File with the Postfix SMTP server RSA certificate in PEM format. This file may also contain the Postfix SMTP server private RSA key.
smtpd_tls_cert_file=/etc/ssl/certs/mailcert.pem
 
# File with the Postfix SMTP server RSA private key in PEM format. May be combined with $smtpd_tls_cert_file.
# The private key must be accessible without a pass-phrase, i.e. it must not be encrypted. 
# File permissions should grant read-only access to the root account ("root"), and no access to anyone else.
smtpd_tls_key_file=/etc/ssl/private/mailcert.key
 
# Opportunistic TLS - announce STARTTLS support to remote SMTP clients, but do not require that clients 
# use TLS encryption. Default is 'no'.
smtpd_use_tls=yes
 
# Optional configuration Postfix SMTP client TLS session caches. It's a science on its own and
# the internet will help you researching...
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
 
# The SMTP TLS security level for the Postfix SMTP server. See documentation for more important info.
# none : TLS will not be used.
# may : Opportunistic TLS - announce STARTTLS support to remote SMTP clients, but do not require that 
# clients use TLS encryption.
# encrypt : Mandatory TLS encryption - announce STARTTLS support to remote SMTP clients, and require 
# that clients use TLS encryption. According to RFC 2487 this MUST NOT be applied in case of 
# a publicly-referenced SMTP server. This option should be used only on dedicated servers.
smtpd_tls_security_level=may
 
# List of TLS protocols that the Postfix SMTP server will exclude or include with opportunistic TLS encryption.
# This prevents using the insecure very old SSL:
smtpd_tls_protocols = !SSLv2, !SSLv3
 
# 0 (Default): Disable logging of TLS activity
# 1 : Log only a summary message on TLS handshake completion. No logging of client 
# certificate trust-chain verification errors if client certificate verification 
# is not required. 
# 2 : Also log levels during TLS negotiation.
# 3 : Also log hexadecimal and ASCII dump of TLS negotiation process.
# 4 : Also log hexadecimal and ASCII dump of complete transmission after STARTTLS.
# Do not use 2 or higher except in case of problems. Use of loglevel 4 is strongly discouraged.
smtpd_tls_loglevel = 1
:

Correctly configured, the /var/log/mail.log file should show things like these when mails are delivered to our server. Note: Postfix log level is set to 1. The default level is 0 when nothing is  specified in the settings. The log file shows less information in this case.

:
postfix/smtpd[16400]: connect from mail-wm0-f49.google.com[74.125.82.49]
postfix/smtpd[16400]: setting up TLS connection from mail-wm0-f49.google.com[74.125.82.49]
postfix/smtpd[16400]: mail-wm0-f49.google.com[74.125.82.49]: TLS cipher list "aNULL:-aNULL:ALL:+RC4:@STRENGTH"
postfix/smtpd[16400]: SSL_accept:before/accept initialization
postfix/smtpd[16400]: SSL_accept:SSLv3 read client hello A
postfix/smtpd[16400]: SSL_accept:SSLv3 write server hello A
postfix/smtpd[16400]: SSL_accept:SSLv3 write certificate A
postfix/smtpd[16400]: SSL_accept:SSLv3 write key exchange A
postfix/smtpd[16400]: SSL_accept:SSLv3 write server done A
postfix/smtpd[16400]: SSL_accept:SSLv3 flush data
postfix/smtpd[16400]: SSL_accept:SSLv3 read client key exchange A
postfix/smtpd[16400]: SSL_accept:SSLv3 read finished A
postfix/smtpd[16400]: SSL_accept:SSLv3 write session ticket A
postfix/smtpd[16400]: SSL_accept:SSLv3 write change cipher spec A
postfix/smtpd[16400]: SSL_accept:SSLv3 write finished A
postfix/smtpd[16400]: SSL_accept:SSLv3 flush data
postfix/smtpd[16400]: Anonymous TLS connection established from mail-wm0-f49.google.com[74.125.82.49]: TLSv1.2 with cipher ECDHE-RSA-AES128-111-SHA256 (128/128 bits)
postfix/smtpd[16400]: EF5E54E0367: client=mail-wm0-f49.google.com[74.125.82.49]
postfix/cleanup[16403]: EF5E54E0367: message-id=<....@mail.gmail.com>
postfix/qmgr[16345]: EF5E54E0367: from=<;.....@gmail.com>;, size=1713, nrcpt=1 (queue active)
postfix/smtpd[16400]: disconnect from mail-wm0-f49.google.com[74.125.82.49]
:

Postfix TLS certificate and key trouble shooting

Not having configured the public certificate (‘smtpd_tls_cert_file‘) and the associated private key (‘smtpd_tls_key_file’) correctly, can lead to all kind of mystical effects. Hereunder, I document some outcomes that I have observed. Google mail is btw. a very good testing tool as it is quite drastic when something is not working like it should.

1) Public certificate and private key file where not matching

In this case, the public key ie. the public server TLS certificate and the associated private key are cryptographically not matching, which means that they are not forming a pair. Probably some files got mixed up during the installation described above.

Error:

X509_check_private_key:key values mismatch

Log file:

:
postfix/smtpd[14676]: warning: cannot get RSA private key from file /etc/ssl/private/mail.key: disabling TLS support
postfix/smtpd[14676]: warning: TLS library problem: 14676:error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch:x509_cmp.c:330:
postfix/smtpd[14676]: connect from mail-wm0-f43.google.com[74.125.82.43]
postfix/smtpd[14676]: lost connection after STARTTLS from mail-wm0-f43.google.com[74.125.82.43]
:

Error mail sent to postmaster:

Date:
From: MAILER-DAEMON@arakeen (Mail Delivery System)
To: postmaster@arakeen (Postmaster)
Subject: Postfix SMTP server: errors from mail-lf0-f51.google.com[209.85.215.51]
Message-Id: <20151209125907.D7E7C4E034F@arakeen>

Transcript of session follows.

Out: 220 vps132034.ovh.net ESMTP Postfix (Debian/GNU)
In: EHLO mail-lf0-f51.google.com
Out: 250-arakeen
Out: 250-PIPELINING
Out: 250-SIZE 10240000
Out: 250-VRFY
Out: 250-ETRN
Out: 250-STARTTLS
Out: 250-ENHANCEDSTATUSCODES
Out: 250-8BITMIME
Out: 250 DSN
In: STARTTLS
Out: 454 4.7.0 TLS not available due to local problem

Session aborted, reason: lost connection
For other details, see the local mail logfile

Testing the keys:

In order to test if public and private keys are indeed a pair, these two commands must output the same MD5 hash values. If this is not the case, public certificate/key and private key are not a clean pair and as consequence they have to be re-generated:

#
root@arakeen:/etc> openssl x509 -noout -modulus -in /etc/ssl/certs/mailcert.pem | openssl md5
(stdin)= d467b8860d07aec22ad97eed3d77cac2
#
root@arakeen:/etc> openssl rsa -noout -modulus -in /etc/ssl/private/mailcert.key | openssl md5
(stdin)= d467b8860d07aec22ad97eed3d77cac2
#

Explanation:

  • rsa : Specifies that the key is an RSA key.
  • x509 : Command allows you to display content of a X509 certificate and to convert it from ot to PEM, NET or DER formats.
  • modulus : Print the RSA key modulus.
  • noout : Prevents the print-out of the key straight to the terminal and the bash history.

The keys for the RSA algorithm are generated based on two random prime numbers P and Q. The factor of P and Q, P x Q = N, is taken as the modulus N. In general, the modulus is the number of times one number can “warp around” in another number. It is not to be confounded with the “remainder” of this operation (1 for “5 mod 2”), generally referred to as the modulo operation (mod).

N is used for both the public and private key and its length depends on the length of the key . The modulus is part of the public and private key, as defined for instance in RFC3447 for RSA, and can easily be obtained having the keys in possession. If public and private keys are forming a cryptographically matching pair, the modulus of each is equal to the other. The MD5 hash is used to reduce the 512++ character string of the effective modulus to a short 41 character string, which greatly simplifies the visual comparative :)

Solution:

Re-generate a clean public key/certificate – private key pair as described above, ie like this:

#
root@arakeen:/etc> openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/mailcert.pem -keyout /etc/ssl/private/mailcert.key
#

2) Corrupt or wrong private key (file)

The file configured as container for the private key does not contain a private key or does not respect the required format. The key must be in PEM (Privacy Enhanced Mail) format.

Error:

TLS library problem: PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: ANY PRIVATE KEY

Log file:

:
postfix/smtpd[15135]: warning: cannot get RSA private key from file /etc/ssl/private/mailcert.csr: disabling TLS support
postfix/smtpd[15135]: warning: TLS library problem: 15135:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: ANY PRIVATE KEY:
postfix/smtpd[15135]: warning: TLS library problem: 15135:error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib:ssl_rsa.c:669:
postfix/smtpd[15135]: connect from somesmtpserveroutthere[7.7.1.1]
postfix/smtpd[15135]: 9C05C4E02FD: client=somesmtpserveroutthere[7.7.1.1]
:

3) “Untrusted” private key configured

The file configured as container for the private key contains a PUBLIC key. The PEM format makes this verification easy.

Error:

TLS library problem: PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: TRUSTED CERTIFICATE

Log file:

:
postfix/smtpd[15683]: warning: cannot get RSA certificate from file /etc/ssl/private/mailcert.xyz: disabling TLS support
postfix/smtpd[15683]: warning: TLS library problem: 15683:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: TRUSTED CERTIFICATE:
postfix/smtpd[15683]: warning: TLS library problem: 15683:error:140DC009:SSL routines:SSL_CTX_use_certificate_chain_file:PEM lib:ssl_rsa.c:730:
postfix/smtpd[15135]: connect from somesmtpserveroutthere[7.7.1.1]
postfix/smtpd[15135]: 9C05C4E02FD: client=somesmtpserveroutthere[7.7.1.1]
:

 

Leave a Reply

Your email address will not be published. Required fields are marked *