how to install mail server raspberry pi

How to set up a mail server on your Raspberry Pi?

There are a lot of projects where you need to be able to send emails, but creating a mail server can also be a project in its own
So we will see the different steps of setting up a web server, be it a simple SMTP or a complete suite with a webmail

How to set up a mail server on your Raspberry Pi?
The installation of a mail server on Raspberry Pi must be done in several steps:

  • Install Postfix to send emails
  • Set up Postfix to receive emails
  • Add Dovecot for POP / IMAP management
  • Install Roundcube as webmail

We will now see each one of these steps in detail

Prerequisites

If you want to set up an SMTP server, the requirements are almost non-existent
A Raspberry Pi and an SMT server that will serve as a relay is sufficient (Gmail for example)

If you want to follow the tutorial until the end you will need:

  • A Raspberry Pi
  • A domain name (I will use domain.com in all the steps below, don’t forget to change it)
  • A static public IP address (or at least one dynamic DNS service)

Also, know that I make this tutorial on Raspbian, so it I recommend to install Raspbian first (lite will be enough) by following this tutorial
I suggest you to use SSH to follow this tutorial from your usual computer and copy/paste commands and configurations

Security warning

Creating your secure mail server is not always easy
It’s easy to miss a setup and turn your server into an open SMTP relay for the world, or get spammed over

So be sure to follow this tutorial precisely and then monitor the system logs to make sure that you are the only one doing the actions that are happening on your server
Setting up additional security features such as a firewall or fail2ban service can also be a good idea

DNS Configuration

IP Address

In the next steps, we will change our domain name DNS settings to use our IP address as the mail server

If you don’t have a static public IP address, you will need to use a free dynamic DNS service like No-IP to redirect a domain to your dynamic IP address
You’ll have to install a tool to give them regularly your current IP address, and they will redirect a domain like myserver.ddns.net to your last known IP address
Also if you don’t have a domain name, I think that you can use this alias directly

For an email server, it’s not a perfect option, because you’ll have small downtimes when your IP change, but if you’re not too serious about your emails, it’s going to be fine

DNS zone configuration

Now you need to go to your domain name registrar and change this zones to match your current IP address (or your dynamic DNS provider domain name):

  • MX
  • pop.domain.com
  • smtp.domain.com
  • imap.domain.com
  • mail.domain.com

The MX one is mandatory to receive email on your Raspberry Pi

The other ones are just easy to remember names for access to your emails

Changes may take up to 24 hours before applying
You can monitor the progress of the changes with an online tool like Network-Tools.com

Send emails with Postfix

Now let’s move on to the main things and so to the installation of Postfix

Postfix will be the base of our mail server.
It will allow us to send and receive emails corresponding to our domain name
In this step, we’ll see how to send emails

Installation

Start by installing the Postfix package:

sudo apt-get install postfix

During the installation you’ll have to choose this two configuration options:

  • The general type of mail configuration: Internet site
  • System mail name: domain.com

Now we will make two changes in the configuration that has been generated

  • Open the configuration file
    sudo nano /etc/postfix/main.cf
  • Disable IPv6 management
    • Replace
      inet_protocols = all
    • By
      inet_protocols = ipv4
  • Enter your domain name as myhostname
    myhostname= domain.com
  • If you are on a local network, most of the Internet providers don’t allow to send emails directly
    So you may need to add a relay host in your configuration
    Ask your provider for the server to use as a relay

    relayhost = smtp.yourprovider.com
  • Save and exit (CTRL+O, Enter, CTRL+X)
  • Restart Postfix
    sudo service postfix restart

At this point, the server should start properly without startup errors
If this is not the case, look to solve these problems before continuing

Testing

We’ll now make our first test by sending an email from the Raspberry Pi

Telnet

For this test, we’ll use telnet to connect to postfix

  • Install telnet
    sudo apt-get install telnet
  • Connect to the SMTP server
    telnet localhost 25
  • Enter this series of commands
    • ehlo
    • mail from: you@domain.com
    • rcpt to: user@mail.com
    • data
    • Subject: test
    • Test
    • .
    • quit
  • This commands sequence will create an email and send it to user@mail.com (external email address)

Here is the full trace:

pi@raspberrypi:~ $ telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 domain.com ESMTP Postfix (Raspbian)
ehlo domain.com
250-domain.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
mail from: me@domain.com
250 2.1.0 Ok
rcpt to: youremail@gmail.com
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
Subject: test
Test
.
250 2.0.0 Ok: queued as 44EAE1FE54
quit
221 2.0.0 Bye

