If you have registered a domain name and would like to use it for email, you might want to set up a mail transfer agent (MTA) through which you can send and receive messages. A great option for an MTA software is the free and open-source Postfix that aims to be fast, easy to administer, and secure. Ensuring a secure Postfix server in any network requires great care in its configuration, but with the help of Let’s Encrypt and Dovecot, the whole process is practically plug-n-play.

Secure Postfix with Let's Encrypt and Dovecot

This guide goes through the steps required in configuring a secure Postfix STMP server with certificates provided by the Let’s Encrypt certificate authority and Dovecot that is used for client authentication. The instructions listed below are intended for Ubuntu 16.04, but the components are available on other distributions as well with just minor changes to the installation commands.

Creating DNS records

The first step in setting up a trustworthy email server is to create the required domain name and mail exchanger records. This process will differ depending on which Domain Name Server you are using to manage your domain name. Most domain name servers will provide instructions or documentations on how these settings can be done.

For example, you could add a subdomain for your SMTP server such as mail.example.com and enable an MX record that points to that subdomain.

The records that you will need to configure:

  • DNS A record, that maps your domain name to the server’s public IP address.
    example.com   A    83.136.253.111
  • MX record, which will tell other mail servers where messages send to your domain should be delivered.
    example.com   MX   1   mail.example.com.
    @             MX   2   mail.example.com.
  • Reverse DNS record, that allows servers to check what domain your server’s IP address belongs to.
    PTR record for IPv4

You can set the reverse DNS name per public IP address at your UpCloud Control Panel under Server settings and IP Addresses tab.

These settings might take a moment to propagate to other DNS servers so it is a good to get them done early.

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.

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.

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:
    Internet Site
  2. System mail name – Replace the <example.com> with your domain name:
    <example.com>
  3. Root and postmaster mail recipient – Any Unix user account:
    root
  4. Other destinations to accept mail for – Include $mydomain as the final destination:
    $mydomain, $myhostname, localhost.$myhostname, , localhost
  5. Force synchronous updates on mail queue?
    No
  6. Local networks:
    127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
  7. Mailbox size limit (bytes):
    0
  8. Local address extension character:
    +
  9. Internet protocols to use:
    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.

sudo postconf -e 'home_mailbox = Maildir/'

Using the Maildir mailbox format emails are stored in under the recipient user’s home folder /home/<username>/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.

sudo postconf -e 'mydomain = <example.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.

sudo apt install letsencrypt

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

sudo letsencrypt certonly --standalone -d <mail.example.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.example.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/<your.domain>/. You can add your new certificates to the Postfix configuration using the two commands below. Replace the <your.domain> with your email server’s domain name.

sudo postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/<your.domain>/fullchain.pem'
sudo postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/<your.domain>/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.

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.

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.

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 example.com domain. Assign the email addresses you want enabled to a username using the same pattern of <[email protected]> <username>.

sudo nano /etc/postfix/virtual
[email protected] root
[email protected] root
[email protected] info

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

sudo postmap /etc/postfix/virtual

Then restart Postfix itself to apply the full configuration.

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.

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.

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.

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.

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.

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

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

sudo nano /etc/dovecot/conf.d/10-mail.conf
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.

sudo nano /etc/dovecot/conf.d/10-master.conf
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 <mail.example.com> with your server’s domain name. Select to require SSL and also disable the insecure SSLv2 and SSLv3 protocols.

sudo nano /etc/dovecot/conf.d/10-ssl.conf
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = required
...
ssl_cert = </etc/letsencrypt/live/<mail.example.com>/fullchain.pem
ssl_key = </etc/letsencrypt/live/<mail.example.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.

dovecot -n

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

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.

nc mail.example.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.

sudo apt install mailutils

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

mail

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

mail [email protected]

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.

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.

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.

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.

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.

sudo nano /etc/postfix/virtual
...
@example.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.

sudo nano /etc/aliases
# 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.

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

Then reload Postfix again to enable the new settings.

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.

Maintaining security

Configuring and maintaining a secure Postfix SMTP server only requires a basic understanding of the components, but simple mistakes in the setup can render the security settings ineffective, therefore most important part is to make sure the server does not become an open relay. Conveniently MX Toolbox, an online network testing utility, provides an SMTP diagnostics tool with which you can easily test your configuration by just entering your mail server domain name such as mail.example.com. With the setup used in this guide, everything should show green in their tests, granted that the DNS rules have propagated.

While a good configuration helps to keep your SMTP server secure, strong user passwords are also very important. In such a case that a third party was to gain unauthorised access to one of the user account, they would be able to send spam messages unhindered using your infrastructure and tarnish your network reputation. A common way to reduce the chance of someone guessing your user’s passwords is to impose limitations to failed logging attempts with Fail2ban. You can read more about install Fail2ban on Ubuntu in its own article to further improve the server security.

General good usage practices can also bring your server security a long way. In addition to the aforementioned security methods, Linux systems offer a number of ways to minimise vulnerabilities and harden your cloud server against abuse. Take a look at our introductory guide to how to secure your Linux cloud server if you wish to learn more.