[Ref: OpenBSD 4.9 amd64/i386, Postfix 2.8.3, TLS Support ]

There's abundant documentation with Postfix for configuring Postfix with TLS. The following notes are directed at enabling TLS for Postfix as the server, and as a client to other SMTP servers. The notes have been shown to work/functional on a clean and working copy of Postfix, it is left to the reader to adapt to their own configuration for Postfix.

Configure TLS

TLS is dependent on Postfix (a) compiled with support for encryption, and (b) the appropriate SSL certificates. Fortunately, the OpenBSD standard packages builds Postfix with SSL support. Install from a prebuilt package.

OpenSSL is installed on the standard install, create certificates, as described in various Internet resources, or our own interpretation at SSL Certificate Generation using OpenSSL

SMTPD Server

Servicing TLS connections from clients is configured independently of the connecting from the Postfix server to another SMTP server.

File excerpt: /etc/postfix/main.cf

smtpd_tls_loglevel = 1

smtpd_tls_security_level = may
smtpd_tls_CAfile = /path-to/private/ca.crt.pem
smtpd_tls_cert_file = /path-to/server.crt.pem
smtpd_tls_key_file  = /path-to/private/server.key.pem
smtpd_tls_received_header = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_tls_session_cache
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_protocols = TLSv1, SSLv3
smtpd_tls_mandatory_protocols = !SSLv2

smtpd_tls_dh1024_param_file = /path-to/dh_1024.pem
smtpd_tls_dh512_param_file  = /path-to/dh_512.pem
smtpd_tls_eecdh_grade       = strong

SMTP Client

To enable Postfix to send mail using TLS, the below configuration is appropriate.

Note, the Postfix documentation specifies:

Do not configure Postfix SMTP client certificates unless you must present client TLS certificates to one or more servers. Client certificates are not usually needed, and can cause problems in configurations that work well without them. The recommended settings is to let the defaults stand

Otherwise, ..., if you really must set something, try the following for our 'known' configuration for certificates.

File excerpt: /etc/postfix/main.cf

smtp_tls_loglevel = 1

smtp_tls_cert_file = /path-to/server.pem
smtp_tls_key_file = /path-to/private/server.key.pem
smtp_tls_CAfile = /path-to/private/ca.crt.pem

smtp_tls_session_cache_database = btree:${data_directory}/smtp_tls_session_cache
smtp_tls_security_level = may
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
smtp_tls_note_starttls_offer = yes
smtp_tls_mandatory_ciphers = medium
smtp_tls_mandatory_exclude_ciphers = RC4, MD5
smtp_tls_exclude_ciphers = aNULL
smtp_tls_mandatory_protocols = SSLv3, TLSv1
smtp_tls_ciphers = export
smtp_tls_protocols = !SSLv2

Client Side smtp configuration.

Opportunistic TLS

smtp_tls_security_level = may

Opportunistic TLS, the SMTP transaction is encrypted if the STARTTLS ESMTP is supported by the server.

TLS Policy Table

Ref: postconf(5)

The TLS policy table is indexed by the full next-hop destination, 
which is either the recipient domain, or the verbatim next-hop. 
This includes any enclosing square brackets and any non-default 
destination server port suffix. 

:::

When the lookup key is a domain name without enclosing square brackets or 
any :port suffix (typically the recipient domain), and the full domain is 
not found in the table, just as with the transport(5) table, the parent domain 
starting with a leading "." is matched recursively. This allows one to specify a 
security policy for a recipient domain and all its sub-domains. 

:::

The lookup result is a security level, followed by an optional list of whitespace and/or comma separated name=value attributes that override related main.cf settings. The TLS security levels in order of increasing security are: 

TLS security levels in order of increasing security are: none | may | encrypt | fingerprint | verify | secure.

Once satisfied that configuration and connections are encrypting data, then the policy can be updated to encrypt.

Referring back to our above sample main.cf configuration settings:

smtp_tls_policy_maps = hash:/etc/postfix/tls_policy

TLS security level: may

Excerpt

example.com     may
.example.com    may

TLS security level: encrypt

example.com     encrypt protocols=TLSv1
.example.com    encrypt

You can specify explicit routing in the following style

File excerpt: /etc/postfix/tls_policy

[example.com]:25     encrypt protocols=TLSv1
[example.net]:465    encrypt protocols=TLSv1 ciphers=high

Note: there is allusion in the documentation that you should use only one of the above styles.

TLS security level: fingerprint

We do have occassions where we want to ensure that we are connecting to a verified remote host. We somehow get a validated SSL Certificate from the user and generate a fingerprint from the certificate that we use to validate that the destination mail server is who they say they are:- * digest format * fingerprint * policy file

Digest Format

[smtptlsfingerprint_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. It should be fine, but read the documentation about what it says may be the better choice digest for you.

Fingerprint

[Ref: openssl x509]

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

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

SMTPS Daemons

Although not necessary, we can enable explicit encrypted services on port smtps(465) through the master.cf

smtps   inet   n    -    -    -    -    smtpd
   -o smtpd_tls_wrappermode=yes

Verification

When the configuration is working, you should not get any warning or error messages in /var/log/maillog during startup, nor when explicitly initiating TLS communications. The following connection methods are to allow you to simulate what a valid client connection will be, and to monitor your logs for errors that may occur (and to rectify them, obviously.)

STARTTLS

To confirm that TLS is supported, you can connect to the Postfix daemon, and list supported services with the EHLO command. If STARTTLS is supported, configured, then in the list of features listed should be STARTTLS.

To negotiate an encrypted channel (TLS), use the command STARTTLS as in the example below. Obviously, it's difficult to respond to encrypted communications using the keyboard, so once you can intiate TLS without error messages you are one step further to reviewing more complete tests.

telnet localhost smtp
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mx.coco.nut.to ESMTP Postfix
EHLO example.com
250-mx.coco.nut.to
250-PIPELINING
250-STARTTLS
STARTTLS
220 2.0.0 Ready to start TLS

Incorrect configuration should be readily detected in console error messages, or by watching /var/log/maillog.

Get out of the connection.

SMTP using STARTTLS

openssl s_client provides a command-line mechanism for initiating a connection, and starting STARTTLS to encrypte connection link.

openssl s_client -starttls smtp -crlf -connect localhost:25
A lot of certificate information is exchanged, and shown on the screen

...

250 DSN
MAIL FROM: <samt@example.com>
250 2.1.0 Ok
RCPT TO: mylocaluser
250 2.1.5 Ok
DATA
354 End data with .
Subject: STARTTLS Test Message

Postfix will decrypt

.
250 2.0.0 Ok: queued as XXXXXXXXXXX
quit
221 2.0.0 Bye

openssl's s_client -starttls smtp tells it to make the encryption/decrypting between our console and an SMTP server. Once connected, then we can go through our normal smtp test message commands. (Shown in CAPITAL letters above.)

SMTPS

Verify the wrapmode smtps service is working correctly using the generic openssl s_client connection.

openssl s_client -connect localhost:465
CONNECTED(0000000X)
Plenty of Certificate negotiation/information

220 mx.coco.nut.to ESMTP Postfix

At this point, you should be able to complete the SMTP test connection using the same example as above for SMTP STARTTLS.

If all things work out, you now have a working TLS server for mail going into your server. Use the above information for verifying your mail server can also send out using TLS.