Postfix TLS Certificate Generation

This page assumes familiarity with the terminology defined on the main Mail Server Page.

With Postfix, you generally only need a TLS private key and certificate if your server accepts incoming connections. In the case of a Null MTA client where all connections are outgoing, you do not need a certificate unless it is a client authentication certificate, which is beyond the scope of this document.

Most clients connecting to Port 25 of your server will be capable of using ECDSA for the TLS key exchange. However a few will not be capable and will resort to sending data using plain text if you use an ECDSA certificate.

For that reason SMTP servers that accept connections on Port 25 should use RSA key pairs with their certificate.

On Port 25 you only need to use a Certificate Authority signed certificate if you are implementing MTA-STS. I highly recommend you do implement MTA-STS but it is not required for SMTP.

Differences from Apache Key / Cert Generation

The shell scripts on the page are virtually identical to the shell scripts on the Apache TLS Certificate Generation page with the following four differences:

RSA Key Pair

SMTP servers listening on Port 25 need to support DHE key exchange, which requires an RSA key pair. For that reason, a 4096-bit RSA certificate is generated rather than an ECDSA key pair.

RSA Key Size

When Forward Secrecy ciphers are used, cracking the private key does not help crack logged encrypted sessions. Even with the computing power of the NSA, a 2048-bit private key would take more than 50 years to crack with current technology and would be long out of service by the time it is cracked, so it is safe to use 2048-bit to avoid MITM attacks.

But there is a kind of Internet user called a ‘Social Media Influencer’. They have figured out how to use their personality and psychology in combination with social media to have a heavy influential impact on their tens of thousands of followers who seem to often worship them like gods.

Social media influencers often (but not always) have a financial motive. They are often paid to promote what they promote or otherwise financially benefit from promoting what they promote. They were heavily used by Hillary in the 2016 primaries against Bernie and by both Hillary and Trump in the 2016 general. They were also used to promote vaping to teens. What they promote very often has no logical basis, but truth in advertising is difficult to apply to them because they are not traditional advertising but are seen as regular joe users expressing free speech.

It does not matter if what they are spouting is sound or not. All that matters is that it appeals enough to their base that their statements get likes and shares. Those likes and shares then give the statement authenticity and authority in the minds of others who see it. Social media really has made social engineering manipulation easy. We really need education in school teaching people how to resist this kind of manipulation, but there is no financial motive for educational facilities to provide such education. With capitalistic societies, there is the unfortunate tendency for everything to devolve to revolving around financial motive. The loss of dynamic range in popular music as a result of the loudness war is a clear example. It could be the undoing of our civilization.

In the context of TLS the social media influencers frequently spout that we should be using 4096-bit keys with RSA and you will often find them pimping commercial services that do so. They sometimes justify a 4096-bit minimum by referencing some government document that says ‘Top Secret’ should use at least 3072-bit RSA. 4096 is stronger, they reckon, and we do not want to be at the weakest this government document requires. These influencers never talk about the context of that requirement or whether what is required in that document they cite has logical reason or was just a number picked out of the air.

In the context of asynchronous encryption which what I suspect the document they are referring to is talking about, I do recommend 4096-bit RSA because if the key is broken ten years from now, everything encrypted with it today is compromised.

In the context of synchronous encryption with Forward Secrecy, the RSA key is actually not used to encrypt diddle. It is used to authenticate the server to the client by signing the DHE or ECDHE key exchange. IT DOES NOT MATTER IF THE RSA KEY IS BROKEN TEN YEARS FROM NOW because it is not related to the shared secret actually used for the actual encryption.

The only thing that matters is that an attacker can not crack the RSA key while it is still in service. 2048-bit RSA is strong enough to guarantee that and likely will be for at least a decade. The use case for RSA in TLS with Forward Secrecy is ephemeral and authenticity only. Understand that concept. Please understand that concept. Pretty please understand that concept.

If you still support cipher suites that do not use Forward Secrecy, that is your actual security problem, not the RSA private key size. Fix the actual problem.

What a bigger key size does, it exponentially increases the amount of work your server has to do with each key exchange it signs. For servers like mine that only receive a modest amount of mail, 4096-bit is easily handled. For very busy servers, 2048-bit gives much better performance. That can be critical during peak load times.

The scripts here do default to 4096-bit because I fear if they do not, social media influencers will mock these instructions as insecure and tell people I am an idiot so that their followers will use the services they are pimping rather than LibreLAMP. I am socially awkward, people like to mock me.

Many influencers will probably mock me anyway, but at least default key size is not a cause for the mocking that sounds reasonable to the ignorant who do not actually understand how it relates to security. They mocked me when I recommended against implementing HPKP yet now even Google (who invented it) has stopped supporting it, due to the very reasons I cited. They still mock me for my support of DNSSEC and DANE. I just am fun for them to mock. But enough about that.

