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.
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.
$ apt install certbot
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 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.
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
Edit the Postfix main configuration file /etc/postfix/main.cf
:
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
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.
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.
Congratulations!
Why do you use service restart instead of reload for postfix and dovecot. Don't both support reloading without a complete restart?