Background
A few days back, I felt this need to have my own mail server setup on my VPS so that I can send and receive emails from my own email account (@AskTaimoor.com). One option I had was to setup CPanel on my VPS but it had its own issues. CPanel is costly and it comes with lots and lots of additional features. Its best for web hosting providers so its none of my use. If you are planning to setup lots of email accounts on lots of domains, you should consider buying CPanel or other commercial products. My requirement was just to setup a few email accounts on a few domains that I personally manage. Also, I always prefer Open Source solutions because of their security and community support.
I followed tutorials on many websites but most of them were outdated and so lead to errors and other issues. After spending hours, I found this one tutorial that was much recent as compared to others but lengthy as hell. Following the steps provided there, I was able to send and receive email from a nice and simple to use web interface. Here I am writing those steps without unnecessary discussion about each and every step, the problems I faced and how I managed to fix those problems.
Limitations
There are a few limitations of this setup that I should point out before I start:
- Account Management
You cannot create, delete or modify email accounts directly from the final interface you will get. All the mail accounts map to local user accounts on the underlying Linux system. - Password Change
Passwords of accounts cannot be changed for the same reason. It has to be manually changed from console or using some postfix plugins. - Non-Fancy Interface
The web interface you will get is not stylish yet pretty simple and straight forward. Don’t expect a fancy looking user interface like Hotmail or Gmail. - Security
Although we will be running everything with limited permissions yet there are some security problems with this setup e.g; MITM attacks.
If you are OK with these limitations you can go ahead otherwise go for alternate solutions that I have mentioned above.
Prerequisites
- Basic Linux Knowledge
If you don’t know basic Linux terminologies or the basic commands used in Linux you might feel lost. If that’s the case, seek help from a Linux pro. - Static IP
Most VPS and dedicated server providers allot Static IPs. In case you don’t have one or you are setting up on your home server, this simply wont work for you. - SSH Access
You must have SSH access to your server using PuTTy or other means. This is a must so that so can run commands on your server. - root Access
This tutorial assumes that you are the administrator of this server. So you must have root access on your server in order to install anything at all.
Installation Steps
Before you start, make sure you have logged in to SSH and changed to root.
- Hostname
Your server’s hostname or FQDN should be the same as your mail address domain name. If you are going for [email protected], your hostname should be mydomain.com.
To know your current hostname, typehostname
in SSH.
If its not correctly set, change it by enteringhostname mydomain.com
- hosts File
Entervi /etc/hosts
Append this at the file’s end (if its not there already):
w.x.y.z mydomain.com mydomain www.mydomain.com
- Reverse DNS
Your servers’s Public IP address should point to your FQDN. This is not set by default. It has to be configured from your server’s control panel usually or you will need to contact your host provider. Look for rDNS or Reverse DNS or PTR Records or Network Settings in your Server Control Panel.
Once configured, run the commandhost w.x.y.z
, where w.x.y.z is your server’s public IP address and the result should be:
z.y.w.x.in-addr.arpa domain name pointer mydomain.com.
- Setup MX Domain Records
Add these records in your DNS manually or from your domain control panel:
mail A w.x.y.z
mydomain.com. MX 10 mail.mydomain.com.
Don’t forget your to restart your DNS server if you have entered the records manually. - EPEL Repository
Some components of this setup are not present in default repository. To fix that, we have to add latest EPEL Repository by typing this:
# make sure to add the proper repo version for your system
wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm
- Disable SELinux
To avoid mysterious errors, I suggest turning of SELinux temporarily. Enter this command to do it:
setenforce 0
- Setup Mail Accounts
As pointed out above, all mail accounts point to local Linux user accounts. That means we will need to setup users on our server:
# for setting up [email protected]
useradd contact
passwd contact
- Setup Postfix
Postfix is the backbone of this whole setup. Hence it must be installed and configured properly before going any further.
# to make sure everything is up-to-date.
yum updateyum install postfix -y
# remove sendmail as it conflicts with postfix
yum remove sendmail -y# use your favorite text editor. mine is vi
vi /etc/postfix/master.cf# find this line, un-comment it and change it to look like this:
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_wrappermode=no
-o smtpd_tls_security_level = encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING# to tell postfix about your hostname
vi /etc/postfix/main.cf# find these lines, un-comment them and change them to look like below:
myhostname = mail.mydomain.com
mydomain = mydomain.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = localhost, 127.0.0.0/8, w.x.y.z
home_mailbox = Maildir/# to make sure postfix runs on startup
chkconfig postfix on# restart postfix
service postfix restart
If you see any errors on starting postfix, that means you have missed something. For error details, enter this command:
tail -f /var/log/maillog
Once you are running postfix without any errors, run this command to send a test email to your other email:
mail my_email@my_isp.com
Press Ctrl+D to send the mail.
Now open your mail and check the Inbox or Junk/Spam folder to confirm that your test email has arrived. - Setup Dovecot
yum install dovecot -y
vi /etc/dovecot/dovecot.conf
# find this line, un-comment it and change it to look like this:
protocols = imap pop3 lmtpvi /etc/dovecot/conf.d/10-mail.conf
# find this line, un-comment it and change it to look like this:
mail_location = maildir:~/Maildirvi /etc/dovecot/conf.d/10-auth.conf
# find these lines, un-comment them and change them to look like below:
disable_plaintext_auth = yes
auth_mechanisms = plain loginvi /etc/dovecot/conf.d/10-master.conf
# find these lines, un-comment them and change them to look like below:
user = postfix
group = postfix# run dovecot on startup
chkconfig dovecot onservice dovecot start
- Setup SquirrelMail
# run squirrelmail wizard
cd /usr/share/squirrelmail/config/
./conf.pl# enter 1 to setup your organization details
# again enter 1 to edit the organization details
# enter all your details and press S to save them and finally press R to return to main menu# enter 2 to setup mail server details
# again enter 1 to set your domain name (mydomain.com)
# enter 3 and then enter 2 to change from Sendmail to SMTP# finally press S followed by Q to save and exit the squirrelmail wizard
- Setup Apache
Apache is installed on most servers by default. If not, install it by typing:
yum install apache -y
Once Apache is properly installed, configure it to serve SquirrelMail front-end:
vi /etc/httpd/conf/httpd.conf# add the below lines at the end of line:
Alias /webmail /usr/share/squirrelmail
Options Indexes FollowSymLinks
RewriteEngine On
AllowOverride All
DirectoryIndex index.php
Order allow,deny
Allow from all
# restart apache server
service httpd restart
Open http://w.x.y.z/webmail in your browser and you will be greeted by SquirrelMail login page like this:
Login with the mail account you previously created.
If you have reached this point without any errors, pat your self as you have completed 60% of the whole setup. - Setup Multiple Accounts
Postfix allows us to send and receive emails using different email addresses on different domains using a single Linux user account.
In order to make it work, enter the following commands:
vi /etc/postfix/main.cf# find these lines, un-comment them and change them to look like below:
virtual_alias_domains = mydomain.com mypersonaldomain.net myofficaldomain.org
virtual_alias_maps = hash:/etc/postfix/virtualvi /etc/postfix/virtual
# add as many accounts you want at the end of file in this format:
[email protected] contact
[email protected] contact
[email protected] contact
[email protected] contact
[email protected] contact# every time you edit the virtual file, you must run these commands:
postmap /etc/postfix/virtual
postfix reload
The emails received on the above email accounts will land in the inbox ofcontact
user account. You can setup as many accounts as you wish by mapping them to the local Linux user accounts. But setting up too many accounts is not recommended. - Setup SPF Records
SPF records are used by most Email servers to prevent SPAM. If you don’t have these records chances are that all your sent emails will land in recipient’s junk/spam folder.
Add this record in your DNS manually or from your domain control panel:
@ TXT "v=spf1 mx a ip4:w.x.y.z"
Don’t forget your to restart your DNS server if you have entered the records manually. - Setup DKIM Keys
Just like SPF, DKIM is a mechanism designed to fight email SPAM. Failing to setup these will cause your emails to be caught up by SPAM filters or never reaching the recipients at all. Perform the following to prevent this:
yum install opendkim -yvi /etc/opendkim.conf
# append the following lines at the file's end:
AutoRestart Yes
AutoRestartRate 10/1h
UMask 002
Syslog yes
SyslogSuccess Yes
LogWhy YesCanonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTableMode sv
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256UserID opendkim:opendkim
Socket inet:12301@localhost
vi /etc/default/opendkim
# find this line, un-comment it and change it to look like this:
SOCKET="inet:12301@localhost"# configure postfix to use DKIM as mail filter
vi /etc/postfix/main.cf# find these lines, un-comment them and change them to look like below:
milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301# setup dkim directory structure
mkdir /etc/opendkim
mkdir /etc/opendkim/keys# specify which hosts should be trusted
vi /etc/opendkim/TrustedHosts# append the follow lines at the end of the file:
w.x.y.z
*.mydomain.com# create a key table
vi /etc/opendkim/KeyTable# append this line at the end of the file:
mail._domainkey.mydomain.com mydomain.com:mail:/etc/opendkim/keys/mydomain.com/mail.private# create signing table
vi /etc/opendkim/SigningTable# append this line at the end of the file:
*@mydomain.com mail._domainkey.mydomain.com# setup public and private keys
cd /etc/opendkim/keys
mkdir mydomain.com
cd mydomain.com
opendkim-genkey -s mail -d mydomain.com
chown opendkim:opendkim mail.private# open mail.txt and copy the domain record
vi mail.txt# the domain record should look like this (do not use this its just a sample):
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5e4Yg/0fTwxDZlDB
8MThaqhifXvrniu6AQfBd+11zucb7ZMtEGHrutlUXC4cHCe4Xj5NoU6
DHQOJTd6DcOt3R88Ik40mpg98EWozAL3RGTb6FifGJEg7s7WFB0x2oE
hT/yFTwHVMOCDOnQgGvr3iftmzKGy7kMyFbVKGWDHtx9QIDAQAB"# restart postfix and opendkim to update the latest changes
service postfix restart
service opendkim restart
Add the above copied record in your DNS manually or from your domain control panel:
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5e4Yg/0fTwxDZlDB
8MThaqhifXvrniu6AQfBd+11zucb7ZMtEGHrutlUXC4cHCe4Xj5NoU6
DHQOJTd6DcOt3R88Ik40mpg98EWozAL3RGTb6FifGJEg7s7WFB0x2oE
hT/yFTwHVMOCDOnQgGvr3iftmzKGy7kMyFbVKGWDHtx9QIDAQAB"
Don’t forget your to restart your DNS server if you have entered the records manually.
Testing
Once all the above steps are completed, its time to test your newly born mail server.
Verify that all your DNS records are setup properly by typing this command:
nslookup -type=ANY mydomain.com
The result should look like below:
The MX, SPF and DKIM records must be present in the results.
To make sure your email server meets the standards and follows the best practices, send an empty email to
[email protected]
from your SquirrelMail.Open http://www.allaboutspam.com/email-server-test-report/index.php in your browser and enter the email from which you sent the empty email ([email protected]) and press enter.
All the results should be shown in green except the BATV and Greylist check. Like for SPF test, you should see this:
Within 10 to 15 minutes, a mail will arrive in your SquirrelMail inbox containing a link ensuring your email server is using the best practices.
Try sending email from your SquirrelMail to the most used email services to test email delivery.
Do not enter words like “test email” “mail testing” in the subject field or email body. Doing this increases the chances of your emails landing in SPAM folder.
Enter something creative that doesn’t look like SPAM and your emails will land safely in Gmail’s and Yahoo!’s inbox!
However in case of Hotmail this isn’t true. Hotmail’s SmartFilter uses IP reputation in addition to other methods to identify potential SPAM. It takes take for SmartFilter before it whitelist your IP. Until then your associates will have to check their Junk folder to find your email.
Other than that, it works fine with most email services providers worldwide.
Following the above steps, if something doesn’t work, you will need to check the following to find the culprit:
For mail server related problems:
tail -f /var/log/maillog
For DNS server related problems:
tail -f /var/named/log/queries.log
For user authentication related problems:
tail -f /var/log/secure
For other problems:
tail -f /var/log/messages
In case you are having problems following this tutorial, just write in comments and we will sort out the problem!