My point is, feel free to edit the scripts and change the KEYSIZE variable from 4096 to either 2048. It will radically improve TLS performance during peak usage, and it is safe to do so. Anyone who tells you otherwise is lying. No one has even come remotely close to cracking 2048-bit RSA. Even 1024-bit still takes enormous resources to crack.

If you want stronger than 2048-bit RSA for a Submission server where users authenticate, use ECDSA for Submission. Not only is it stronger than 2048-bit RSA, but ECDSA is easier on the server too. Instructions are on the Dovecot TLS Certificate Generation page.

And please do not let this bias you against social media influencers. Some of them are honest and I respect those that are. Look at the quality of their content and the actual logic behind it, not what people say about them.

OCSP Stapling

Postfix does not yet support OCSP stapling. At the moment it looks like Postfix does not plan to. Feel free to bug the developers about it if you want. I chose not to bug them, I tend to come of as condescending when I bug developers about that kind of thing and I like the Postfix developers, but if you have better skills at persuasion please feel free to.

I do not feel confident enough in my own cryptography coding skills to provide a patch that adds such support, no stapling is better than poorly implemented stapling and many coders with better skill than I have have produced poor implementation of OCSP stapling in other servers. I can avoid their obvious mistakes (e.g. stapling malformed responses which has happened with some servers) but I may not be able to avoid the less obvious mistakes.

As such, the scripts for Postfix will not produce certificates that require OCSP stapling. I do hope Postfix adds it in the future. Where it matters most is SMTP Submission, though MTA-STS would also benefit.

Certificate with Chain of Trust

The script for Let’s Encrypt will produce an additional file that contains the certificate combined with the Certificate Authority Bundle. Postfix configuration recommends using a single file for both rather than separate files.

Self-Signed Certificate Option

For SMTP servers that do not support MTA-STS and do not accept connection from e-mail clients, self-signed certs can be deployed. I personally recommend only doing so if you also implement DNSSEC and Postfix DANE Security, though that is up to you.

Unless you implement MTA-STS the MTA client connecting to you is not going to care if your certificate validates with PKI or not, so self-signed is fine.

I do recommend you implement MTA-STA (see the Postfix PKI Security page) but if you do not, CA signed certificates only make sense if e-mail clients connect.

Thus I offer a script that generates a self-signed certificate for you in addition to a Let’s Encrypt script and a CSR script.

Private Key / CSR / Certificate Generation Scripts

For usage instructions, please refer to the Apache TLS Certificate Generation page.

Note that the script names and the files they generate contain SMTP in them. They will however also work with Dovecot if you prefer to use an RSA key pair with Dovecot.

To generate a Let’s Encrypt certificate: LE-SMTP-Keygen.sh.

To generate a CSR for use with a commercial certificate authority: CSR-SMTP-Keygen.sh.

Remember that both of those scripts, you need to edit them for a few local details (such as admin e-mail address) before you run them.

To generate a self-signed certificate: SS-SMTP-Keygen.sh.

Let’s Encrypt Notes

Sample session with the Let’s Encrypt script:

[root@domblogger ~]# systemctl stop httpd.service
[root@domblogger ~]# sh LE-SMTP-Keygen.sh domblogger.net mail.domblogger.net
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

[ redacted output ]

TLSA from PubKey:
3 1 1 02A53782C441170796728B3CB61129E020E93816139AB72CC969A0D0A51BEC9B

Private Key:    /etc/pki/tls/eff_private/domblogger.net-SMTP-20190523.key
x.509 Cert:     /etc/pki/tls/eff_certs/domblogger.net-SMTP-20190523.crt
CA Bundle:      /etc/pki/tls/eff_certs/domblogger.net-SMTP-CAB-20190523.pem
Cert Plus CAB:  /etc/pki/tls/eff_certs/domblogger.net-SMTP-CertPlusCAB-20190523.pem
DANE TLSA Data: /etc/pki/tls/tlsa/domblogger.net-SMTP-20190523.tlsa

New Private Key Generated.
Be sure to update your DNS TLSA record(s) if you use DANE
[root@domblogger ~]# systemctl start httpd.service

You only need to stop the httpd service if one is running on the server. Also, make sure your firewall does not block port 80 or 443.

Except when a new key is generated (first time you run it in a calendar year), only the certificate setting (smtpd_tls_cert_file parameter) needs to be updated in the Postfix /etc/postfix/main.conf file, the private key (smtpd_tls_key_file parameter) will remain the same.

CSR Script Notes

This script is for generating a CSR that is then manually submitted to a commercial Certificate Authority to obtain a certificate that is valid for one or two years rather than ninety days.

