Home / guides   Print version

Mail server setup on CentOS

This tutorial is written with the following version:

  • CentOS 5.5 (Kernel 2.6.18-194)
  • Sendmail 8.13.8 is the actual mail daemon that accepts the mail and saves the emails in the users mail box.
  • Dovecot is the pop3/imap server that allows users to download their email to their PC.
  • procmail 3.22-17.1 is a mail delivery agent (MDA) capable of sorting incoming mail into various directories and filtering out spam messages.
  • SpamAssassin 3.2.5-1 is the spam-filter.



On RedHat based distribution, like CentOS, Sendmail is usually installed by default. If it isn't you can install it by:

yum install sendmail

The configuring part is a little more difficult.
Luckily, we don't have to edit the sendmail.cf file directly, it's a nightmare. What we do is edit the sendmail.mc file which holds a list of macro commands, and then run it through the m4 macro interpreter to generate the sendmail.cf. All files are located in /etc/mail, although some versions put the sendmail.cf in just /etc. If you can't seem to find them, use the find command to locate them (find / -name sendmail.mc). Here I will detail some basic changes that I make to the sendmail.mc file, and why.

You can comment/uncomment a line by adding/removing dnl in front of the line.

The default setting are usually good.

One important thing is to set the greeting when someone connects to the mail server. The default gives out the version and other info, which could be beneficial to a potential attacker.

