One recommended way to help secure your Postfix mail server is enabling TLS (Transport Layer Security) for connections to and from Postfix. You can search for more detailed descriptions of exactly how TLS works, but basically it’s a crypotgraphic protocol that allows connections between systems to remain secure. It relies on a key and a certificate to help accomplish its purposes, and this article will walk you through generating a key, getting your certificate, and installing everything on your Postfix system to enable TLS/SSL for SMTP connections.
Of course, this article assumes you already have Postfix working on your system.
Step 1: Sign up and Get Verified with StartSSL
Because they’re free, many Postfix admins use self-signed SSL certificates when setting up TLS. If your plan is to only enable mail submissions on port 25 (which I don’t recommend), then a self-signed certificate is good enough. But if your plan is to also enable mail submissions on port 587 (which I do recommend), a self-signed certificate will cause your users’ mail clients to spit out scary warnings about the identity of the remote server not being be verified. So I recommend getting a third-party signed SSL certificate for your Postfix server.
There are a handful of free SSL certificate issuers out there (such as CAcert), but I’ve been a happy user of StartSSL – the self-proclaimed “Swiss Army Knife of Digital Certificates & PKI.” While their interface may not be as slick as paid SSL providers (like GoDaddy or Network Solutions), what StartSSL lacks in design they make up for in value. You can actually get a 128/256-bit Encrypted Class 1 SSL/TLS + S.MIME certificate for free. Seriously, no strings attached.
The first step is to sign up at StartSSL and verify your personal identity via email, and also verify that you have admin authority for the domain. I noticed that Chrome won’t work properly with their authentication procedure, so you’ll need to use IE, Firefox, or Safari. I won’t go through all the verification steps here. Just follow the instructions on their website to get verified, and get to the Control Panel. Or, try their Express Lane option to get verified and receive a certificate in one step.
IMPORTANT: Make sure you choose the proper domain and subdomain name for your certificate when you come to that point. You can change your mind later, but you’ll have to pay $25 to do so. Just be sure you understand everything before you start clicking buttons…
Eventually, you’ll reach the Certificates Wizard. Select a Web Server SSL/TLS Certificate. Then press the Skip>> button, because you’ll want to create your own private key and certificate request on your server.
Step 2: Create Your Key and Certificate Request
The next screen is where you submit your certificate request (CSR). But first, you’ll need to build your private key and the CSR itself. Make a directory to store all your SSL files with
mkdir -p /etc/ssl cd /etc/ssl
Of course, you can choose any directory to store your SSL stuff, and you may already even have one. Use whatever directory you like. I personally like /etc/ssl because it’s easy to remember.
Inside your /etc/ssl directory, do:
openssl req -new -newkey rsa:2048 -nodes -keyout hostname.domain.key -out hostname.domain.csr
You can use any filename you want for the key and csr, but I like to include the subdomain and hostname of the mail server in mine, such as mail.example.key and mail.example.csr.
This command build both your private key and the CSR. Answer the questions (you don’t have to answer the optional ones), and be sure that when it requests the Common Name, use hostname and domain name of your server as you’ll be entering it in your email client (such as mail.example.com). If you make a mistake anywhere along the way, you can CTRL+C out of it, or just re-run the command to write a new key and CSR over the existing ones.
Once the command is finished, do an ls to see the two files you just created.
Your private key must be kept, well, private. So get into the habit of setting proper permissions for private keys right after you make them.
chmod 0640 hostname.domain.key
Step 3: Give your CSR to StartSSL and receive your certificate
Spit out the contents of your CSR with:
cat hostname.domain.csr
Then copy the entire contents of the file (including the:
-----BEGIN CERTIFICATE REQUEST-----
and
-----END CERTIFICATE REQUEST-----
lines, then paste it into the text area of the StartSSL CSR request page.
Hit the Continue>> button, and then select the specific subomain and domain you’ll use (such as mail.example.com or www.example.com) to access your server. For the free Class 1 certificate, you can include the domain and only one subdomain. This means the certificate will work for example.com and www.example.com, or example.com and mail.example.com.
If you want your certificate to work for two or more subdomains in addition to the primary domain, you’ll need to pay $59.99 to become Class 2 verified. But the good news is that you can then generate unlimited Class 2 certificates, which allow multiple and/or wildcard subdomains on your certificates. This is actually what I did, and it’s still a bargain.
After your request is processed, the certificate back from StartSSL, copy the contents and paste them into a file in your /etc/ssl directory called hostname.domain.crt (using your hostname and domain name, of course).
At this point, it’s a good idea to download all three files (key, csr, and crt) and store them somewhere safe. I have a secure USB key that I keep for such a purpose. Your .key file is irreplaceable at this point. If you lose it or accidentally delete it, you’ll have to revoke your certificate, which will cost you $25.
Step 4: Download the StartSSL Certificate Bundle
Certificates are about trust, and so you’ll need to inform your server that you trust StartSSL. List of certificate authorities that your server can trust are stored in Certificate Bundles. Download StartSSL’s bundle with:
wget --no-check-certificate https://www.startssl.com/certs/ca-bundle.pem -O startssl-ca-bundle.pem
If you have a pre-existing certificate bundle file somewhere on your server (such as ca-bundle.crt or cacert.pem), you may want to copy it into your /etc/ssl directory:
cp /etc/pki/tls/certs/ca-bundle.crt /etc/ssl
Then you’ll need to combine the StartSSL ca-bundle with your existing bundle (this step just copies the StartSSL bundle to the new filename if you didn’t have an existing bundle):
cat startssl-ca-bundle.pem >> ca-bundle.crt
Step 5: Edit your Postfix main.cf file
Now create a new section in your /etc/postfix/main.cf file (or edit it if you had one already) previously using a self-signed certificate) with the following settings. Take note that some of the settings start with smtpd and others start with smtp (incoming vs. outgoing mail settings) . Make sure you get things right (I recommend copying and pasting and then editing for your particular needs):
# SSL/TLS Settings # Allow TLS for incoming and outgoing smtpd_tls_security_level = may smtp_tls_security_level = may # Require senders to use TLS smtpd_tls_auth_only = yes # Add TLS info to message headers smtpd_tls_received_header = yes # Locations of TSL Certificate and Key Files smtpd_tls_cert_file = /etc/ssl/hostname.domain.crt smtpd_tls_key_file = /etc/ssl/hostname.domain.key # Location of the Certificate Authority Bundle for incoming and outgoing smtpd_tls_CAfile = /etc/ssl/cacert.pem smtp_tls_CAfile = $smtpd_tls_CAfile # Increase the logging for incoming and outgoing smtpd_tls_loglevel = 1 smtp_tls_loglevel = 1
Step 6: Edit your Postfix master.cf file
Since you’re requiring users to authenticate with TLS before they can send mail with the smtpd_tls_auth_only = yes option above, you’ll also need to edit a section of your /etc/postfix/master.cf file and uncomment a few lines to help that happen.
Edit your /etc/postfix/master.cf file and locate the following lines:
#submission inet n - n - - smtpd # -o smtpd_enforce_tls=yes # -o smtpd_sasl_auth_enable=yes # -o smtpd_client_restrictions=permit_sasl_authenticated,reject
You’ll need to uncomment the first three lines, but if you’re running Postfix 2.10 or later (and you really should be) leave the smtpd_client_restrictions line commented out. As of Postfix 2.10, it’s preferable to use smtpd_relay_restrictions for what we need. I recommend editing your submission section of master.cf to look like this:
submission inet n - n - - smtpd -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o milter_macro_daemon_name=ORIGINATING # -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,reject -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions= -o smtpd_data_restrictions= -o smtpd_end_of_data_restrictions=
Step 7: Restart Postfix and Test your Configuration
Once you’ve got your settings right, restart Postfix with:
service postfix restart
As a habit, any time I restart Postfix after a configuration change, I do a tail -f on my maillog to watch for any obvious errors.
For mail testing, it’s always helpful to have a Gmail account handy. Test your outbound TLS settings by using a mail client to authenticate and send a message from your Postfix server to your Gmail account. Your maillog should show something like this:
Jul 11 12:32:43 hostname postfix/smtpd[2992]: Anonymous TLS connection established from server.example.com[192.168.216.41]: TLSv1 with cipher RC4-SHA (128/128 bits) Jul 11 12:32:43 hostname postfix/smtpd[2992]: 6A937148079: client=server.example.com[192.168.216.41], sasl_method=PLAIN, sasl_username=username
Or, if you send a message direct from the Postfix server itself (using something like Alpine), your log would show something like:
Jul 11 12:32:43 hostname postfix/smtp[26822]: Trusted TLS connection established to gmail-smtp-in.l.google.com[74.125.28.27]:25: TLSv1 with cipher RC4-SHA (128/128 bits)
If everything looks good, send a message from your Gmail account to an account on your Postfix server. The maillog should show somethig like this:
Jul 11 12:34:01 servername postfix/smtpd[26811]: Anonymous TLS connection established from mail-wg0-f45.google.com[74.125.82.45]: TLSv1 with cipher RC4-SHA (128/128 bits)
Those messages show that TLS is working for both inbound and outbound connections.
Congratulations! You’ve got TLS set up on your Postfix mail server.
As always, I welcome your comments and feedback below. However, I don’t answer Postfix troubleshooting requests. For Postfix help, I highly recommend searching the archives of the Postfix-Users mailing list, or subscribing to the list and asking support questions there.