Skip to content

Instantly share code, notes, and snippets.

@mrothNET
Last active August 14, 2024 00:15
Show Gist options
  • Save mrothNET/cb6f313e9cbe896f3e0fdec80ad2f3fa to your computer and use it in GitHub Desktop.
Save mrothNET/cb6f313e9cbe896f3e0fdec80ad2f3fa 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/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

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.

Attention:

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.

Done

Yes, that's it!

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

Congratulations!

References and Links

@RossComputerGuy
Copy link

When I try connecting via mailspring, I get this error:

----------IMAP----------
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot (Ubuntu) ready.
1 LOGIN "[email protected]" *********
1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE] Logged in
2 ENABLE QRESYNC
* ENABLED QRESYNC
2 OK Enabled (0.001 + 0.000 secs).
3 NAMESPACE
* NAMESPACE (("" ".")) NIL NIL
3 OK Namespace completed (0.001 + 0.000 secs).
4 LIST "" "*"
* LIST (\HasNoChildren) "." INBOX
4 OK List completed (0.001 + 0.000 secs).


----------SMTP----------


mailsmtp Last Error Code: MAILSMTP_ERROR_SSL

mailsmtp Last Error Location: 5

mailsmtp Last Auth Type: 0

@adipose
Copy link

adipose commented Oct 26, 2020

Why do you use service restart instead of reload for postfix and dovecot. Don't both support reloading without a complete restart?

@strarsis
Copy link

strarsis commented Nov 6, 2020

And why is the CLI config used instead the individual certbot certificate config or renewal hook.

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