Even though Let’s Encrypt certificates are financially free, if you have the budget honestly I recommend just paying for a two-year Comodo certificate from Namecheap so that frequent renewal is not needed. The cheap PositiveSSL product is probably what you want, unless you need the certificate to be valid for more than one hostname, in which case you want the PositiveSSL Multi-Domain product. The more expensive products (EssentialSSL and InstantSSL) are just marketing, they do not add any actual security. The most expensive option, EV certificates, are meaningless for SMTP.

I still recommend generating a fresh private key once a year. The reason for a two-year certificate, your certificate does not expire if you are a little later than one year in generating a new one. At $16.00 for the single domain option, that is less than $2.00 a month.

Make January the month you renew. New year, new private key and new certificate. If you first buy a certificate late in the year (and it is a two year certificate) go ahead and skip the first January and wait until the next January to start the January renewal pattern.

While it is not 100% mandatory, it is recommended that you use a single file to contain the certificate and the bundle provided by Certificate Authority. The certificate for your server needs to be first in the file, the intermediary certificates (the Certificate Authority Bundle) come second. To combine them into a single file:

[root@host ~]# cat certificate-file.crt ca-bundle-file.crt > example.org-SMTP-CertPlusCAB-20190523.pem
[root@host ~]# mv example.org-SMTP-CertPlusCAB-20190523.pem /etc/pki/tls/certs/

The resulting file /etc/pki/tls/certs/example.org-SMTP-CertPlusCAB-20190523.pem is what you will use with the Postfix smtpd_tls_cert_file directive.

Self-Signed Notes

On Port 25, the sending MTA only cares about the validity of the certificate on receiving MTA when it has been specifically configured to care.

This is a consequence of Opportunistic TLS. When a connection can not be upgraded to encrypted, the connection continues in plain text anyway, so it is illogical to care whether or not the certificate is valid. Yes, that makes SMTP extremely easy to attack.

There are two solutions.

With DANE for SMTP, the client MTA will refuse the connection if the fingerprint of the certificate (or public key in the certificate) does not match a fingerprint retrieved from DNS secured by DNSSEC. That solution does not need the certificate to be signed by a Certificate Authority. This solution is described on the DNSSEC and Postfix DANE Security page.

The second solution is MTA-STS. It does require certificates signed by a Certificate Authority. This solution is described on the Postfix PKI Security page.

If you are not implementing MTA-STS then you simply do not need a Certificate Authority signed certificate for Port 25 traffic. A self-signed certificate is just as secure. However if you are also running a submission server, you really do need to use a signed certificate for that. You can use the same ECDSA certificate you use for Dovecot as described on the Dovecot TLS Certificate Generation page.

The self-signed certificate generated from the shell script I provide is valid for 1200 days (just over 3 years).

In practice you should generate a new one every year. The long expiration is just to prevent the certificate from expiring in the event that you do not. With the Opportunistic TLS practice of using plain text should encryption fail, I felt a long life was better than accidental expiration of the certificate.

Note that there is no Certificate Authority bundle with a self-signed certificate. This is because there are no intermediary certificates or a chain of trust.

DANE TLSA Record Notes

When changing the private key, the fingerprint of the public key obviously changes. Due to caching in the DNS system, you need to add the TLSA record for the new public key before you put it into service, or some clients will compare the fingerprint of the new public key against the fingerprint in the old TLSA record. The comparison will obviously fail resulting in the client refusing to connect.

Set a relatively short TTL on your TLSA records. I personally use 3600 which is one hour.

Leave the old TLSA records in place so your current certificate continues to validate, and add the new TLSA record to your DNS zone file. Generally when twice the TTL has passed, the new TLSA has propagated through the DNS system and it is safe to switch Postfix over to the new private key and certificate. However I prefer to wait twenty-four hours just to make sure.

When you have updated the Postfix /etc/postfix/main.conf file to use the new private key and certificate, you can then safely remove the old TLSA record.

This is what the TLSA records in your zone file might look like:

_25._tcp.example.org.        IN   TLSA ( 3 1 1 4e8d1dba09323acacf56ad828bc04b6d9c6f94a849c34d5b6ec30ea805d61027 )
_25._tcp.mail.example.org.   IN   TLSA ( 3 1 1 4e8d1dba09323acacf56ad828bc04b6d9c6f94a849c34d5b6ec30ea805d61027 )

Note it starts with an _ followed by a port number and then ._tcp followed by another . and then the host name ending with a ..

TLSA records are port specific, so you need to specify a record for each port that certificate is used on even if the domain name the certificate is valid for is the same.

For more information on the DANE TLSA record, see DNSSEC and Postfix DANE Security (internal site link).

Please note that a TLSA record is pointless if your zone is not secured by DNSSEC. Use of DNSSEC to secure your DNS zone is REQUIRED for DANE. You can still create the TLSA records, but they will be ignored simply because the data in them can not be validated and therefore can not be trusted.

Postfix Configuration

Please see the Postfix MTA Server TLS Configuration instructions on the LibreLAMP Postfix TLS Configuration page.