Mailutils

If you are looking for a most friendly way to do this, you can install mailutils to use the mail command

  • Install mailutils
    sudo apt-get install mailutils
  • Send a test email with the mail command
    echo 'Test' | mail -s "Test mail command" you@gmail.com

 

In both cases, you can follow the email sending in this log file: /var/log/mail.log

Receive emails with Postfix

Now it’s time to edit our Postfix configuration to receive emails

Configuration

We’ll do this by using the Maildir mailboxes format
Maildir is a safe and easy way to store emails: each mailbox is a directory, and each email is a file

  • Edit the configuration file
    sudo nano /etc/postfix/main.cf
  • Add these lines at the end of the file
    home_mailbox = Maildir/
    mailbox_command =

    This configuration will tell Postfix to create a Maildir folder for each system user
    This folder will now host your new incoming emails

Now we need to create the Maildir folder template by following these steps

  • Install this packages
    sudo apt-get install dovecot-common dovecot-imapd
  • Create folders in the template directory
    sudo maildirmake.dovecot /etc/skel/Maildir
    sudo maildirmake.dovecot /etc/skel/Maildir/.Drafts
    sudo maildirmake.dovecot /etc/skel/Maildir/.Sent
    sudo maildirmake.dovecot /etc/skel/Maildir/.Spam
    sudo maildirmake.dovecot /etc/skel/Maildir/.Trash
    sudo maildirmake.dovecot /etc/skel/Maildir/.Templates

These templates will be used for the next users you will create
But for those already existing, you have to do it manually

For example, you have to run this commands for pi:

sudo cp -r /etc/skel/Maildir /home/pi/
sudo chown -R pi:pi /home/pi/Maildir
sudo chmod -R 700 /home/pi/Maildir

Testing

You can now repeat the same kind of test as before, but put the user pi in the receiver

echo "Test" | mail -s "Test" pi@domain.com

And then check that the mail has arrived in the Maildir folder

pi@raspberrypi:~ $ cat /home/pi/Maildir/new/1535959347.Vb302I3dc1bM266961.raspberrypi
Return-Path: <pi@raspberrypi>
X-Original-To: pi@domain.com
Delivered-To: pi@domain.com
Received: by webinpact.com (Postfix, from userid 1000)
        id 26B5020423; Mon,  3 Sep 2018 07:22:27 +0000 (UTC)
Subject: Test
To: <pi@domain.com>
X-Mailer: mail (GNU Mailutils 3.1.1)
Message-Id: <20180903072227.26B5020423@domain.com>
Date: Mon,  3 Sep 2018 07:22:27 +0000 (UTC)
From: pi@raspberrypi

Test

You should have only one mail in the new folder, use tab auto-completion to find it
As you can see the return path address is not correct, you have to change your hostname to fix this

sudo hostname domain.com

But we reach our goal for this step.
We receive emails sent to our domain

Secure the mail server

As I said at the beginning, there are some options to put in place to secure a minimum of the web server

  • Edit your configuration file
    nano /etc/postfix/main.cf
  • Add these lines at the end of the file
    smtpd_helo_restrictions =
            permit_mynetworks,
            permit_sasl_authenticated,
            reject_invalid_helo_hostname,
            reject_non_fqdn_helo_hostname,
            reject_unknown_helo_hostname,
            check_helo_access hash:/etc/postfix/helo_access

    This configuration will limit SMTP usage to the local network and reject people saying that they are from your domain name

  • Create the helo_access file
    sudo nano /etc/postfix/helo_access

    In this file, we need to put the list of domain name we want to block

  • Paste these lines into it
    X.X.X.X   REJECT
    domain.com   REJECT
    smtp.domain.com   REJECT
    mail.domain.com   REJECT

    Replace X.X.X.X with your public IP address

  • Restart postfix daemon
    sudo service postfix restart

Install Dovecot to allow POP and IMAP connections

We now have a functional and secure mail server
So we will move on to the next part, which is to make this mail server accessible to POP and IMAP clients via SASL authentication.

As you may have noticed, we already installed Dovecot in the previous step to create Maildir folders
The only thing left to do is to finalize the configuration

