EmailMainXMLTagsEditHistoryDiscussion

  1. Introduction
  2. Features
  3. To do
  4. Components
  5. Postfix
    1. master.cf
  6. Cyrus
      1. Spam folder
  7. SpamAssassin
    1. Training
    2. Configuration
      1. Create folders
    3. Filter script
      1. To Do
  8. Administration
    1. Creating a user
      1. Cyrus Mailboxes
      2. Groups
      3. Razor configuration
  9. Usage
    1. Filtering mails
      1. Create your Sieve rules
      2. Apply your Sieve rules
    2. Mutt
      1. Configuration
        1. Using IMAP folders for drafts and sent-mail
        2. Highlighting messages
        3. Marking messages as spam or ham

Introduction

This documents the way Alejandro Forero Cuervo prefers to configure email servers.

The system is designed with the basic goal of allowing a power user, someone receiving lots of email probably through many different mailing lists, to handle things efficiently.

This is just a draft, I'm still improving this document.

Features

  • IMAP based access.
  • Virus control with ClamAV.
  • Spam control with SpamAssassin:
    • Individual per-user configuration files and databases (since SpamAssassin automatically learns from messages it sees). I prefer this over a global database since I believe it is more likely to produce correct results in the long run.
    • Messages way too likely to be spam are copied to a global spam folder (in case the administrator wants to look at them). Likely-spam messages are sent to the user's "spam" folder. Regular messages are sent to the inbox.
    • In order to re-train the spam system, users simply need to copy messages to their "learn-as-ham" or "learn-as-spam" folder.
  • Users can define their own rules to automatically filter their messages into specific folders, using Sieve.

To do

Our system isn't perfect. Far from it. Here are some things it misses which we would like to have:

Automatic expiration of messages
Make it possible for assign a date to each folder to have messages on the expire automatically. This is possible with Cyrus 2.2, but we're using Cyrus 2.1 (since 2.2 is not available in Debian stable as of the time of this writing).
Use DomainKeys and SMTP auth
Our current document does not yet explain how to configure DomainKeys nor SMTP Auth.

Components

  • Debian
  • Postfix
  • Cyrus
  • SASL
  • ClamAV
  • SpamAssassin
  • Fetchmail
  • Razor

You should get things like this:

apt-get install postfix razor spamassassin fetchmail clamav-base clamav clamav-daemon clamav-freshclam

Postfix

http://www.loadtr.com/resimuploads/52191c2a7c7bdda441df3b565050997b.jpg

master.cf

Define the mfilter service:

smtp      inet  n       -       -       -       -       smtpd
pickup    fifo  n       -       -       60      1       pickup
cleanup   unix  n       -       -       -       0       cleanup
qmgr      fifo  n       -       -       300     1       qmgr
rewrite   unix  -       -       -       -       -       trivial-rewrite
bounce    unix  -       -       -       -       0       bounce
defer     unix  -       -       -       -       0       bounce
trace     unix  -       -       -       -       0       bounce
verify    unix  -       -       -       -       1       verify
flush     unix  n       -       -       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
smtp      unix  -       -       -       -       -       smtp
relay     unix  -       -       -       -       -       smtp
showq     unix  n       -       -       -       -       showq
error     unix  -       -       -       -       -       error
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil

mfilter   unix  -       n       n       -       -       pipe
  flags=Rq user=cyrus argv=/var/spool/cyrus/bin/mfilter_transport ${user} ${extension}

Cyrus

...

Spam folder

Whenever you create a folder for a user, make sure to also make a spam folder for him (I'm not sure what happens in Debian if cyrdeliver is called with an unexisting folder; will it create it? If so, this entire subsection should be removed).

SpamAssassin

Training

Root's ~/.fetchmailrc:

poll localhost
  protocol imap
  user cyrus
  password PWPWPWPW
  fetchall
  no rewrite

Avoid encryption since we're connecting to localhost. :-)

~cyrus/bin/sa-learn-pending:

for user in $(getent passwd | cut -f1 -d:); do
  if groups $user | grep mailusers >/dev/null; then
    for type in ham spam; do
      fetchmail --folder user.$user.learn-as-$type --silent --mda "( echo -n 'From %F ' ; date '+%a %b %e %R:%S %Y' ; /bin/cat ; echo ) >> /tmp/mbox.$$";
      if test -f /tmp/mbox.$$; then
        su $user -c "sa-learn --$type --mbox" </tmp/mbox.$$;
        rm /tmp/mbox.$$;
      fi
    done
  fi
done

If you figure out how to suppress the fetchmail: Server CommonName mismatch: freaks-unidos.net != localhost errors (that still only receives unencrypted imap connections through the loopback interface), let me know.

Make a crontab for user root that runs this script. I choose to run it once every day, but you can pick a different interval.

11 2 * * * ~cyrus/bin/sa-learn-pending 2>/dev/null >/dev/null

Here are a few notes:

  • The crontab dumps the output of the sa-learn-pending command. We shouldn't do that. But then, the CommonName mismatch error would make things very verbose (and I don't want to just grep it out, that adds more complexity).
  • The sa-learn-pending scripts does this:
    • For every user in the mailusers group:
      • Fetch all learn-as-ham into a mbox folder using fetchmail and then learn all of them. Do the same for the learn-as-spam messages.
  • The --mda parameter in sa-learn-pending isn't very reliable; it would be best to use a program to deliver messages to the mbox with better error reporting. If you figure out one to use instead, let me know. I'll use it for the time being since losing messages there (before the training) isn't that bad (we're erasing them anyway!).

