[Ref: OpenBSD 4.9 amd64/i386, Postfix 2.8.3, TLS Support ]
Table of Contents
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.
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
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
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.
smtp_tls_security_level = may
Opportunistic TLS, the SMTP transaction is encrypted if the STARTTLS ESMTP is supported by the server.
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
Excerpt
example.com may
.example.com may
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.
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:-
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.
[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.
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
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
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.)
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.
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.)
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.