In many cases it can be beneficial to run an own mail server. Although it takes a bit of effort to set up and keep it running securely, the option to store a large amount of mails in a secure location can be very interesting. This also convinced me to set up my own mail server. In the following, I will cover most of the important tools and knowledge required to set up your own mail server. And the best thing about this: You don’t need much power, a Raspberry Pi can easily handle a small private mail server!
2015-04-23: Original article 2015-05-21: Updated with countermeasures against Logjam vulnerability and links to Mozilla Cipher Suites
I am running the server as smart host, meaning that I collect my mails from another server and also use that server to send out mails. While this means that this intermediate server has access to all mails passing through it, I do not have to deal with direct connections of other mail servers. This is a personal decision, but as emails generally anyway pass unencrypted through the net, any server can read it. I find that acceptable. For secure emails, one should anyway use encryption. This setup also requires an external server, which could be something like Google, or a rented server. I am using the latter, it came with my domain. If you use other servers, such as Google, note that emails don’t always get deleted when fetching them automatically.
Mozilla Cipher Suites
Up-to-date information on secure cipher suite settings are available from Mozilla. You might want to use the modern compatibility suites and fall back to intermediate, if you experience compatibility issues.
I will try to keep this article as up-to-date as possible.
I am torn about writing a full guide, but there is a guide just too good to ignore it and I used it as a basis for my setup also. It was written by Sam Hobbs and is available here. The blog of Sam Hobbs is generally a recommended read, also beyond the mail server article! I will refer to the post of Sam Hobbs to shorten things here and will explain some additional details I required. I suggest you follow his tutorial to set up a mail server, at least parts 1-3. The settings here can be added afterwards.
You will need a minimum of 3 tools to set up your own mail server as a smart host.
- Postfix - a mail transfer agent and the core of your server
- Dovecot - the access point for your client
- Fetchmail - this fetches your mails from the external server
The following items are optional, but I would recommend the use of them:
- Roundcube - a web interface for your new mail server
- Fail2ban - a small script to check for failed login attempts and automatic blocking of IPs
You might also want to use SpamAssassin and Sieve to automatically sort out your spam. This is also explained on the website of Sam Hobbs.
The setup process of Postfix is described perfectly fine in Sam Hobbs’ blog. Follow his tutorial and you will have a running Postfix setup. As we are using a smart host setup, we do not require the incoming SMTP ports for other servers. Delivery will be taken care of by Fetchmail. So for increased security, make sure to disable unprotected login and only allow port 993 for IMAP. Make sure to disable the protocols and cipher suites that have proven to be insecure. For this, add the following line to /etc/postfix/main.cf:
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3 smtp_tls_mandatory_ciphers = high smtpd_tls_mandatory_ciphers=high tls_high_cipherlist=EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
Update 2015-05-21: For the Logjam vulnerability, you should additionally add
smtpd_tls_mandatory_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CDC3-SHA, KRB5-DE5, CBC3-SHA
as well as a 2048-Bit Diffie-Hellman group. Details can be found here
As we are setting up a smart host and not handing emails out directly to the target mail server, but instead to our own mail server on the internet, who takes care of the distribution, we will need to let Postfix know to do exactly this. For this, add the following lines to your /etc/postfix/main.cf:
relayhost=yourdomain.com smtp_sasl_auth_enable=yes smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd smtp_sasl_security_options=noplaintext, noanonymous
The file /etc/postfix/sasl_passwd contains the access to your server, e.g.:
Note that the user entered here needs to be able to send mails. On most mail servers a single user is sufficient, even if you have multiple mail accounts, as it is often sufficient to have a valid SMTP access account to send mails.
Similarly to the Postfix setup, you can also follow the Dovecot setup in Sam Hobbs’ blog. Make sure to disable unprotected login here also. And make sure to open port 465 for SMTP client connections.
Also for Dovecot, you also want to disable obsolete protocols and cipher suites. To do so, add the following lines to your /etc/dovecot/conf.d/10-ssl.conf:
ssl_protocols = !SSLv2 !SSLv3 ssl_cipher_list = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" ssl_prefer_server_ciphers = yes
Update 2015-05-21: To address Logjam vulnerability, add a 2048-Bit Diffie-Hellman group. Details can be found here
This of course assumes that you already have your certificates set up correctly, I will add an explanation for this here soon also. Hint: Chain SSL certificates via
cat /etc/ssl/server.pem /etc/ssl/cacert.pem > /etc/ssl/cert_chain.pem
and add them to /etc/dovecot/conf.d/10-ssl.conf:
ssl_cert = </etc/ssl/cert_chain.pem ssl_key = </etc/ssl/priv_key.key
To set up Fetchmail, install it via
sudo apt-get install fetchmail
Fetchmail takes care of fetching your mails via POP3 and delivers it to your local mailboxes. To do so, you will need to configure all your mail accounts in /etc/fetchmailrc, for example:
poll pop.gmail.com protocol pop3 port 995 user firstname.lastname@example.org password pw ssl flush forcecr mda "/usr/lib/dovecot/dovecot-lda -d local_user -m INBOX"
for email@example.com with password pw for the local user local_user.
While it is not ideal to enter all your mail accounts here and keep this file updated whenever a password changed, I find the effort reasonable for small private servers.
Make sure your /etc/fetchmailrc has the correct rights
sudo chmod 600 /etc/fetchmailrc
and start fetchmail automatically at boot by adding it to /etc/rc.local:
fetchmail -f /etc/fetchmailrc &
While Sam Hobbs prefers to use SquirellMail, I prefer a more advanced webmail client. After testing a few solutions, I decided to go for Roundcube.
You can install Roundcube as described here
Make sure your settings are correct in /var/lib/roundcube/config/config.inc.php. As you are not running your server directly, you might want to use a different sender address, than the default firstname.lastname@example.org. This can be configured here, by setting:
Hint: This only takes action on the first login with every username!
Also here, you want to disallow obsolete protocols. For this, edit your Apache VirtualHost config for Roundcube and add:
SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" SSLHonorCipherOrder on
This of course assumes that you already have your server set up for SSL connections with proper certificates, etc. I will add a description how to do that here also soon. Update 2015-05-21: To address Logjam vulnerability, add a 2048-Bit Diffie-Hellman group. Details can be found here
SSLEngine on SSLCertificateKeyFile /etc/ssl/priv_key.key SSLCertificateFile /etc/ssl/ssl.crt SSLCertificateChainFile /etc/ssl/ca.pem
You can check your setup with Qualys SSL Labs.
Fail2ban is a less commonly known tool, but rather simple and effective. It checks the logs of different applications and in case failed login attempts are logged, the IPs for these attempts are blocked.
You might want to ignore your local networks. For this, add the following to your /etc/fail2ban/jail.conf, for example:
ignoreip = 127.0.0.1/8 192.168.0.0/24
If you already set up fail2ban, you may as well activate it for ssh as well. This is already prepared in /etc/fail2ban/jail.conf, simply set enabled=true:
[ssh] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 6
Activate fail2ban for Apache by activating the prepared filters:
[apache] enabled = true port = http,https filter = apache-auth logpath = /var/log/apache*/*error.log maxretry = 6 [apache-noscript] enabled = true port = http,https filter = apache-noscript logpath = /var/log/apache*/*error.log maxretry = 6 [apache-overflows] enabled = true port = http,https filter = apache-overflows logpath = /var/log/apache*/*error.log maxretry = 2
The same for Postfix:
[postfix] enabled = true port = smtp,ssmtp filter = postfix logpath = /var/log/mail.log
[sasl] enabled = true port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s filter = sasl # You might consider monitoring /var/log/mail.warn instead if you are # running postfix since it would provide the same log lines at the # "warn" level but overall at the smaller filesize. logpath = /var/log/mail.log [dovecot] enabled = true port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s filter = dovecot logpath = /var/log/mail.log
You might want to backup your mails, e.g. with rsync. I will write a separate article about that. Your mails are stored in your user folders, so e.g. /home/local_user/Maildir
While this tutorial is relatively long, the setup is not too hard. I can only recommend to run your own mail server. But make sure your mails are backup up properly, in case the SD card in your Pi fails.
Security is an issue, of course, as soon as you open your mail server up to the outside world. Also, keeping the server secure is an ongoing process. I try to keep this post updated with the newest security settings. Please let me know in the comments section below, should I lag behind with that.