Create and Deploy Postfix TLS Certificates Safely
The postfix tls command turns certificate generation into a checkable pipeline instead of an OpenSSL incantation you hope you typed right. You will test the defaults, generate a key and self-signed certificate, prepare a CSR or DANE records, and deploy only after reviewing the result. The examples match Postfix 3.8.6 and its postfix tls command. Allow 20 to 30 minutes, plus however long your certificate authority or DNS provider takes.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need: the
postfixpackage, thepostfixadministrative command, a hostname that resolves to this server, and root privileges for commands that update Postfix configuration. - Placeholder: replace
mail.example.orgwith the public SMTP hostname you actually use. - Back up first: these commands affect the SMTP service and private keys, so take a backup of the Postfix configuration before deployment.
1. Check the installed command and configuration
Confirm the version and find the configuration directory before generating anything:
$ postconf mail_version
mail_version = 3.8.6
$ postconf config_directory
/etc/postfix
The command is invoked as postfix tls, but the administrative interface is restricted to the superuser on this machine. Read-only inspection through postconf can normally be done as an ordinary user. Do not use a guessed configuration path in later commands.
Checkpoint
Record the value printed by postconf config_directory. Generated filenames are relative to this directory when the manpage says a relative path is allowed.
2. Confirm that the defaults are safe to enable
enable-server changes settings only when the SMTP server TLS parameters still have their defaults. Test that condition first:
# postfix tls all-default-server
# printf 'status=%s\n' "$?"
status=0
Status 0 means every relevant server TLS setting is still at its default. A non-zero result means the command will not silently take over an existing TLS design; stop and inspect the current values instead:
$ postconf smtpd_tls_security_level smtpd_tls_cert_file smtpd_tls_key_file smtpd_tls_eccert_file smtpd_tls_eckey_file
Do not overwrite an intentional configuration merely to make the check pass. There is a matching guard for the client side, all-default-client, if you are configuring outbound opportunistic TLS rather than the receiving SMTP server.
3. Generate a server key and certificate without deploying it
Generate an RSA key and self-signed certificate for the server name and its alternative name:
# postfix tls new-server-key -a rsa -b 2048 mail.example.org smtp.example.org
This creates files with UTC timestamped names such as key-20260926-120000.pem and cert-20260926-120000.pem in the Postfix configuration directory. The actual timestamp and output filenames will differ. The command displays deployment, CSR and TLSA commands, so save that output; this subcommand does not deploy the new files.
RSA 2048 is the documented default. ECDSA is also supported when the local OpenSSL and clients support it:
# postfix tls new-server-key -a ecdsa -b secp256r1 mail.example.org smtp.example.org
- Stick to documented curves. Use only
secp256r1,secp384r1orsecp521r1for broad interoperability. - DSA is not supported.
- Need both algorithm families? Generate and deploy both rather than assuming every client can use ECDSA.
Checkpoint
Verify the generated files are present and private key permissions are restricted:
# ls -l /etc/postfix/key-*.pem /etc/postfix/cert-*.pem
# openssl x509 -in /etc/postfix/cert-YYYYMMDD-HHMMSS.pem -noout -subject -issuer -dates
Use the exact filenames printed by your run. The self-signed certificate is temporary until a CA-signed certificate replaces it.
4. Prepare a CA request or DANE record
For a public CA, produce a CSR from the generated key. The -k option accepts a pathname or an algorithm name such as rsa:
# postfix tls output-server-csr -k /etc/postfix/key-YYYYMMDD-HHMMSS.pem mail.example.org smtp.example.org > /root/mail.example.org.csr
# openssl req -in /root/mail.example.org.csr -noout -subject
Protect the CSR file, although it does not contain the private key. When the CA returns the server certificate, put the server certificate first in the chain file, followed by every required intermediate certificate. Keep the matching private key unchanged.
If you operate DANE, generate TLSA data from the key files and publish it before deployment:
# postfix tls output-server-tlsa -h mail.example.org /etc/postfix/key-YYYYMMDD-HHMMSS.pem
Wait for DNS secondaries and cached records to update before switching to a new key. A DANE deployment made in the wrong order can make TLS verification fail for remote senders.
5. Deploy the reviewed certificate and key
Warning
This changes the certificate Postfix presents and can disrupt SMTP clients if the names, chain or key do not match. Keep the currently deployed files until the new service has been tested.
Deploy the certificate file and its matching private key. Use the exact paths from the generation step, or the CA chain file you prepared:
# postfix tls deploy-server-cert /etc/postfix/cert-mail.example.org-chain.pem /etc/postfix/key-YYYYMMDD-HHMMSS.pem
The filenames may be relative to config_directory, but absolute paths make a change record less ambiguous. Check the resulting parameters:
$ postconf smtpd_tls_cert_file smtpd_tls_key_file smtpd_tls_eccert_file smtpd_tls_eckey_file
Reload Postfix through the normal service manager used by your system, then test an SMTP connection from a separate host. If the certificate is wrong, redeploy the previous certificate and key with the same deploy-server-cert command, then reload again. Do not delete old files until mail flow and certificate validation have passed.
6. Enable opportunistic TLS only when appropriate
If every server TLS setting was still at its default and you want Postfix to enable opportunistic TLS and create its own initial certificate, the combined operation is:
# postfix tls all-default-server && postfix tls enable-server mail.example.org
If the guard fails, enable-server suggests parameter settings without changing them. Treat that output as advice to review, not a command to paste blindly. For outbound SMTP, the equivalent guarded operation is:
# postfix tls all-default-client && postfix tls enable-client
Neither guard proves a remote server will trust your certificate, and opportunistic TLS is not the same as mandatory authenticated encryption.
Done means
- Identified the installed Postfix release with
postconf mail_version. - Recorded the relevant
all-default-*check before enabling anything. - Covered: the certificate names cover the SMTP hostname and the private key is protected.
- Handled the CSR or TLSA output before deployment where applicable.
- Confirmed Postfix presents the intended certificate after reload, with previous files kept for rollback.