Configuration

Create folders

Enter the following commands at cyradm:

cm cyrus.spam
cm cyrus.virus
dam cyrus.spam anyone
dam cyrus.virus anyone
sam cyrus.spam cyrus all
sam cyrus.virus cyrus all

Filter script

~cyrus/bin/mfilter_transport, what a sexy script:

#!/bin/sh

USER=$1
MAILBOX=$2

EX_OK=0
EX_TEMPFAIL=75
EX_UNAVAILABLE=69

VIRUS_RETURN=$EX_OK;

/usr/bin/spamc -u $USER >/tmp/filter.$$ || { echo "Unable to save mail: /tmp/filter.$$"; rm -f /tmp/filter.$$; exit $EX_TEMPFAIL; }

CLAMAV=$(/usr/bin/clamdscan --disable-summary --stdout - </tmp/filter.$$)

if echo $CLAMAV | grep -q FOUND; then
  MAILBOX=virus;
  USER=cyrus;
  FORCE_EXIT=$EX_OK;
elif echo $CLAMAV | grep -q ERROR; then
  echo $CLAMAV;
  rm -f /tmp/filter.$$;
  exit $EX_TEMPFAIL;
elif egrep -q "^X-Spam-Level: \*{12,}" /tmp/filter.$$; then
  MAILBOX=spam;
  USER=cyrus;
  FORCE_EXIT=$EX_UNAVAILABLE;
elif grep -q "^X-Spam-Flag: YES" /tmp/filter.$$; then
  MAILBOX=spam;
fi;

/usr/sbin/cyrdeliver -a "$USER" -e -m "$MAILBOX" "$USER" </tmp/filter.$$
RET=$?;
rm -f /tmp/filter.$$;
test $FORCE_EXIT && exit $FORCE_EXIT
exit $RET;

To Do

  • Only send replies for spam messages when either:
    • The origin address can be traced back to its domain (using DomainKeys or SPF) or
    • The domain name of the origin address doesn't have DomainKeys nor SPF configured.

Administration

Creating a user

Suppose we're creating user azul.

Cyrus Mailboxes

Connect as user cyrus and run the following commands:

cm user.azul
cm user.azul.spam
cm user.azul.learn-as-spam
cm user.azul.learn-as-ham
sam user.azul.learn-as-spam cyrus lrds
sam user.azul.learn-as-ham cyrus lrds

Groups

Add the user to the mailusers group.

Razor configuration

As the user you are creating:

$ razor-client
$ razor-admin --create
$ razor-admin --register

Usage

This section explains how to use the email system from an end-user's point of view.

Filtering mails

Right now setting up filter is rather difficult: it assumes knowledge of Sieve as well as the capability of login into the machine (eg. using an SSH client or some other similar method) and running commands on it.

Create your Sieve rules

Write your rules into ~/lists.script (you could use any other name but make sure to use it in the steps below, when applying your script to the server).

The following is an example:

require ["fileinto"];

if header :contains "list-post" "<mailto:users@subversion.tigris.org>"
{
  fileinto "INBOX.subversion-users";
  stop;
}

Apply your Sieve rules

Login to the server and run:

sieveshell localhost

Authenticate and run the following commands in the shell:

put lists.script
activate lists
quit

Mutt

Mutt is my favorite email client. :-)

Configuration

Using IMAP folders for drafts and sent-mail

Add to ~/.muttrc:

set folder=imaps://azul@freaks-unidos.net/INBOX;
set spoolfile==;
set postponed==Drafts;
set record==Sent;

As you see, you can reference your IMAP folders simply by =name.

Highlighting messages

I want to highlight messages coming from an address from which I had previously received ham. I made the following script:

#!/bin/sh

# I use two sed processes voluntarily (to easily handle both "From:
# foo@bar.com" as well as "From: foo <foo@bar.com>").

ADDRESS=$(grep ^From: | head -1 | sed 's/^From: *//' | sed 's/^.*<\(.*\)>.*$/\1/')

# Add it unless it is already there.

grep $ADDRESS ~/.mutt.scores.rc || echo "score '~f $ADDRESS' 10" >>~/.mutt.scores.rc

It reads a message from its standard input, extracts the email address it comes from and adds it to the .mutt.scores.rc file unless it is already there. The next time Mutt reads it, it will give a greater score to messages coming from it.

To highlight the messages I just add the following to ~/.muttrc

source "/home/azul/mutt.scores.rc";
color index brightwhite default '~n 10-';

Note that you could also color messages based on the X-Spam-Level header (eg. make it so messages with a high spam score are shown in a color that is slightly more difficult to read), but that slows down the process of displaying messages significantly. An option would be to use the X-Label header, but that seems too complicated (and it would make it difficult to use that header for other purposes).

Marking messages as spam or ham

I define two key bindings (in ~/.muttrc:

macro index S "s=learn-as-spam\n" "learn message as spam and delete it";
macro index H "C=learn-as-ham\nsimaps://azul@freaks-unidos.net/INBOX.read\n|~/bin/mutt-from-score >/dev/null\n" "learn message as ham and move it to the read folder";

Last update: 2007-03-01 (Rev 10750)

svnwiki $Rev: 15576 $