How to Secure Postfix Using Let’s Encrypt

Installing Postfix

Postfix is the default MTA for Ubuntu and can be installed directly with the package manager. Use the following command to install the required packages.

1
sudo apt install postfix

Once the installation is complete, the setup will run a configuration script that asks to define a few settings, select the defaults for now by pressing enter to continue.

With Postfix installed, run the full configuration script to define the settings as below.

1
sudo dpkg-reconfigure postfix

The reconfiguration command will display the configuration interface again, select the following values in order of appearance.

1. General type of mail configuration:

1
Internet Site

2. System mail name – Replace the with your domain name:

1
<itkylin.com>

3. Root and postmaster mail recipient – Any Unix user account:

1
root

4. Other destinations to accept mail for – Include $mydomain as the final destination:

1
$mydomain, $myhostname, localhost.$myhostname, , localhost

5. Force synchronous updates on mail queue?

1
No

6. Local networks:

1
127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128

7. Mailbox size limit (bytes):

1
0

8. Local address extension character:

1
+

9. Internet protocols to use:

1
all

The configuration is written into the /etc/postfix/main.cf file. In case you want to make changes to the above settings, you can always run the reconfiguration script again.

By default, Postfix uses the mbox mailbox format. Another commonly used option is Maildir which stores emails in individual files reducing the chance of your mail database getting corrupted. The following settings will use Maildir but you are free to choose any format. If you wish to use something else, remember to also configure it for Dovecot.

Rather than editing the configuration file directly, you can use the postconf -e command to change the Postfix parameters.

1
sudo postconf -e 'home_mailbox = Maildir/'

Using the Maildir mailbox format emails are stored in under the recipient user’s home folder /home//Maildir.

Also, tell Postfix what domain it is the final destination for so that it can be easily referenced as a Postfix variable as was already show in the configuration script.

1
sudo postconf -e 'mydomain = <itkylin.com>'

Now that Postfix is installed, you can continue below with further configurations.

Getting Let’s Encrypt certificates

Enabling the TLS will require you to obtain certificates. Let’s Encrypt is a free, automated, and open Certificate Authority that allows easy certificate setup using the Certbot ACME client from the Electronic Frontier Foundation.

An easy way to get the certificates issued on a server that does not have a running web server is to use the client with the –standalone plug-in. Start by installing the Let’s Encrypt module.

1
sudo apt install letsencrypt

Once the install is finished, you can run the certificate process with the easy command below. Replace the with your domain name.

1
sudo letsencrypt certonly --standalone -d mail.itkylin.com

The command starts an interactive configuration script which will ask a couple of questions to setup the certificate correctly.

1.Select Yes to use the default vhost file and specify the settings manually.
2.Enter the email server’s domain name like mail.itkylin.com.
3.On the first installation on any specific host, you’ll need to enter a contact email.
4.Next, read the Let’s Encrypt Terms of Service and select Agree to continue.
5.Then select whether you wish to use both HTTP and HTTPS or to require all traffic to use encryption by highlighting either the Easy or the Secure option and selecting OK.

If everything worked correctly you’ll get a message that HTTPS was successfully enabled.

If you already have a web service installed on your mail server, you can find more about how to obtain certificates with Apache2 or Nginx in their software-specific instructions.

Once you have finished the process, the certificates will be stored under /etc/letsencrypt/live/itkylin.com/. You can add your new certificates to the Postfix configuration using the two commands below. Replace the with your email server’s domain name.

1
2
sudo postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/itkylin.com/fullchain.pem'
sudo postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/itkylin.com/privkey.pem'

With the certificate installed, you can configure the rest of the email server.

Setting up SMTP authentication

Next, you should enable SMTP-AUTH, which allows a client to identify itself through the authentication mechanism SASL. Transport Layer Security (TLS) should be used to encrypt the authentication process. Once authenticated, the server will allow the client to relay mail.

Enter the following edits as they are.

1
2
3
4
5
6
7
sudo postconf -e 'smtpd_sasl_type = dovecot'
sudo postconf -e 'smtpd_sasl_path = private/auth'
sudo postconf -e 'smtpd_sasl_local_domain ='
sudo postconf -e 'smtpd_sasl_security_options = noanonymous'
sudo postconf -e 'broken_sasl_auth_clients = yes'
sudo postconf -e 'smtpd_sasl_auth_enable = yes'
sudo postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'

Then configure Postfix to provide TLS encryption for both incoming and outgoing mail.

1
2
3
4
5
sudo postconf -e 'smtp_tls_security_level = may'
sudo postconf -e 'smtpd_tls_security_level = may'
sudo postconf -e 'smtp_tls_note_starttls_offer = yes'
sudo postconf -e 'smtpd_tls_loglevel = 1'
sudo postconf -e 'smtpd_tls_received_header = yes'