Configuration

  • Open the Dovecot configuration file
    sudo nano /etc/dovecot/dovecot.conf
  • Remove IPV6 support
    • Replace
      #listen = *, ::
    • By
      listen = *
  • Open the Dovecot mail configuration file
    sudo nano /etc/dovecot/conf.d/10-mail.conf
  • Edit the Maildir folder
    • Replace
      mail_location = mbox:~/mail:INBOX=/var/mail/%u
    • By
      mail_location = maildir:~/Maildir
  • Open the Dovecot master configuration file
    sudo nano /etc/dovecot/conf.d/10-master.conf
  • Tell Dovecot to listen for SASL authentification
    • Comment all lines from the default service auth paragraph (add # before each line)
    • Add these lines a the end of the file
      service auth {
              unix_listener /var/spool/postfix/private/auth {
                      mode = 0660
                      user = postfix
                      group = postfix
              }
      }
  • Open the Dovecot auth configuration file
    sudo nano /etc/dovecot/conf.d/10-auth.conf
  • Allow plaintext auth
    • Uncomment and edit this line
      #disable_plaintext_auth = yes
    • To become this one
      disable_plaintext_auth = no
  • Edit this line too
    auth_mechanisms = plain login
  • Edit the Postfix configuration file
    sudo nano /etc/postfix/main.cf
  • Tell Postfix to use SASL (add these lines)
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
  • Restart Dovecot and Postfix
    sudo service postfix restart
    sudo service dovecot restart

Testing

To test that SASL authentication works well, we will create a test user and try to connect to the mail server with it

User creation

Create a new user with login test and the password you want

adduser test

Get the encoded password

We need to get our password in a base64 encoded format
You can get it with this command:

printf '\0%s\0%s' '[LOGIN]' '[PASSWORD]' | openssl base64

In my case (test/password), the string displayed is AHRlc3QAcGFzc3dvcmQ=

Log in

We can now retry a connection with telnet by specifying this string for identification
The only change is that we need to use the AUTH PLAIN command to log in

pi@raspberrypi:~ $ telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 domain.com ESMTP Postfix (Raspbian)
ehlo domain.com
250-domain.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN AHRlc3QAcGFzc3dvcmQ=
235 2.7.0 Authentication successful
mail from: me@domain.com
250 2.1.0 Ok
rcpt to: youremail@gmail.com
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
Subject: test
Test
.
250 2.0.0 Ok: queued as 44EAE1FE54
quit
221 2.0.0 Bye

Enable IMAPS

Dovecot allow us to connect with IMAP (telnet localhost 143)
But we now need to enable TLS for IMAP on the port 993

  • Edit the Dovecot master configuration file
    sudo nano /etc/dovecot/conf.d/10-master.conf
  • Enable listener on the port 993
    The configuration should look like this

    service imap-login {
      inet_listener imap {
        port = 143
      } 
      inet_listener imaps {
        port = 993
        ssl = yes
      }
    }
  • Then edit the SSL configuration file
    sudo nano /etc/dovecot/conf.d/10-ssl.conf
  • Enable SSL by editing the first line of the file
    ssl = yes
  • Then uncomment the certificate locations
    ssl_cert = </etc/dovecot/dovecot.pem
    ssl_key = </etc/dovecot/private/dovecot.pem
  • You also have to uncomment the ssl_protocols options to deny SSLv3
    ssl_protocols = !SSLv3
  • Finally, restart Dovecot server
    sudo service dovecot restart

Dovecot is now responding on the port 993, but if you try to connect you will get an error:

imap-login: Fatal: Couldn't parse private ssl_key: error:0906D06C:PEM routines:PE

We need to generate our SSL certificate with these commands

cd /etc/dovecot
sudo openssl req -new -x509 -nodes -config /usr/share/dovecot/dovecot-openssl.cnf -out dovecot.pem -keyout private/dovecot.pem -days 365

You can now check that your IMAPS server is working, with this command:

openssl s_client -connect localhost:993

The login syntax is: a login [LOGIN] [PASSWORD]

The full trace should look something like this:

* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.
a login pi password
a 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 SPECIAL-USE] Logged in
b select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 3 EXISTS
* 0 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1536038369] UIDs valid
* OK [UIDNEXT 4] Predicted next UID
b OK [READ-WRITE] Select completed (0.000 + 0.000 secs).
b logout
* BYE Logging out
b OK Logout completed (0.000 + 0.000 secs).
closed

You are now able to connect to your IMAP server from any clients in the LAN
If you want to access your server from anywhere, don’t forget to open the needed ports in your router firewall

Set up Roundcube to add a webmail access

Most of the work is done, but we will push a little more and add a Webmail server to our mail server on Raspberry Pi
Roundcube is a modern free and open source webmail software

The big advantage of Roundcube compared to other webmails is that it’s available directly in the Debian and therefore Raspbian repositories.

If you started from a blank Raspbian, you would need to install a MySQL server first (MariaDB)

MySQL server

If you don’t have one yet, you need to install a MySQL server to store the Roundcube database:

sudo apt-get install mariadb-server

Then you need to follow these steps to set a root password, and create a Roundcube user:

  • Connect with root (we need sudo because only root can access)
    sudo mysql -uroot
  • Set the root password
    use mysql;
    UPDATE user SET password=PASSWORD('YourPassword'), plugin='' WHERE User='root' AND Host = 'localhost';
    FLUSH PRIVILEGES;

    Don’t forget to replace “YourPassword” with a secure password

  • Create a new user for Roundcube
    CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'password';

    Replace “password” with your chosen password

  • Create the Roundcube database
    CREATE DATABASE roundcubemail;
  • Give all privileges to the Roundcube user on the Roundcube database
    GRANT ALL PRIVILEGES ON roundcubemail.* to 'roundcube'@'localhost';
  • Quit the mysql console
    FLUSH PRIVILEGES;
    quit

Your database server is ready, move to the next step

Roundcube

To install it, enter the following command:

sudo apt-get install roundcube roundcube-plugins

This will also automatically install all other dependencies (mainly Apache, PHP and MySQL client)

Again, the installation wizard will ask you these questions about your MySQL server:

  • Imap Server: ssl://imap.domain.com:993
  • Default language: set it as you want
  • Configure database with dbconfig-common: yes
  • MySQL application password for Roundcube: your Roundcube user password
  • Database administrator password: your MySQL root password

Now edit the apache configuration for Roundcube to enable the web app

sudo nano /etc/apache2/conf-enabled/roundcube.conf

Uncomment the first line

Alias /roundcube /var/lib/roundcube

Then go to http://[RASPBERRY-IP]/roundcube to see the web interface

roundcube login screen

If you get any error, you can restart the installation wizard with this command:

sudo dpkg-reconfigure roundcube-core

You can now log in with your credentials created in the previous step, or with the account “pi”
Enjoy your webmail now, and remember that it is possible to add many plugins on RoundCube to extend its functionality

Logs and configuration file summary

So we saw how to set up a full mail server on Raspberry Pi
If you have had any errors, or want to go further, here is the summary of the file locations

Postfix

In this tutorial we are using Postfix to send and receive emails, it’s the core of the mail server

Configuration

  • /etc/postfix/main.cf: Main configuration for Postfix
  • /etc/postfix/master.cf : Processes configuration for Postfix

Log files

  • / var/log/mail.log: Here you can see all mail traces, and errors if there are

Dovecot

We installed Dovecot to manage IMAP connections with a SASL security layer

Configuration

  • /etc/dovecot/dovecot.conf: The main configuration of Dovecot
  • /etc/dovecot/conf.d/: This subfolder contains several files with each part of the configuration to know easily where’s the option that you’re looking for

Log files

  • /var/log/syslog: Dovecot doesn’t have a specific log file, it’s using the main syslog file

Apache

Apache is used in this tutorial to run Roundcube
Normally you shouldn’t need to change something unless Roundcube is not accessible at all.

Configuration

  • /etc/apache2/apache2.conf: The main configuration file for apache2
  • /etc/apache2/conf-enabled/: Here you will find the configuration for some Apache services (like Roundcube.conf)
  • /etc/apache2/sites-enabled/: Here you will find the configuration for any Apache website

Log files

  • /var/log/apache/error.log: If you get any errors with Apache, you can find them here

Roundcube

And finally, we installed Roundcube to add webmail to our mail server

Configuration

  • /etc/roundcube/config.inc.php: Here is the main configuration file for Roundcube

Log files

  • /var/log/roundcube/errors: If you get some issue with Roundcube, you’ll find the errors in this file

Conclusion

And here we are at the end of this tutorial
You have learned to set up a complete mail server with:

  • Postfix for transport
  • Dovecot for secure authentication
  • Roundcube for web access to your emails

As you may have noticed, it’s not a simple thing to set up, there’s still a lot of configuration options and it can be a lot of work to put that in place at home

I think in most cases, the first part with Postfix is the one that will interest you
You are going to be able to send emails from your different projects, but not necessarily to set up all the other steps

In any case if you really need to install everything you know how to do

Leave a Comment