In this post, we will configure personal e-mail hosting on a Debian Gnu/Linux 9 (stretch) server. The server will be able to:
- send and receive e-mails (SMTP with Postfix)
- read e-mails from clients (IMAP with Dovecot)
- secure connections (SSL/TLS)
- authenticate users using system usernames and passwords (PAM)
We assume that you already have your domain name, say example.com, and that
the MX records of your DNS
configuration point to your server. You can check this quickly using
dig
:
dig +short MX example.com
Generating SSL certificates¶
The best solution to generate SSL certificates nowadays is to use Let's Encrypt. Install it by:
sudo apt-get install certbot python3-certbot-nginx
Request a certificate for your mail server by:
certbot certonly --standalone -d mail.mydomain.com
Replacing mail.mydomain.com
with the fully qualified domain name
(FQDN) of your
server. Certificates issued by Let's Encrypt expire after 90 days, but will be
automatically renewed every 60 days by a Cron job (installed by default in the
Debian distribution).
Configuring Postfix¶
Postfix is a Mail Transfer Agent (MTA), that is, software that sends and receives e-mails to and from other computers on the network using the Simple Mail Transfer Protocol (SMTP). From the point of view of an e-mail client, POP/IMAP are the protocols used for receiving messages, and SMTP is used for sending. However, it is not true that "POP/IMAP = receive" and "SMTP = send": e-mail servers use SMTP to exchange messages between themselves, that is, both sending and receiving. What is correct is that:
- POP/IMAP are used by a client to read messages from an e-mail server;
- SMTP is used to exchange e-mails between computers.
If your computer was on and connected to the network all the time, you could use SMTP to receive messages to your machine. However, as your computer can be turned off or disconnected, the most common pattern is that you ask your e-mail server to keep messages for you, and read them later on using POP/IMAP.
This being said, let us install Postfix!
sudo apt-get install postfix
An ncurses GUI will pop up with some configuration questions. Answer as follows:
- General type of mail configuration: "Internet Site";
- Mail name: enter your domain name, example.com in our example;
- Leave the default values to other questions.
Go to your configuration file /etc/postfix/main.cf
and make sure your
domain name and SSL configuration fields are correct. Here are some snippets
from my configuration file (beware: it is not a complete configuration file):
# Hostname and domain name
myhostname=mymachine.example.com
mydomain=example.com
myorigin=$mydomain
# SSL/TLS certificates
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.mydomain.com/privkey.pem
smtpd_use_tls=yes
smtpd_tls_auth_only=yes
# Anti-SPAM rules adapted from https://wiki.debian.org/Postfix
# Updated with https://docs.spamhaus.com/datasets/docs/source/40-real-world-usage/PublicMirrors/MTAs/020-Postfix.html
smtpd_recipient_restrictions = permit_sasl_authenticated,
reject_invalid_hostname,
reject_unknown_recipient_domain,
reject_unauth_destination,
reject_rbl_client zen.spamhaus.org=127.0.0.[2..11]
reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[2..99]
reject_rhsbl_helo dbl.spamhaus.org=127.0.1.[2..99]
reject_rhsbl_reverse_client dbl.spamhaus.org=127.0.1.[2..99]
warn_if_reject reject_rbl_client zen.spamhaus.org=127.255.255.[1..255]
permit
smtpd_helo_restrictions = permit_sasl_authenticated,
reject_invalid_helo_hostname,
reject_non_fqdn_helo_hostname,
reject_unknown_helo_hostname
smtpd_client_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
reject_rbl_client cbl.abuseat.org,
permit
# Mail user agent restrictions adapted from https://askubuntu.com/a/1132874
smtpd_restriction_classes = mua_sender_restrictions,
mua_client_restrictions,
mua_helo_restrictions
mua_sender_restrictions = permit_sasl_authenticated, reject
mua_client_restrictions = permit_sasl_authenticated, reject
mua_helo_restrictions = permit_mynetworks,
reject_non_fqdn_hostname,
reject_invalid_hostname,
permit
# Mail will be stored in users' ~/Maildir directories
#
# NB: make sure to enforce this setting as well in the `mail_location`
# of /etc/dovecot/conf.d/10-mail.conf (thanks to Markus Hoffmann for
# pointing this out):
#
# mail_location = maildir:~/Maildir
#
home_mailbox = Maildir/
mailbox_command =
# From http://wiki2.dovecot.org/HowTo/PostfixAndDovecotSASL
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
Here we are forcing secure authentication with smtpd_tls_auth_only
(just comment it out to allow for unencrypted traffic). An important field is
the list of smtpd_recipient_restrictions
(note that it is specific to
Postfix 2.9.x, which comes by default on Debian Wheezy; for later versions of
Postfix, use smtpd_relay_restrictions
). It is a list of instructions,
such as "permit" or "reject", that the server will apply in this order to
received e-mails.
Later on, you may want to look at aliases (used to forward e-mails) or virtual e-mail addresses (used to create mailboxes not tied to a Unix account), both of which are described in the Debian Wiki page for Postfix.
Next, go to /etc/postfix/master.cf
and uncomment the lines starting
with #submission
and #smtps
. On my machine, it was:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
-o smtpd_helo_restrictions=$mua_helo_restrictions
-o smtpd_sender_restrictions=$mua_sender_restrictions
-o smtpd_recipient_restrictions=
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
-o smtpd_helo_restrictions=$mua_helo_restrictions
-o smtpd_sender_restrictions=$mua_sender_restrictions
-o smtpd_recipient_restrictions=
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
Also, add the following line at the bottom of the file for Dovecot:
dovecot unix - n n - - pipe
flags=DRhu user=email:email argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}
Configuring Dovecot¶
To install Dovecot with the IMAP stack:
sudo apt-get install dovecot-common dovecot-imapd
(You can throw in dovecot-pop3d
if you want the POP3 server as well;
however, we will focus on IMAP in this tutorial.) Dovecot's configuration files
are in /etc/dovecot/conf.d/
. To configure the SSL certificates, open
10-ssl.conf
and make sure the following three settings are set to:
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.mydomain.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.mydomain.com/privkey.pem
To force SSL/TLS encryption, open 10-auth.conf
and uncomment the
following line:
disable_plaintext_auth = yes
Next, open the main configuration file 10-master.conf
and uncomment the
paragraph for Postfix in the auth
service block:
service auth {
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
user = postfix
group = postfix
mode = 0660
}
}
This will create the private/auth
path that we set up in the SASL
and Postfix will not be able to read it), or alternatively set the mode to 0666.
configuration of Postfix. (Postfix runs chrooted in /var/spool/postfix
,
group lines if they are not present (otherwise the file will be owned by root
which is why we put a relative path.) Make sure to either add the user and
Client Configuration¶
For e-mail clients, your server configuration should now be:
- Server: example.com
- User account: user@example.com (full e-mail address)
- Password: the user's Unix password
- Protocol: SMTP for sending (authentication required), IMAP for receiving
- Ports: SMTPS 587 and IMAPS 993
And that's it! You should be good to go, or, most likely and otherwise, able to debug your next configuration errors 😜 You can follow them at:
tail -f /var/log/mail.log
You may need some extra configuration for your e-mail server to survive in the wild, that is to say: defend yourself against spam, and get the proper credentials so that other e-mail providers do not treat you as a spammer. See the follow-up post on SPF and DKIM for instructions on how to do that.
Webography¶
At the time of writing this post, I learned from articles of the Debian Wiki and the Dovecot Wiki. The tutorial How to set up a simple mail server on Debian in 5 easy steps also helped. Initial details on SSL certification were provided by Switch to HTTPS Now, For Free from Eric Mill's blog (now outdated). When updating this post to Debian 9, I also found this GitHub gist most concise and useful.
Discussion ¶
You can subscribe to this Discussion's atom feed to stay tuned.
-
Timbo Neko
Posted on
This howto has aged quite well, my mail server is doing service for some years now. Apart from the listings, the explanations are really helpful! Thanks for sharing this!
Feel free to post a comment by e-mail using the form below. Your e-mail address will not be disclosed.