Enabling the SASL lets users send messaged outside the local domain without compromising the security of the relay.

Virtual alias mapping

The last bit of configurations for Postfix is to map the email addresses you wish to use to your user accounts. With virtual alias domains, each hosted address can be aliased to a local UNIX system account or a remote address. Enable virtual alias mapping with the following two edit commands.

1
2
sudo postconf -e 'virtual_alias_domains = $mydomain'
sudo postconf -e 'virtual_alias_maps = hash:/etc/postfix/virtual'

You can then create the alias map indicated above. The example below shows how to use this mechanism for the itkylin.com domain. Assign the email addresses you want enabled to a username using the same pattern of .

1
sudo nano /etc/postfix/virtual

Once you have configured the virtual aliases, tell Postfix to generate the required database file from the list.

1
sudo postmap /etc/postfix/virtual

Then restart Postfix itself to apply the full configuration.

1
sudo systemctl restart postfix

You might also want to add the Maildir setup to the user home directory template so that it is automatically configured when a new user account is created.

1
2
3
4
5
sudo maildirmake.dovecot /etc/skel/Maildir
sudo maildirmake.dovecot /etc/skel/Maildir/.Drafts
sudo maildirmake.dovecot /etc/skel/Maildir/.Sent
sudo maildirmake.dovecot /etc/skel/Maildir/.Trash
sudo maildirmake.dovecot /etc/skel/Maildir/.Templates

The same Maildir can be added to the current user with the commands below. Replace the $USER with any existing username if that user does not have sudo privileges.

1
2
3
4
sudo cp -r /etc/skel/Maildir /home/$USER/
sudo chown -R $USER:$USER /home/$USER/Maildir
sudo chmod -R 700 /home/$USER/Maildir
sudo adduser $USER mail

Finally, include the Maildir location in your terminal and mail profiles.

1
echo 'export MAIL=~/Maildir' | sudo tee -a /etc/bash.bashrc | sudo tee -a /etc/profile.d/mail.sh

Relog to the terminal to apply the group changes by reopening the SSH connection.

Configuring Dovecot

Postfix supports two SASL implementations, that are used for authentication, Cyrus and Dovecot. Of these two, Dovecot is relatively simple to configure and was therefore selected for this guide. To enable Dovecot SASL you will need to install the dovecot-common package. You might also wish to install the Dovecot plugins for IMAP and POP3 to allow connections from mail clients such as Thunderbird or Outlook.

1
sudo apt install dovecot-common dovecot-imapd dovecot-pop3d

Once installed, you will need to make some changes to few of the configuration files. Dovecot configuration is split between a number of files under /etc/dovecot/conf.d/. To enable the required security features, make the changes and indicated below to the next four .conf files.

Start by disabling the plaintext authentication at the top and enabling login authentication mechanism near the end of the auth.conf file.

1
sudo nano /etc/dovecot/conf.d/10-auth.conf
1
2
3
disable_plaintext_auth = yes
...
auth_mechanisms = plain login

Then instruct the mail directory to use the same format as Postfix.

1
sudo nano /etc/dovecot/conf.d/10-mail.conf
1
mail_location = maildir:~/Maildir

Next, configure the IMAP and POP3 protocols for email clients in the master.conf file as shown below. Uncomment the port lines shown underneath by deleting ‘#’ sign at the start of these lines. In the same file, also edit the service auth segment to allow user authentication.