define(`confSMTP_LOGIN_MSG', `$j Sendmail; $b')dnl
A better greeting is this one:
define(`confSMTP_LOGIN_MSG', `$j server ready at $b')dnl

I comment out (add dnl to the front of) this line:

dnl DAEMON_OPTIONS(`Port=smtp,Addr=, Name=MTA')dnl
Which by default limits smtp to the loopback, and add this one in it's place to allow the server to accept connections from outside, otherwise your domain doesn't get emails. So in the end it looks like this:
DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl

To cut down on spam, you can comment out (add dnl to the front of) the following line:

dnl FEATURE(`accept_unresolvable_domains')dnl
Which basically says that if the domain of the sender (whatever is to the right of the @) does not resolve to an IP properly, like you see with fake domains from spammers, don't accept it!

Create the sendmail.cf file

From the /etc/mail directory, you can backup the current and then create the new sendmail.cf like this:
cd /etc/mail
cp sendmail.cf sendmail.cf_`date +%m%d%y_%H%M%S`
m4 sendmail.mc > sendmail.cf

Configure the /etc/mail/local-host-names file

In /etc/mail, there is a file called local-host-names. This file tells sendmail what domains it is to accept mail for, so basically any hostname that is going to be receiving mail needs to be in here.


Configure the /etc/mail/virtusertable file

The virtusertable allows you to specify mail users and how they are going to get mail, including wild cards. Let's say you create a user account named fred, and you want it to receive mail for flintstones.com, you would put this in the virtusertable:
fred@flintstones.com fred
What this is, is an email address to user map. You can even send it to another email address rather than a local user, if you want to setup a mail forward at the server level.

One thing that I do, is to add a catch all in case someone spells a username wrong, you can also set the catch all to dump to /dev/null, for example, after all legitimate users. I add this to catch any other usernames coming in with my domain and send to a user I created just to catch it named deadletter:

@yourdomain.com deadletter

Once you have the virtusertable setup to your liking, we must build the database or hash of the file. The hash is actually what is read by sendmail, use this command to build the hash:

makemap hash virtusertable < virtusertable
This should make a file called virtusertable.db, alongside your text file.

Don't forget to create a local user for every (real) user in the virtusertable. This is need to store the emails and to be able to download them.

useradd user1
passwd user1

Configure the access file

This is not necessary to receive mail, only to allow other users to relay (send) mail through your server.
I recommend to leave it to the default (Only allow the server itself to send mail.) The file called access, and it's function is to control who can relay mail. In it's simplest form, you add the network that is allowed to send mail and tell it that it can relay. For example, in our 10.10.10.x network, we would add:

10.10.10 RELAY
This will allow the whole 10.10.10.x network to relay mail through your server. You can also REJECT the same way, and you can specify a single IP, subnet or even hostnames. Just use REJECT instead of RELAY. Just like the virtusertable, when you are done, you have to create the hash:
makemap hash access < access


You guessed it, this allows to create aliases for local accounts. It is mostly used to forward mails system-accounts to a real user-account. Edit the file

nano /etc/aliases
Add something like this
# Person who should get root's mail
root:           john
# User aliases
jsmith:         john
j.smith:        john
Don't forget to rebuild the aliases database:

Restart and test!

Restart the sendmail daemon like so:

/etc/init.d/sendmail restart

And the test it.

telnet smtp.mailserver.com 25
helo me
mail from:myaddress@domain.com
rcpt to:youraddress@domain.com
This is a test



Dovecot is a very popular POP3/IMAP server. The main difference between POP3 and IMAP is while accessing the your email with outlook if you use POP3 the mail is downloaded to your computer and deleted from the server. With IMAP the mail is retained in the server. IF any problem occurs while downloading the emails are lost with POP3.

To install Dovecot:

yum install dovecot

Open the dovecot config file /etc/dovecot.conf and adapt to your liking.

I only going to setup a secure POP3 server (pop3s).
So I adapt the line:

protocols = imap imaps pop3 pop3s
protocols = pop3s
You might also want to set up the ip-address if you have several ip-addresses (You can leave it blank for all):
pop3s_listen =
Configure the ssl settings:
# Disable SSL/TLS support.
ssl_disable = no

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert_file = /usr/share/ssl/certs/dovecot.pem
ssl_key_file = /usr/share/ssl/private/dovecot.pem

# SSL parameter file. Master process generates this file for login processes.
# It contains Diffie Hellman and RSA parameters.
ssl_parameters_file = /var/run/dovecot/ssl-parameters.dat

# How often to regenerate the SSL parameters file. Generation is quite CPU
# intensive operation. The value is in hours, 0 disables regeneration
# entirely.
ssl_parameters_regenerate = 72

# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that 127.*.*.* and
# IPv6 ::1 addresses are considered secure, this setting has no effect if
# you connect from those addresses.
disable_plaintext_auth = yes
The cert and key files are created automatically by Dovecot when you install it. (The path to the certificates can be different depending on the version of Dovecot or your flavor of linux.). Please note, that these keys are not signed and will give "bad signature" errors when connecting from a client. To avoid this, you can use commercial certificates, or even better, you can use your own SSL certificates.

Don't forget to set it up so its starts at boot..

sudo /sbin/chkconfig --add dovecot
sudo /sbin/chkconfig --level 3 dovecot on


You can test it with:
openssl s_client -connect mail.sample.com:pop3s



On most linux distribution (including CentOS) procmail is installed by default.
Just check it with

procmail -v
and if it is not installed, install it with the following command.
yum install procmail

Each user can configure the procmail-rules the way (s)he wants to, by editing the .procmailrc-file in his home directory (/home/USER/.procmailrc).

But you can also add general rule for all user. This can be done in the file /etc/procmailrc.
We will need this when we use SpamAssassin, because we don't want to do it for every user.



You can install spamassassin with the following command:

yum install spamassassin

Now we need add the following line to /etc/procmailrc.
This is the global configuration file. You can also set the per user:
Just create the file /home/$USER/.procmailrc and add the rules.

:0fw: spamassassin.lock
| /usr/bin/spamassassin
The above line filters all incoming mail through SpamAssassin and tags probable spam with a unique header. If you would prefer to have spam blocked and saved to a file called "caughtspam" in your home directory, instead of passed through and tagged, append this directly below the above lines:
* ^X-Spam-Status: Yes
Or you can delete them (Not recommended)
* ^X-Spam-Status: Yes

You can configure SpamAssassin by editing the configuration file:
It has several option that you can configure, check the man page for a full list:

man Mail::SpamAssassin::Conf
The lines I use the most are whitelist_from and whitelist_to.
whitelist_from user@domain.com
This line allows mails from user@domain.com to not be marked as spam.
This rule blindly trusts the message, there are other rules that do some checks to make sure it is not spoofed.
whitelist_to me@mydomain.com
This line allows mails to me@mydomain.com to not be marked as spam.
That is not really true, it still does some checks and the obvious spam-mails are marked.
If you want all mails to pass through, all_spam_to is the rule you should use.

The following site helps you to setup the local.cf-file:

More info of Spamassassin can be found at http://spamassassin.apache.org