Enabling TLS/SSL on Postfix

I am working on a Postfix server which only sends mails (newsletters).

I have read I should enable TLS and/or SSL on Postfix in order to increase mail deliverability performance. Is it true? Is there a difference between SSL and TLS under Postfix?

I already have these three lines by default on my Postfix installation:

smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes

So I am wondering if SSL/TLS is already enabled by default? What are these auto-generated pem and key files? How can I replace them by my HTTPS certificate? I have already an HTTPS certificate for my domain. Can I use the same certificates for both Postfix and Nginx?


Solution 1:

Enabling encryption doesn't help with delivery performance, but it's recommendable because it increases email privacy. Encrypting email on transport has become a standard, as you may notice from Google's Transparency Report on Email encryption in transit.

While SSL and older versions of TLS have been deprecated, email is a backwards compatible infrastructure that considers any encryption better than none, and is willing to fallback to unencrypted connections. Therefore, man-in-the-middle attacks would be easy, and techniques like SMTP Security via Opportunistic DANE TLS (RFC 7672) are invented to increase security while maintaining backwards compatibility.

By default (as of May 2020), SSLv2 and SSLv3 have been disabled in Postfix for both

  • smtp_tls_protocols – client component for delivering mail &
  • smtpd_tls_protocols – server component for receiving mail.

My answer summarizes current best-practices & how they could be implemented in Postfix.


Inbound TLS

You currently have self-signed default "snake oil" certificates that comes with Postfix. You told you already have a certificate for your web server and you can certainly use the path for that certificate chain & key, but for this answer to be more useful for the rest, one could also replace them with free Let's Encrypt certificates. For that,

  1. use (or install) a web server on the same machine for the HTTP-01 challenge and

  2. use the certificates created by it for incoming mail. Example:

    smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
    smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem
    smtpd_tls_security_level=may
    

Notice that

  • your current smtpd_use_tls is replaced by smtpd_tls_security_level in Postfix ≥ 2.3.

  • with Postfix ≥ 3.4 the preferred way to configure server keys and certificates is via the smtpd_tls_chain_files parameter.

  • per RFC 3207, 4 you should use opportunistic TLS on publicly-referenced SMTP servers:

    A publicly-referenced SMTP server MUST NOT require use of the

STARTTLS extension in order to deliver mail locally. This rule prevents the STARTTLS extension from damaging the interoperability of the Internet's SMTP infrastructure. A publicly-referenced SMTP server is an SMTP server which runs on port 25 of an Internet host listed in the MX record (or A record if an MX record is not present) for the domain name on the right hand side of an Internet mail address.

Using Let's Encrypt with Certbot means your certificates get automatically renewed in 2-3 month cycles. Postfix doesn't load these updated certificates automatically, so it might be wise to add a cronjob for realoading Postfix with the new certificate regularly, e.g. (once a week in Debian 10) with

50 5 * * 1 systemctl reload postfix

Outbound TLS

If you want to add TLS authentication for the receiving servers on your outbound mail, you could use the opportunistic DANE with smtp_tls_security_level. Using DANE requires that your DNS resolver has DNSSEC capabilities, and it only authenticates those domains that have TLSA policies published. Again, this is the best-practice for increasing privacy without breaking the backwards compatibility.

dane

  • Opportunistic DANE TLS. At this security level, the TLS policy for the destination is obtained via DNSSEC. For TLSA policy to be in effect, the destination domain's containing DNS zone must be signed and the Postfix SMTP client's operating system must be configured to send its DNS queries to a recursive DNS nameserver that is able to validate the signed records.
# TLS, DNSSEC and DANE for SMTP client
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_security_level = dane
smtp_dns_support_level = dnssec

If you can't use DANE, you could manually specify a list of domains that you know to have encryption and enforce using TLS for them, alone, using smtp_tls_policy_maps:

smtp_tls_policy_maps = hash:/etc/postfix/tls_policy

With this Berkeley DB, the contents of /etc/postfix/tls_policy may look like:

# Encrypt all mail to @gmail.com using any MX with TLS 1.2
gmail.com encrypt protocols=TLSv1.2

# Ecrypt all mail delivered using a specific nexthop destination
[contoso-com.mail.protection.outlook.com] encrypt

DANE for inbound TLS with Let's Encrypt

For completeness, the outbound DANE verification works best if you also publish your own TLSA records. With Let's Encrypt, it's a bit problematic to automate publishing the fingerprints for your current certificates. Instead, you can use DANE-TA(2) as explained in Please avoid “3 0 1” and “3 0 2” DANE TLSA records with LE certificates:

_25._tcp.mail.example.com. IN TLSA 2 1 1 (
    60B87575447DCBA2A36B7D11AC09FB24A9DB406FEE12D2CC90180517616E8A18
)

Also, for this to work you need a DNSSEC signed zone for your domain.