1
sudo nano /etc/dovecot/conf.d/10-master.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
service imap-login {
   inet_listener imap {
      port = 143
   }
...
}
service pop3-login {
   inet_listener pop3 {
      port = 110
   }
   ...
}
...
service auth {
...
   # Postfix smtp-auth
   unix_listener /var/spool/postfix/private/auth {
      mode = 0660
      user = postfix
      group = postfix
}

Most email clients default to the standard ports, 143 for IMAP and 110 for POP3. With STARTTLS required for every connection, there is no need to duplicate the services to the SSL dedicated ports.

You will also need to include your certificates in the Dovecot ssl.conf file, replace the with your server’s domain name. Select to require SSL and also disable the insecure SSLv2 and SSLv3 protocols.

1
sudo nano /etc/dovecot/conf.d/10-ssl.conf
1
2
3
4
5
6
7
8
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = required
...
ssl_cert = </etc/letsencrypt/live/mail.itkylin.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.itkylin.com/privkey.pem
...
# SSL protocols to use
ssl_protocols = !SSLv2 !SSLv3

When you are done editing the files, you can check the Dovecot configuration with the following command.

1
dovecot -n

Once everything looks correct, restart Dovecot to apply the new settings.

1
sudo systemctl restart dovecot

That is it! Congratulations, your mail server is now ready to receive and send emails using secure authentication.

Testing the SMTP server locally

You can test the Postfix server locally from the terminal by using a direct connection with netcat, telnet or similar. The following commands need to be executed in the correct order or the server will close the connection.

1
2
3
4
5
6
7
8
9
10
nc mail.itkylin.com 25
EHLO $hostname
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Test email
 
Body of the email
.
QUIT

If the configuration worked correctly, you should see a confirmation that the email you just wrote has been placed in the queue and will arrive momentarily.

Note that using this method you can only send emails to your own domain addresses. When attempting to set recipient outside your own domain, you will see a message stating that relay access is denied and the connection will be closed.

Another little more convenient way to use email from the terminal is to install Mailutils.

1
sudo apt install mailutils

It can be used to check mail with the simple command below.

1
mail

You can also test sending mail using the same utility by adding the recipient address.

Then complete the email form with subject and body text. Send the message by pressing Ctrl+D which exits the utility. Using this method will allow you to send messages outside your network. However, the sender and return addresses will show your username and server domain name, e.g. [email protected], instead of the probably more desirable [email protected]. Therefore this method should only be used for testing purposes.

Additional security options

The main concerns of running a private SMTP server will be combating both incoming and outgoing spam messages. A secure configuration and strong user passwords will help with the latter but you might wish to take additional steps to prevent incoming spam.

Reject bad connections and spam messages

Tightening the rules for SMTP connections can stop many of the common spambots that disregard email etiquette. Requiring a valid HELO or EHLO command with a fully qualified domain name can do just that. Add the following parameters to further improve your secure Postfix configuration.

1
2
sudo postconf -e 'smtpd_helo_required = yes'
sudo postconf -e 'smtpd_helo_restrictions = reject_non_fqdn_helo_hostname,reject_invalid_helo_hostname,reject_unknown_helo_hostname'

Postfix supports a verify (VRFY) command which allows anyone to determine if an account exists on the system, which can provide significant assistance to any brute force attack on your user accounts. VRFY may also give out sensitive information about the users, such as the account owners full name. It is recommended to disable the VRFY command with the following parameter.

1
sudo postconf -e 'disable_vrfy_command = yes'

You might also wish to delay the reject message to allow Postfix to log recipient address information when the connected client breaks any of the reject rules. This allows you to later find out who the spammers were trying to target.

1
sudo postconf -e 'smtpd_delay_reject = yes'

The Postfix recipient restrictions that were set in the SASL configuration part are important in securing the server while allowing users to connect with email clients such as Thunderbird or Outlook. Keeping these parameters in the right order will retain this ability, but you can include further restrictions that incoming messages will need to comply with.

1
sudo postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination,reject_invalid_hostname,reject_non_fqdn_hostname,reject_non_fqdn_sender,reject_non_fqdn_recipient,reject_unknown_sender_domain,reject_rbl_client sbl.spamhaus.org,reject_rbl_client cbl.abuseat.org'

The parameters above are fairly self-explanatory though a little difficult to read in a terminal copy paste friendly format. The general idea is to reject connections from made up addresses that do not use a fully qualified domain name or simply do not exist. Here is possible to also add external spam filters such as the Spamhaus or CBL blacklists. If you wish to find out more, Postfix has a very extensive documentation on its configuration options.

Directing spam to /dev/null

Postfix supports a so-called catch-all address with the virtual aliases. Any emails sent to an address not specified in the virtual map will be directed according to the catch-all address. This is useful to hide the valid addresses by allowing mail delivery to any address hence preventing spammers from finding real users through simple trial and error.

Enable the catch-all address by adding a line as shown in the example below to the end of your virtual mapping without any local part and direct the messages to a virtual user nobody.

1
sudo nano /etc/postfix/virtual
1
2
...
@itkylin.com nobody

To prevent spam from filling up all of your storage space, edit the system aliases list to direct messages sent to invalid addresses straight to /dev/null.

1
sudo nano /etc/aliases
1
2
3
# See man 5 aliases for format
postmaster: root
nobody: /dev/null

Once you have configured both the system and virtual aliases, tell Postfix to regenerate the required database files from these lists.

1
2
sudo postmap /etc/postfix/virtual
sudo postalias /etc/aliases

Then reload Postfix again to enable the new settings.

1
sudo service postfix reload

You can test the spam trap by sending a message to any random unconfigured email address, the mail should be delivered successfully but will not be stored. Another way to test this is by using an address validator such as the Email Checker, any address should show up as valid, even the none existing ones.