Postfix TLS

It bothered me enough that I need to record it, and hopefully the path to a solution that others will follow.

(delivery temporarily suspended: Server certificate not verified)

Lesson: Document things properly, especially if it’s something interesting, more so if the technology/thing you’re doing is normally not what you do, and it’s already taken you a long while to get it working properly in the first place.

Mind you, the above may be a difficult task when rushed to get a system out and the only way to confirm the installation is to break it apart and start from scratch

Scenario:

We exchange e-mail with an external organisation (duh!!) with regulatory standards that requires us to ensure e-mail sent to them is encrypted. We achieve this through the following:

  1. Certify that the server we’re connecting to is theirs by using:
    • using SSL certificates
    • smtp_tls_policy_maps and
    • fingerprinting
  2. Encrypt the traffic between the two sites using TLS

So, we follow the online Postfix TLS Support and smtpd_tls_fingerprint documentation and have it up and running with the basic configuration:

File extract: /etc/postfix/main.cf

smtp_tls_policy_maps = hash:/etc/postfix/tls_policy

File extract: /etc/postfix/tls_policy

example.com    fingerprint
    fingerprint-digest-is-here

Problem:

External Organisation used a 1 year self-sign certificate, it expires (as most eventually do) and no messages go through them. We get the below “cryptic” message in our logs:

(delivery temporarily suspended: Server certificate not verified)

Answer:

Seems easy enough, we just need to re-do/fix our 1st step above for Certifying the connection.

  1. Get updated certificate from remote site
  2. Update the fingerprint

Load up the online documentation and follow it through.

Get the updated certificate

For test purposes, we can connect directly to the IP-Address of the server and grab the certificate from the operating service.

echo | openssl s_client -showcerts -starttls smtp -crlf -connect host-record:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > certificate.pem 

Update the fingerprint

openssl x509 -noout -fingerprint -in certificate.pem
SHA1 Fingerprint=fingerprint-digest-is-here

Oooops, it doesn’t work.

The logs laugh: /var/log/maillog

(delivery temporarily suspended: Server certificate not verified)
  1. The message is not sent (deferred) with the error message “Server Certificate not verified”.
  2. The message is never sent, since the Server Certificate is never validated.
  3. Bypass certification and send e-mail. The short-term configuration is to not require the fingerprint to be ‘certified’.

I’m sure I followed the steps correctly … (wrong)

Solution:

Walk away from the documentation for a while, walk through it again with the presumption that you’ve screwed everything up so you need to take all your knowledge and check the basics (verify assumptions) as you go along.

  • digest format
  • fingerprint
  • policy file
Digest Format

[smtp_tls_fingerprint_digest]

Verification of an SMTP server certificate fingerprints, uses a message digest.

Don’t get trapped putting together fingerprints that are invalid, or unnecessary. Find out which fingerprint digest is supported by your configuration, and use that.

postconf | grep fingerprint
lmtp_tls_fingerprint_digest = md5
smtp_tls_fingerprint_digest = md5
smtpd_tls_fingerprint_digest = md5

The above configuration output shows we’re using the MD5 digest format.

Fingerprint

[Ref: openssl x509]

After acquiring getting your SSL Certificate through some ’trusted’ method, generate the fingerprint for the ’trusted’ certificate.

openssl x509 -noout -fingerprint -md5 -in /etc/ssl/certs/example.pem
MD5 Fingerprint=fingerprint-digest-is-here

After comparing the above fingerprint-digest-is-here with what I have in the tls_policy file, it is obvious they don’t look anything similar.

Policy File

With the above fingerprint, and digest we can fix the TLS Policy table such as the below:

example.com    fingerprint
    fingerprint-digest-is-here

Remap the file to make sure the correct hashed version is active:

# postmap /etc/postfix/tls_policy 

Restart the server and things are coool.

postfix reload

But isn’t that what the Postfix documentation says you have to do?

I guess it does, but for some reason the steps I took those days weren’t the correct steps. And now that I’ve rehashed the already hashed, I hopefully will not mis-read the documentation the next time through.