Creating A Linux Mail Server
Creating A Linux Mail Server
Creating A Linux Mail Server
Software Used
• Installing Postfix
• Installing Fetchmail
• Installing Procmail
• Installing SpamBayes
• Installing Mutt
• Installing courier-imap courier-authlib
• Installing SquirrelMail
• Installing pop-before-smtp
Postfix Configuration
• main.cf
Fetchmail Configuration
Mutt Configuration
• .muttrc Configuration
• New Mutt Commands
SquirrelMail Configuration
Courier Authentication
Pop-before-smtp Configuration
Additional Simple Procmail Recipes and Mailbox Config
Conclusion
Resources
• Example Files
• Links
Contributions
This document covers how I have set up my Linux box to work as a Mail Server. The details will
be specific to Arch Linux, but it will be be general enough for any *nix distribution if you have a
knowledge of installing software packages, finding the location of configuration files, and
starting/stoping services..
My goals in creating this mail system are to have all of my mail, from various email accounts,
stored locally on my machine so I can access it anytime via SSH, the web, or imap. I wanted all
of my mail delivered to my local user account and I wanted the spam to be sucked out and
launched into space.
The backbone of the mail system is the Mail Transport Agent (MTA). It will handle receiving
mail addressed directly to your machine, sending it to the correct users mail box, and sending
mail out from the machine. I determined Postfix to be the best choice for my MTA and after
some reading found Procmail for sorting mail, SpamBayes for detecting spam, and Fetchmail for
grabbing mail from my pop mailboxes.
Software Used
• Arch Linux
• Postfix 2.1.5
• Procmail 3.22
• SpamBayes 1.1a1
a Bayesian anti-spam filter, initially based on the work of Paul Graham. The
major difference between this and other, similar projects is the emphasis on
testing newer approaches to scoring messages.
• Mutt 1.4.2.1
• Courier-imap 4.0.4
• Courier-authlib 0.57
• Pop-before-smtp 1.38
A simple daemon written in Perl, to allow email relay control based on successful
POP or IMAP logins.
Installing Postfix
A note for those with dynamic IP addresses: Before installing Postfix we must first
consider if it will need to make use of Simple Authentication and Security Layer (SASL).
If you have a dynamic IP address and are using a service like dyndns.org you will need to
have Postfix send your mail through your ISP's mail server (with authentication) making
use of SASL for the connection. This is because many domains that you will send email
to will recognize your hostname as pointing to a dynamic IP address and send the mail
back. Check if your distributions Postfix package was built with SASL support or if you
are compiling Postfix from scratch add SASL with a ./configure option.
If you've determined you do not need SASL support in postfix:
If you do need SASL support we need to install cyrus-sasl and use the Arch Build System
(abs) utility for building Postfix. Follow the instructions bellow or follow these Arch
Wiki instructions: http://wiki.archlinux.org/index.php/PostFix_Howto_With_SASL
to:
make OPT="${CFLAGS}" \
CCARGS="-DUSE_SASL_AUTH -I/usr/include/sasl/" \
AUXLIBS="-L/usr/lib/sasl2 -lsasl2" || return 1
Now run:
$ makepkg
$ pacman -A postfix-*.pkg.tar.gz
I like to then copy the package into a directory under /var/lib/pacman so I have access to
all of my abs built packages later:
$ mkdir /var/lib/pacman/abs_built
$ cp postfix-*.pkg.tar.gz /var/lib/pacman/abs_built
Installing Fetchmail
$ pacman -S fetchmail
Installing Procmail
$ pacman -S procmail
Installing SpamBayes
SpamBayes is not yet in the pacman repository. Download it, extract, and install
(substitute version numbers with most current):
$ wget
http://dl.sourceforge.net/sourceforge\
/spambayes/spambayes-1.1a1.tar.gz
$ tar zxvf spambayes-1.1a1.tar.gz
$ cd spambayes-1.1a1
$ python setup.py install
Installing Mutt
$ pacman -S mutt
SquirrelMail as well as other mail clients (evolution, outlook, cell phone, etc.) will use
this to connect to the mail box. Courier-imap also depends on courier-authlib, so this
command will install that as well.
$ pacman -S courier-imap
Installing SquirrelMail
$ pacman -S squirrelmail
Installing pop-before-smtp
You are going to want to consider using Postfix/TLS or pop-before-smtp if you are
interested in users connected via IMAP being able to send mail (using your mail server as
a SMTP relay). I recommend using Postfix/TLS but will not cover how to
install/configure it in this document.
Pop-before-smtp is not in pacman repositories. Substitute version numbers with the most
current.
$ wget http://dl.sourceforge.net/sourceforge/popbsmtp/pop-before-smtp-
1.38.tar.gz
$ tar zxvf pop-before-smtp-*.tar.gz
$ cd pop-before-smtp-*
Read the README in this directory and then read README.QUICKSTART in the
contrib directory for where to copy the necessary files to.
Postfix Configuration
main.cf
Now change to the '/etc/postfix' directory and open up main.cf for editing.
The domain name for my machine is through dyndns.org. Set your myhostname and my
domain to something like this:
Next we are going to want to set Postfix up for using qmail-style delivery with Maildir
(where each email is stored in its own file). This is for courier-imap which SquirrelMail
will be using to access the mail and will have other advantages. Don't forget the ending
forward slash.
home_mailbox = Maildir/
Set it up so that incoming mail is sent through procmail and so we can alias names/users
to mailboxes.
alias_maps = hash:/etc/postfix/aliases
If you have a dynamic IP or have trouble with mail being returned from large ISP's or
mail systems you are going to have to take a few extra steps. We will set it up so that
mail will go through a relay host. In this example I will use my ISP's (SBC) smtp server
as an example. Make these additional changes to main.cf
relayhost = [smtp.sbcglobal.yahoo.com]
# authentication for sbc yahoo
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
That wraps up our changes to main.cf. We just need to create the hash aliases databases that we
defined above. Add these lines to the top of /etc/postfix/aliases (replacing hypexr with your user
account of course):
root: hypexr
spam: hypexr
ham: hypexr
$ postalias aliases
Set up smtp server and authentication for SBC mail relay. sasl_passwd:
smtp.sbc.mail.yahoo4.akadns.net [email protected]:my_passw
Note: Server name can change from time to time. There is a CNAME that points to this name but
CNAMEs do not work here.
$ ./postmap sasl_passwd
$ /etc/rc.d/postfix start
Having problems getting it to start? Check out the Postfix log file usually in /var/log/mail or
/var/log/maillog.
Fetchmail Configuration
We are going to run our fetchmail daemon from user root. So create the file /root/.fetchmailrc:
This tells fetchmail to check every minute for mail at pop.mypop.com and also at my gmail
account. The flush option at the end of the mypop entry tells it to remove the mail after it is
downloaded. I do not want the mail removed from my Gmail account so I use the keep option.
Google also uses ssl, hence the "with ssl". Fetchmail comes with its configuration utility
fetchmailconf which makes setting up your .fetchmailrc file easy.
I don't believe that Arch Linux has a rc script for fetchmail. The one that I made
(/etc/rc.d/fetchmail) looks like this (stat_busy, stat_fail, stat_done are specific to Arch Linux.
You could take these out):
#!/bin/sh
. /etc/rc.conf
. /etc/rc.d/functions
DAEMON_NAME="fetchmail"
DAEMON_CONF="/root/.fetchmailrc"
DAEMON_PATH="/usr/bin/fetchmail"
case "$1" in
start)
stat_busy "Starting ${DAEMON_NAME}"
[ -z "$PID" ] && ${DAEMON_PATH} -f ${DAEMON_CONF} -d
60 &> /dev/null
if [ $? -gt 0 ]; then
stat_fail
else
add_daemon ${DAEMON_NAME}
stat_done
fi
;;
stop)
stat_busy "Stopping ${DAEMON_NAME}"
[ ! -z "$PID" ] && kill "$PID" &> /dev/null
if [ $? -gt 0 ]; then
stat_fail
else
rm_daemon ${DAEMON_NAME}
stat_done
fi
;;
restart)
# calling 'stop' and 'start' without the $0 fails...
$0 stop
sleep 3
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
exit 0
$ /etc/rc.d/fetchmail start
Or if you don't want to create/modify an rc script you can start the fetchmail daemon like:
$ /usr/bin/fetchmail -d 60
We are going to be using Spambayes to train and determine if mail is spam and Procmail to sort
the mail into folders when they enter our mail system. These two go together as far as Procmail
is going to use Spambayes to help sort the mail.
I had used SpamAssassin for a year and had not been very happy with its performance. I have
only been using Spambayes for a few weeks and have been pleasantly surprised by how well it
has worked and how quickly it adapts. In fairness I had been training SpamAssassin on all of my
spam, the spam it had caught and the spam it had missed as well. It was also an older version and
I was not using all of the features. With that being said if you are curious give it a try. Many
other excellent programs exist. A quick search on Google will turn them up.
When Spambayes is installed it is going to move several files that start with sb_ into your
/usr/bin directory. We are going to be interested in sb_mboxtrain.py and sb_filter.py. The former
trains the spam filter and the later classifies incoming spam. There are two methods I tried for the
initial training:
1. Since I already had thousand of spam and ham (non spam) messages saved up I first tried
initially training on this older mail. The results were okay but it was miss sorting mail.
These problems would have sorted them selves out with the continued training of the
misclassified mail but it would have also took a little while because the database had
already been trained so much.
2. The second method I used was extremely effective. I started out with no training on
initial messages. I simply let Spambayes work with no information. I then sent the spam
and ham messages that ended up in the wrong mailbox to a designated folder. I then run
the Spambayes training program on these miss classified messages.
The results from the second method have been amazing. Without even having to manually
classify very many messages Spambayes has been performing at superior levels. Check out
Spambayes Wiki for many other training methods. I will discuss easy methods of sorting miss
classifications in the Mutt and Squirrel Mail sections.
We are going to want Maildir folders to hold our regular mail, mail classified as spam,
mail classified as unsure, missed spam, and missed ham.
If the standard Maildir directory (~/Maildir) doesn't already exist lets create it with the
necessary sub directories to make it a mail box. Run these commands from your user
account who will be receiving the mail.
$ mkdir ~/Maildir
$ mkdir ~/Maildir/{new,cur,tmp}
And now the other 4 directories that we are going to use for dealing with spam (Making
the directories hidden is going to be done for integration with Squirrelmail):
$ mkdir ~/Maildir/{.MissedSpam,.MissedHam,.CaughtSpam,.Unsure}
$ mkdir ~/Maildir/.MissedSpam/{new,cur,tmp}
$ mkdir ~/Maildir/.MissedHam/{new,cur,tmp}
$ mkdir ~/Maildir/.CaughtSpam/{new,cur,tmp}
$ mkdir ~/Maildir/.Unsure/{new,cur,tmp}
#!/bin/sh
# Script to copy mail missed spam and ham into correct folders
# and run sb_mboxtrain.py to train spambayes
# Training will be done only on missed spam and ham
$ chmod +x ~/Maildir/train_spambayes
Set up our database that will be consulted for new email and trained on new spam/ham:
$ /usr/bin/sb_filter.py -d $HOME/.hammie.db -n
You will want cron installed so that it can launch the script above, which trains
Spambayes, every night at 3:21 am. Edit your cron jobs with the command crontab -e
and add:
21 3 * * * ~/Maildir/train_spambayes
These are basic procmail recipes that will sort the spam from ham. From Spambayes on
Unix or Linux. Add these lines to your mail recipient's ~/.procmailrc:
SHELL=/bin/sh
MAILDIR=$HOME/Maildir
DEFAULT=$HOME/Maildir/
CAUGHT_SPAM=$MAILDIR/CaughtSpam/
UNSURE=$MAILDIR/Unsure/
#Spambayes process
:0fw:hamlock
| /usr/bin/sb_filter.py -d /home/hypexr/.hammie.db
:0
* ^X-Spambayes-Classification: spam
${CAUGHT_SPAM}
:0
* ^X-Spambayes-Classification: unsure
${UNSURE}
So incoming mail is not filtered through procmail's rules where Spambayes's sb_filter
decides whether it is spam or ham. The mail is now sitting in the correct directories and
ready to be accessed by whatever reader/front-end you would like. Next I going to
describe setting up Mutt and SquirrelMail for viewing your mail. Mutt will be the most
powerful option combining speed and sleekness but SquirrelMail will be able to match
functionality.
Mutt Configuration
First we need to set the MAIL variable so that Mutt will know where to look for your mail. In
your ~/.bashrc (create if does not exist) add the line:
MAIL='~/Maildir'
Exit out of your shell and log back in so that the variable will be set or run export
MAIL='~/Maildir'. On some systems mutt will not use $MAIL to determine the location of
your mail box. When trying to start mutt if it reports a message that no mail directory exists you
can try setting the MAILDIR variable or just create the directory that it wants to use and make it
a valid Maildir: mkdir -p ~/.maildir/{cur,new,tmp} where .maildir is the folder that mutt wants
to use. If you use a directory other than ~/Maildir remember to substitute that wherever I
reference Maildir in this document.
Now for the fun part. Lets make everything look pretty and integrated in Mutt. If you start up
Mutt right now you will see any mail that your system has received since you have completed
the steps above. If no mail shows up in Mutt and there should be mail you need to first check if
Spambayes has filtered it into your .Unsure or .CaughtSpam directories. Type 'c' to change
directories and enter ~/Maildir/Unsure and check out the mail thats been classified as spam: 'c'
~/Maildir/CaughtSpam. If you still have not found the mail that you are expecting to have
received make sure that you have configured Postfix, Fetchmail, and Procmail correctly. Also,
try sending mail directly to [email protected] and see if it shows up in one of the
directories above.
Now mail is flowing into your system and we can check how Spambayes has classified it by
checking the different mail folders. The miss classified mail just needs to be moved into the
correct folders for the training.
To manually move the misclassified spam mail:
1. From you Maildir inbox tag each message that has arrived that is spam. Do this by
pressing 't' and an asterisk will appear by the messages. After all of the messages have
been tagged, press '; m' and enter ~/Maildir/MissedSpam and the spam messages in
your inbox will be moved to the MissedSpam mailbox for training by spambayes.
2. When looking at the mail that it has classified as spam in '~/Maildir/CaughtSpam', tag all
of the messages it considered spam that were ham and press '; C' and enter
~/Maildir/MissedHam. Now tag them again and press '; m' and enter ~/Maildir to move
them into your inbox, where they should have been placed in the first place.
Of course all of this manual stuff is a huge pain so lets automate all of it in .muttrc.
.muttrc Configuration
This .muttrc file is going to save you a quazillion.. thats right a quiazalliona hours in
productivity in dealing with our current setup. Here it is:
# This one lets me quickly move job search related emails to the
# correct directory. Want to give me a job? :)
macro index B ";s~/Maildir/.Job\r\r$\r"
macro pager B ";s~/Maildir/.Job\r\r$\r
# Thanks to many people whom have written the documents and posts
that I
# have gotten these settings from.
Here are the most useful (as far as dealing with spam) commands that we can now use in
mutt:
So for example, if a couple of spam messages show up in your inbox you can now tag
them and hit 'S' (remember its uppercase s) and have them vanished into .MissedSpam for
training.
SquirrelMail Configuration
!!! IMPORTANT SECURITY NOTE!!! - Using SquirrelMail like this is not secure! Sending
the plain text passwords that you use for your Unix account can be accessed by by a 3rd party,
which would them access to your account. You should set up a secure server with SSL and have
Courier-imap use passwords that differ from the users system password using Courier Authlib,
which I will demonstrate in the next session. Excellent documents exist all over the net for
setting up your web server with ssl.
Courier Authentication
Now is a good time to address a bit of essential security. As of now when a user connects via the
SquirrelMail or IMAP interface the passwords are being sent in plain text and if these are sniffed
that users system account is compromised. Without adding secure connections we can minimize
the threat by using alternate passwords for imap connections. The snoop would then have access
to your mail, but not be able to log in to the system.
Edit your authdaemonrc file. If your on Arch Linux this will be in /etc/authlib. Under
authmodulelist I commented out:
authmodulelist="authuserdb"
I believe that adding authuserdb to the front of the list may work, but I am only using this
method of authentication so it is all I need in my list.
You will now be prompted for this pseudo users new password. Next make sure that
/etc/authlib/userdb has read/write/execute access for the owner. If not chmod 700
/usr/authlib/userdb. Now create the user database that courier is going to look to for
authentication:
$ makeuserdb
Again look to using Postfix/TLS for a tunneling the connection through a secure connection.
Pop-before-smtp Configuration
!!! IMPORTANT SECURITY NOTE!!! - I will not use the pop-before-smtp method because it
involves sending a password over an insecure connection. Use Postfix through a SSL connection,
Postfix/TLS, to accomplish this. Since your local machines are likely already allowed to use your
Postfix as a mail relay the only time that you would be using this method is from a non-trusted
server where you password can be sniffed. If you still choose to use this method make sure that
you have changed the users courier password as described in Courier Authentication.
If you are a member of any news letters/mailing lists you can have them automatically sorted to
their own mailbox using Procmail. First create the new mail directory in your ~/Maildir
directory. Lets call it .Sbayes and pretend that we are on the Spambayes mailing list. So exactly
as before with the spam related mailboxes:
mkdir -p ~/Maildir/.Sbayes/{cur,new,tmp}
In the .mutrc example above it shows an example of setting alt-5 as the macro to see your
Spambayes emails.
A slightly different method can be used to send spam and ham for training. Adding the following
lines will allow you to bounce spam messages to spam@localhost (localhost or your
mail_domain.com) and ham messages to ham@localhost:
If you want to bounce messages to the spam and ham addresses like this, you will need to make
sure that the headers stay intact. Do not try using this or a similar technique for forwarding mails
to an address because the email's headers would not be intact and this is a large part of the spam
classification. This method works because above we specified spam and ham as aliases for
hypexr in the Postfix aliases file.
Conclusion
For Arch Linux users, Add saslauthd authdaemond courier-imap postfix fetchmail to
DAEMONS in your /etc/rc.conf file and they will be started automatically when your machine
boots. If you are running a web server have the httpd service listed after the services we are
adding.
/etc/rc.conf
Enjoy your new mail system and centralized mailbox. If you are handling a large number of
users for you email system this is just the tip of the iceberg and you are going to mostly be
interested in virtual users, security, and a system wide spam classifier. There are many good
documents on various setups to accomplish this, see the links section. If you have any
suggestions, questions, comments, or corrections send me an email or drop a note in the forum. If
this document has been of any use to you, cheers. :)