Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save unique1984/c61f355a39d0aacf681087be0b2c570d to your computer and use it in GitHub Desktop.
Save unique1984/c61f355a39d0aacf681087be0b2c570d to your computer and use it in GitHub Desktop.
Let's Encrypt / Dovecot / Postfix / UFW firewall / Certbot

Let's Encrypt / Dovecot / Postfix / UFW firewall / Certbot

This tutorial describes how to install TLS to a mail server consisting of Postfix and/or Dovecot by using Let's Encrypt certificates with automatic renewing and firewall management.

The system used for this tutorial was:

$ lsb_release -idrc
Distributor ID: Ubuntu
Description:    Ubuntu 17.10
Release:        17.10
Codename:       artful

This tutorial assumes the following prerequisites:

  • No firewall configured at all.
  • No HTTP server running. (It's a mail system, isn't it?).
  • Postfix and/or Dovecot without TLS running.

Let's Encrypt

Getting certificates from Let's Encrypt is done by tools. There are many. We will use certbot. It is straight forward and will do all the hard work.

Install certbot

$ apt install certbot

Create an Account

First time you need to create a Let's Enrypt account. Certbot will do it for you:

$ certbot

You will be asked some questions. Be gentle and honest.

Request a certificate

Request a certificate for your mail server. Again, certbot is your friend:

$ certbot certonly --standalone -d your.server.toplevel

Replace your.server.toplevel with the FQDN of your server. Make sure the name corresponds to your DNS entries.

Now you have a working certificate. However, the certificate will expire in 90 days. But certbot will take care for you and a cron job renews your certificate 30 days before expiration, automatically.

But interaction with the (yet to be installed) firewall and restarting Dovecot and Postfix is missing.

Please read on.

Enable TLS in Dovecot

Assuming a standard configuration, edit /etc/dovecot/conf.d/10-ssl.conf:

ssl = required
ssl_cert = </etc/letsencrypt/live/your.server.toplevel/fullchain.pem
ssl_key = </etc/letsencrypt/live/your.server.toplevel/privkey.pem

Replace your.server.toplevel with the FQDN of your server.

Restart Dovecot:

$ systemctl restart dovecot.service

Enable TLS in Postfix

Edit the Postfix main configuration file /etc/postfix/

smtp_tls_security_level = may
smtp_tls_note_starttls_offer = yes
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/your.server.toplevel/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/your.server.toplevel/privkey.pem

Replace your.server.toplevel with the FQDN of your server.

There are more detailed tutorials how to tweak TLS in Postfix available. Use them for more detailed information.

Restart Postfix:

$ systemctl restart postfix.service

Setup Firewall

We will use UFW firewall. It is simply, straight forward and works out of the box.

Normally UFW is already installed with Ubuntu but deactivated. If not installed, install it using apt install ufw.


Before enabling the firewall it is absolutely essential to configure SSH to be allowed! If you miss this you get locked out of your server!

Enable SSH, Postfix and Dovecot in UFW and deny HTTP. Type at the console:

ufw allow OpenSSH
ufw allow "Dovecot IMAP"
ufw allow "Dovecot Secure IMAP"
ufw allow Postfix
ufw allow "Postfix SMTPS"
ufw allow "Postfix Submission"
ufw deny http

Again: Missing the first line ufw allow OpenSSH will lock you out of your server!

You allowed OpenSSH, do you? Then you are ready to enable UFW:

$ ufw enable

Now your firewall is up and running.

Hooks for UFW, Postfix and Dovecot

Every time certbot have to renew a certificate it starts a standalone webserver for communication with the Let's Encrypt infrastructure. But of course, because we are a mail system, networking traffic to port 80 (HTTP) is denied by the firewall.
So certbot needs a way to tell the firewall to open port 80 (HTTP) temporally for a few seconds and closing it afterwards.

A second issue is telling Postfix and Dovecot to reload their certificate when it was renewed by certbot. This is easiest done by a restart.

Wisely, the certbot authors have foreseen these requirements and implemented hooks.

Create a file /etc/letsencrypt/cli.ini with this configuration content:

# Manage Firewall
pre-hook = ufw allow http
post-hook = ufw deny http

# Restart Postfix & Dovecot
renew-hook = systemctl restart dovecot.service postfix.service

The pre-hook gets called before the standalone HTTP server is started by certbot and post-hook gets called after communication with Let's Encrypt is done. The whole procedure takes only a few seconds.

When the certificate was renewed successfully, renew-hook gets called to restart Dovecot and Postfix.


Yes, that's it!

Now you have a working TLS encrypted mail server with automatic certificate renewal and firewall.


References and Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment