How to set up your own mail server (Postfix + Dovecot + SASL + MySQL)
A perfect case (except one detail — I had problems with SATA cable I bought, it is a straight version, but a right angle one is a better choice)! After finishing the case I assembled my future server and powered it up. Several tests with HDD showed that there are problems with power supply — not enough power. I changed several of them until I found a decent one. It was high time for setting up my server. First thing to accomplish — incoming/outgoing mail server. There was struggles… Many of them! This is why I am writing this post — for myself as a reference and as a guide for others. Let’s begin!
As a base system I chose Bananian. It is based on Debian Wheezy and represents just the base system and a series of custom tweaks. While I was playing with different software I was forced to upgrade the system to Jessie. It went very well and I haven’t encountered any problems. This is my current /etc/apt/sources.list file: http://pastebin.com/pUZ6tJwh . Pay attention to the second part — it points to the mirror situated in Moldova (giving me the speed at the level of a LAN). Change it accordingly! When done issue this commands:
It will take time, be patient! After finishing issue a reboot command. Now we have a shiny Debian Jessie running on our Banana Pi!
You may think it’s time to start installing software… But how about the domain name (name of your site)? A good place to take your free domain is DotTK . Just insert your name and check its availability. Free (and not a special one)? OK, register it (point it to your public IP)! Log in to your DotTK account (upper right corner), go to DOMAINS, choose My Domains, press Manage Domain and press Manage Freenom DNS. You have by default 2 records. For mail we need at least 2 more. Lets suppose we registered tritoniada.tk. For mail we will create a new A record — mail (you can change to whatever you want, but better use something suggestive). Point it again to your public IP. Press Save Changes and lets proceed to second record. This time we again write mail but point it to tritoniada.tk. The type must be changed to MX and insert priority 10! Save it and we are done.
Tricks: If you want to be accessible not only through email@example.com but also firstname.lastname@example.org you have to add a new MX record (with a priority different than 10) which will point to mail.tritoniada.tk. Also you can register more domains (ex. cassiniada.tk) and use email@example.com using the same trick with MX records pointing to the right domain (mail.tritoniada.tk).
Now we need to change the identity of the system:
And change it to mail (or whatever else you chose).
nano /etc/hosts #http://pastebin.com/62N4WR0c . Don't forget to change the domain!
Reboot your system!
Finally lets install necessary software for our database:
apt-get install mysql-client mysql-server
Don’t leave empty password when asked! Choose something strong enough to be calm in the future. Now let’s secure our database:
Give your database password and answer yes to all questions (except the one for changing the current password). Now it’s time for next software portion:
apt-get install postfix postfix-mysql
You will get question like this one:
Ok, more software:
apt-get install dovecot-common dovecot-imapd dovecot-mysql dovecot-sieve libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl telnet bsd-mailx
Here we start to prepare our database. Issue mysql -u root -p and you will get to MySQL command prompt. Lets’ go (don’t forget to change mail_admin and mail_admin_password):
CREATE DATABASE mail;
GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost' IDENTIFIED BY 'mail_admin_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost.localdomain' IDENTIFIED BY 'mail_admin_password';
We created the database for our mail system. Now we need to create tables in our database. First one will be the table containing domains to serve:
CREATE TABLE domains (domain varchar(50) NOT NULL, PRIMARY KEY(domain));
Table for forwarding (from one e-mail account to another):
CREATE TABLE forwardings (source varchar(80) NOT NULL, destination TEXT NOT NULL, PRIMARY KEY(source));
Table for e-mail accounts:
CREATE TABLE users (email varchar(80) NOT NULL, password varchar(20) NOT NULL, PRIMARY KEY(email));
Time to configure Postfix to work with MySQL:
nano /etc/postfix/mysqlconf/virtual_domains.cf #http://pastebin.com/FemAFwVc . Don't forget to change login data!
nano /etc/postfix/mysqlconf/virtual_forwardings.cf #http://pastebin.com/AHrSBbgH . Don't forget to change login data!
nano /etc/postfix/mysqlconf/virtual_mailboxes.cf #http://pastebin.com/ktUUJa5q . Don't forget to change login data!
nano /etc/postfix/mysqlconf/virtual_email2email.cf #http://pastebin.com/1FnG9kaz . Don't forget to change login data!
Lets protect our files:
chmod o= /etc/postfix/mysqlconf/virtual_*.cf
chgrp postfix /etc/postfix/mysqlconf/virtual_*.cf
We need a system user for dealing with mail:
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /home/vmail -m
Time for configuring main settings of the Postfix:
cp /usr/lib/postfix/main.cf /etc/postfix/main.cf
nano /etc/postfix/main.cf #http://pastebin.com/LNxvuF1f . Don't forget to change domain!
Lets secure out Postfix server using SSL:
openssl req -new -outform PEM -out /etc/postfix/certificate/smtpd.pem -newkey rsa:2048 -nodes -keyout /etc/postfix/certificate/smtpd.key -keyform PEM -days 365 -x509
Answers are up to you, there are no specific rules. Private key must be protected:
chmod o= /etc/postfix/certificate/smtpd.key
Activate SSL for Postfix:
mkdir -p /var/spool/postfix/var/run/saslauthd
nano /etc/default/saslauthd #http://pastebin.com/a4H68WHs
nano /etc/pam.d/smtp #http://pastebin.com/UhWbr4FN . Don't forget to change login data!
nano /etc/postfix/sasl/smtpd.conf #http://pastebin.com/DpmiG0Rb . Don't forget to change login data!
chmod o= /etc/pam.d/smtp
chmod o= /etc/postfix/sasl/smtpd.conf
Finalizing configuration for Postfix:
adduser postfix sasl
No errors messages should appear!
mv /etc/dovecot/dovecot.conf /etc/postfix/master.cf $HOME #we won't remove them - just move to home folder
nano /etc/postfix/master.cf #http://pastebin.com/hikFkpq2
nano /etc/dovecot/dovecot.conf #http://pastebin.com/GxGU1SZZ . Don't forget to change domain!
nano /etc/dovecot/dovecot-sql.conf #http://pastebin.com/cFBGC6pf . Don't forget to change login data!
openssl req -new -outform PEM -out /etc/dovecot/certificate/dovecot.pem -newkey rsa:2048 -nodes -keyout /etc/dovecot/certificate/dovecot.key -keyform PEM -days 365 -x509
chmod o= /etc/dovecot/certificate/dovecot.key
chgrp vmail /etc/dovecot/dovecot.conf
chmod g+r /etc/dovecot/dovecot.conf
Finishing with Dovecot:
nano /etc/aliases #http://pastebin.com/u8VFtaKW . Don't forget to change domain!
It’s time to check our installation… Issue:
telnet localhost 25
You must receive something like this:
220 mail.triton.tk ESMTP Postfix (Debian/GNU)
If you received it — we can continue:
You will receive something like this:
Presence of 250-STARTTLS means our settings are right. To exit issue quit .
Now we need to get back to MySQL command prompt:
mysql -u root -p
INSERT INTO domains (domain) VALUES ('mail.tritoniada.tk');
Optionally you can issue (explanation I gave in the Tricks):
INSERT INTO domains (domain) VALUES ('tritoniada.tk');
Now we need to create our first user:
INSERT INTO users (email, password) VALUES ('firstname.lastname@example.org', ENCRYPT('password'));
Don’t forget to change the password (and user name, if you wish)!
Lets test our mail system:
Enter the subject, press Enter, enter text, press Enter, press Ctrl+D, just press Enter when you will see CC. Done! Lets check if everything went fine:
And search for something like this:
Jan 4 19:00:42 mail postfix/smtpd: connect from localhost.domain[127.0.0.1]
Jan 4 19:01:02 mail postfix/smtpd: disconnect from localhost.domain[127.0.0.1]
Jan 4 19:20:36 mail postfix/pickup: 9F03420002: uid=0 from=
Jan 4 19:20:36 mail postfix/cleanup: 9F03420002: message-id=<20150104172036.9F03420002@mail.tritoniada.tk>
Jan 4 19:20:36 mail postfix/qmgr: 9F03420002: from=<email@example.com>, size=309, nrcpt=1 (queue active)
Jan 4 19:20:37 mail postfix/pipe: 9F03420002: to=<firstname.lastname@example.org>, relay=dovecot, delay=0.55, delays=0.25/0.03/0/0.27, dsn=2.0.0, status=sent (delivered via dovecot service)
Jan 4 19:20:37 mail postfix/qmgr: 9F03420002: removed
Yes, found? Alright, lets check Dovecot:
And look for:
2015-01-04 19:20:37 lda(email@example.com): Info: msgid=<20150104172036.9F03420002@mail.tritoniada.tk>: saved mail to INBOX
Found? That’s cool, mail system is ready for production use!
Note: if you are behind a router don’t forget to open ports 25, 465 and 993 (for IMAP usage. For POP3 you also need 143)!
We created a table for forwarding… What we can use it for? A good example is forwarding mail from firstname.lastname@example.org to inbox of email@example.com, so we will receive administrative mails in our inbox. Lets do it:
mysql -u root -p
INSERT INTO forwardings (source, destination) VALUES ('firstname.lastname@example.org, 'email@example.com');
In the next posts I will explain you how to connect an Android system to our fresh new mail server! Also I will describe how to deploy a web interface (and much more) for our server. If you have problems during the process / found mistakes in the instruction above just write in the comments and I will try to get to you as soon as possible!