Setting Up Your Own Mail Server Can Be Fun!


A typical Web mail application, which would be sufficient for the needs of an individual, is woefully inadequate when it comes to system generated emails. The obvious solution to this issue is to set up your own mail server. Here’s a detailed guide on how to go about it.

Email notifications have become a common feature, especially in SaaS applications. To send out email notifications, you can use Sendmail, which is usually available on any UNIX/Linux-based server. This should suffice if the volume of mail is small. For slightly larger volumes, any of the public mail services like Google and Yahoo can be used to push out emails. In this case, however, the mail ID of the sender will be similar to If you are conscious about building your brand and would like to send out emails from your domain, you can purchase a mail service from any of the hosting providers like GoDaddy. The advantage in this case is that the sender mail ID will be one that has your domain name:

Why set up your own mail server?
The number of system generated mails from your programmes, like sign-up confirmations, password changes, etc, can hardly be predicted. A large volume of unsolicited mail from an IP to any of the public email services like Google and Yahoo is likely to get your IP blacklisted.
On the other hand, if you use a purchased email service from hosting providers, there is a limit to the volume of emails that can be sent out using their servers. I discovered that I was able to send out about 80 mails with GoDaddy, though the FAQ on its site mentioned that about 300 emails could be pushed out at a time. To send out larger volumes, I had to purchase a different plan.
If you are running a marketing or email campaign, it’s recommended that you use any of the public bulk mail services like Mail Chimp ( or Mail Gun ( These services ensure that you maintain a good reputation for your domain.
However, for transactional notifications like when you want to notify a diner that her table booking has been confirmed, the volume of emails depends on the popularity of the site. High volumes require very deep pockets if you are signing up for a third party mailing service. In such a situation, creating a fully functional SMTP, POP or IMAP server is a necessity.

Before we start setting up a mail server, let’’s take a quick look at the basic terminology that will be used, so that there’’s no ambiguity later on.
MTA: A Mail Transfer Agent or Message Transfer Agent is the piece of software that transfers messages from one computer to another using SMTP (Simple Mail Transfer Protocol). It implements both the sending and receiving components.
MDA: A Mail Delivery Agent or Message Delivery Agent is a piece of software that is responsible for the delivery of the messages or mail to a recipient’’s mailbox.

What is to be installed?
To have fully operational email capabilities, we’ll need to install the following:
Postfix: A MTA and the most popular alternative to Sendmail that was released by Wietse Venema in December 1998
Dovecot: A mail server suite that includes a MDA, an IMAP and POP3 server. It was released in 2002 by Timo Sirainen.
SpamAssassin: An email spam filtering software originally written by Justin Mason, and which is part of the Apache Foundation.
SquirrelMail: A Web mail interface originally written by Nathan and Luke Ehresman.

Setting up the Virtual Private Server (VPS)
We’’ll need a VPS and the smaller the better. A 20 GB HDD and 512 MB of memory should suffice. Digital Ocean, Rackspace and Tata Insta Compute have such offerings, though there must be other providers with similar options. Spin an instance with the bare minimum configuration using CentOS 6.x. If you prefer Ubuntu, you can spin an Ubuntu instance, but the rest of the article assumes that you have CentOS installed on your VPS.
Most Linux distributions have Sendmail running by default. Check if Sendmail is running on your VPS and remove it. We’ll install Postfix to do its job.

ps aux | grep sendmail
yum remove sendmail

Set up the fully configured domain name as the host name by executing the following command:
echo "“”" >> /etc/sysconfig/network

Alternatively, open the network file using an editor like Nano or Vi, and type in the host name, i.e., replace with your domain name.
nano /etc/sysconfig/network

Next, open the hosts file using Nano or Vi, and add a host entry for your domain. In the example below, replace the IP address and the domain with your IP address and domain:
nano /etc/hosts file

Change the time zone of your VPS by executing this command:
ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime

Next, set up your iptables to allow incoming and outgoing connections on ports 25, 110, 143, 465, 587,993 and 995. You can put these commands in a file and execute them:
iptables -F 
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP 
ip tables -A INPUT -p tcp! --syn -m state --state NEW -j DROP 
ip tables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP 
iptables -A INPUT -i lo -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 110 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 143 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 465 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 487 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 993 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 995 -j ACCEPT 
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -P INPUT DROP
iptables -L -n
iptables-save | sudo tee /etc/sysconfig/iptables
service iptables restart

We have completed setting up the VPS. We should now install the postfix MTA. Execute this command from the terminal:
yum -y install postfix

You should see some messages on the screen while it is getting installed. 

<strong>Installing SMTP authentication and creating certificates</strong>
Having installed Postfix, let’'s now install the SMTP AUTH packages, which provide a SSL channel for your SMTP server. Install the packages by executing the following command from the terminal:
yum -y install cyrus-sasl cyrus-sasl-devel cyrus-sasl-gssapi cyrus-sasl-md5 cyrus-sasl-plain

Once the SMTP AUTH packages are installed, create the directories required for storing the ssl certificates:
mkdir /etc/postfix/ssl
cd /etc/postfix/ssl/

Now generate a private key. You will be prompted to enter a pass phrase. Provide a password, write it down and keep it in a safe place.
openssl genrsa -des3 -rand /etc/hosts -out smtpd.key 1024
chmod 600 smtpd.key

The above command generates a private key using a triple DES cipher that uses pseudo-random bytes and writes it to a file <em>smtpd.key</em>.  
Next, create a certificate using the key we just created. Execute the following command in a terminal:
openssl req -new -key smtpd.key -out smtpd.csr
You should see the following output:
Enter pass phrase for smtpd.key: 

You are about to be asked to enter information that will be incorporated 
into your certificate request. 
What you are about to enter is what is called a Distinguished Name or a DN. 
There are quite a few fields but you can leave some blank 
For some fields there will be a default value, 
If you enter '.', the field will be left blank. 
Country Name (2 letter code) [XX]:IN 
State or Province Name (full name) []:Tamilnadu 
Locality Name (eg, city) [Default City]:Chennai 
Organization Name (eg, company) [Default Company Ltd]:Sastra Technologies Pvt. Ltd., 
Organizational Unit Name (eg, section) []:Netraja 
Common Name (eg, your name or your server’s hostname) [] 
Email Address []
Please enter the following ‘'extra'’ attributes to be sent with your certificate request:
A challenge password []: 
An optional company name []:
This will create a file <em>smtpd.csr</em>. Execute the following command on your terminal:
openssl x509 -req -days 365 -in smtpd.csr -signkey smtpd.key -out smtpd.crt

You should see the following output:
Signature ok 
subject=/C=IN/ST=Tamilnadu/L=Chennai/O=Sastra Technologies Pvt. Ltd.,/OU=Netraja/ 
Getting Private key 
Enter pass phrase for smtpd.key: 
This will create the certificate file smtpd.crt.

Now execute the following command:
openssl rsa -in smtpd.key -out smtpd.key.unencrypted

You should see the following output:
Enter pass phrase for smtpd.key: 
writing RSA key

This will create the unencrypted key and write a file <em>smtpd.key.unencrypted</em>. Now move the unencrypted key to the <em>smtpd.key</em> file

...…and generate the RSA key:
openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 365

You should see the following output:
Generating a 2048 bit RSA private key 
writing new private key to 'cakey.pem' 
Enter PEM pass phrase: 
Verifying - Enter PEM pass phrase: 
You are about to be asked to enter information that will be incorporated 
into your certificate request. 
What you are about to enter is what is called a Distinguished Name or a DN. 
There are quite a few fields but you can leave some blank 
For some fields there will be a default value, 
If you enter '.', the field will be left blank. 
Country Name (2 letter code) [XX]:IN 
State or Province Name (full name) []:Tamilnadu 
Locality Name (eg, city) [Default City]:Chennai 
Organization Name (eg, company) [Default Company Ltd]:Sastra Technologies Pvt. Ltd., 
Organizational Unit Name (eg, section) []:Netraja 
Common Name (eg, your name or your server's hostname) [] 
Email Address [] 

<strong>Update the DNS Zone entries</strong> 
After generating the SSL keys, set up the DNS Zone entries so that you designate the VPS for sending and receiving mail. 
Set up the MX entries for pop, imap and smtp to point to your IP address. Create an mx record that points to a CNAME record which, in turn, points to an A record that points to the mail server IP.  
Most registrars will have a Web interface that allows you to do this. The interface may differ slightly but the DNS records are specified in a standard format.

<strong>Setting up Postfix</strong> 
Open the Postfix configuration file and make the following changes:
nano /etc/postfix/

Comment the following lines:
#inet_interfaces = localhost
#mydestination = $myhostname, localhost.$mydomain, localhost
Now add these lines at the bottom of the file. Use your host and domain names. The IP addresses indicate the IPs that are allowed to connect to Postfix. At the very least, these addresses should contain, which indicates localhosts. The other addresses mentioned are that of our server's  IPs; you should substitute these with the addresses of your servers if you want the mail host to serve more than one application for sending out emails.
myhostname = 
mydomain = 
myorigin = $mydomain 
home_mailbox = mail/ 
mynetworks = 
inet_interfaces = all 
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain 
smtpd_sasl_auth_enable = yes 
smtpd_sasl_type = cyrus 
smtpd_sasl_security_options = noanonymous 
broken_sasl_auth_clients = yes 
smtpd_sasl_authenticated_header = yes 
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination 
smtpd_tls_auth_only = no 
smtp_use_tls = yes 
smtpd_use_tls = yes 
smtp_tls_note_starttls_offer = yes 
smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key 
smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt 
smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem 
smtpd_tls_received_header = yes 
smtpd_tls_session_cache_timeout = 3600s 
tls_random_source = dev:/dev/urandom 

Now open the master configuration file and enter the following lines:
nano /etc/postfix/
smtps	  inet  n	-	n	-	-	smtpd
 -o smtpd_sasl_auth_enable=yes 
 -o smtpd_tls_security_level=encrypt 
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o broken_sasl_auth_clients=yes

Ensure that you retain the two blank spaces before the ‘'-o'’ when you save the file. Postfix is a bit finicky when it reads this file and will report vague errors if this space convention is not adhered to.  Now let’s restart Postfix and sasl auth services:
service postfix start
service saslauthd start
chkconfig --level 235 postfix on
chkconfig --level 235 saslauthd on

<strong>Check SMTP connectivity</strong> 
Let us now check if Postfix is running by Telnet. From your terminal, run the following command:
telnet localhost 25

…...then type:
ehlo localhost

Your transcript will look something like what follows:
[ sridhar]# telnet localhost 25 
Trying ::1... 
Connected to localhost. 
Escape character is '^]'. 
220 ESMTP Postfix 
ehlo localhost 
250-SIZE 10240000 
250 DSN 
221 2.0.0 Bye 
Connection closed by foreign host. 

<strong>Installing and setting up Dovecot</strong> 
Dovecot is the MDA that will enable the POP and IMAP capabilities. So let's install it:
yum -y install dovecot

Open the Dovecot configuration file and make the following changes:
protocols = imap pop3
mail_location = maildir:~/mail
pop3_uidl_format = %08Xu%08Xv

Ensure that the mail_location is the same as the home_mailbox in the Postfix configuration. Restart and enable Dovecot on start up:
service dovecot start
chkconfig --level 235 dovecot on

Test the POP connectivity:

[ sridhar]# telnet localhost 110 
Trying ::1... 
Connected to localhost. 
Escape character is '^]'. 
+OK Dovecot ready. 
+OK Logging out 
Connection closed by foreign host.
The going is good and though the server is ready to receive mails, we are yet to create users. So let’'s do so now. 

<strong>Install and configure SpamAssassin</strong> 
SpamAssassin is an email spam filter that uses DNS-based fuzzy logic, Baynesian filtering and several other methods for spam detection. To install it, run the following command in your terminal:
yum install spamassassin

Open the SpamAssassin configuration file as follows:
nano /etc/mail/spamassassin/

You should see the following entries in the file:
required_hits 5 
report_safe 0 
rewrite_header Subject [SPAM] 

The <em>required_hits</em> determines the intensity of the filter. The lower the score, the higher the filter aggression. For a start-up organisation, you could set it at 5. Higher values will let more incoming mails to pass through. 
The <em>report_safe</em> parameter determines whether the incoming mail is delivered to the intended recipient after being flagged as ‘spam’ or trashed. If you want all spam to be trashed mercilessly, use a value of ‘1’. Otherwise, use ‘0’, in which case mails that are appended with a spam notice in the subject line are still sent to the recipient’s inbox. 
The rewrite header specifies the text that is appended to the subject line of any mail that is flagged as spam. In our case, we'll have [SPAM] appended to our subject line. You could also use ****S P A M**** if you wish to draw the recipient’s attention. 
Let’'s add another parameter required_score, which sets the score for all emails allowed through to your domain. A score of 0 will classify the email as legitimate, while a score of 5 will classify an email as definite SPAM. Let’s set it to 3, which will let us trap a few unsolicited mails but will also flag a few false positives.

required_score 5
SpamAssassin relies on two UNIX daemon processes to work correctly-<em>spamd</em> and <em>spamc</em>. <em>Spamd</em> waits for new email to arrive—once it receives an incoming connection it spawns the spamc daemon to read the email from the respective socket. Spamc reads the email and once it encounters an EOF, it will pass the message to spamd. Spamd will then rewrite the message based on your spam rules, e.g., it may rewrite the header with [SPAM] in the beginning and pass it back to spamc. The spamc daemon process then ends and Dovecot processes the incoming message. 
Because of the nature of these daemon processes, we'll need to create a separate group and user for spamd to integrate with Postfix:
groupadd spamd
useradd -g spamd -s /bin/false -d /var/log/spamassassin spamd
chown spamd:spamd /var/log/spamassassin

Reconfigure Postfix to use SpamAssassin scripts:
nano /etc/postfix/
smtp	  inet  n	-	n	-	-	smtpd -o content_filter=spamassassin

Right at the bottom, include the following line:
spamassassin unix - n n - - pipe flags=R user=spamd argv=/usr/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Before you start SpamAssassin, update the rules. From your terminal, execute the following command:
sa-update && /etc/init.d/spamassassin start

Restart SpamAssassin and Postfix:
/etc/init.d/postfix reload
/etc/init.d/spamassassin restart

<strong>Create users and test the configurations</strong> 
Let’'s create users who'll have the accounts to receive mail but will not be able to log in to the server. Since my user ID already exists, let me create that of my colleagues:
useradd -m amarnath.m -s /sbin/nologin
useradd -m balaji.k -s /sbin/nologin
useradd -m balamurugan.k -s /sbin/nologin
useradd -m premnath.b -s /sbin/nologin

Feel free! Add as many users as you want! You don't have to pay for each mail ID that you create. Set their passwords using the following commands:
passwd amarnath.m
passwd balaji.k
passwd balamurugan.k
passwd premnath.b

Test one of the users’' configurations in Thunderbird. You should be able to successfully set up an account. Your mail server is now ready. But like any organisation, roving programmers need a Web interface. So let's install Squirrel Mail.

<strong>Install and configure Squirrel Mail</strong> 
Squirrel Mail is a fabulous Web mail client but has a very modest user interface. It’s available from the EPEL repository (Extra Packages for Enterprise Linux). So enable the EPEL repository using <em>rpm</em>:
rpm -ivh

yum install squirrelmail

This command installs Squirrel Mail with Apache and PHP. To configure Squirrel Mail, run the following command:
perl /usr/share/squirrelmail/config/

The interface will take a bit of getting used to but it’s self-explanatory. 
Open the <em>/etc/httpd/conf.d/squirrelmail.conf</em> file and uncomment the following lines:
# RewriteCond %{HTTPS} !=on
# RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Figure 1 Configuration of squirrel mail
Figure 1 Configuration of squirrel mail
Figure 2 Squirrel mail
Figure 2 Squirrel mail

Start the Apache service and enable it on boot:

service httpd start
chkconfig --level 235 httpd on

Fire up a browser and type <em>http://serverip/webmail</em> in the URL bar (remember to replace the server IP with your server’s IP address); you will see the login screen. Log in using the user credentials you created earlier.  
Congratulations! You are now ready to roll out your mail server across your organisation. 
We have successfully installed a mail server for our SaaS application. With external email service providers, the throughput is about 80 emails per send attempt. Rolling out your own email server enables you to scale to a whopping 40,000 mails on a 512 MB RAM VPS. However, there were a few issues that we encountered. Since cloud server IP addresses are dynamically assigned, some email providers don't accept emails that originate from cloud servers. But there are ways to tell these servers that your mails are genuine, which is the subject of another article.




  1. Real nice one. Brings memories of when I started my career as a Free Software Enthusiast with mainly mail servers :) Thanks for sharing.

  2. I’m able to send and receive mails successfully. Thanks to you.
    I wanted to ask is there a way to parse the mail and forward the mail to another ID automatically if the mail contains any abusive content. Any help would be appreciated.


Please enter your comment!
Please enter your name here