Maildrop Syntax Tutorial: Difference between revisions
| Line 175: | Line 175: | ||
=A real example= | =A real example= | ||
<pre> | |||
MAILDIR="/users/$LOGNAME/mail" | |||
DEFAULT="/var/mail/$LOGNAME" | |||
SPAMCAN="/users/$LOGNAME/mail/SPAM" | |||
logfile "/users/$LOGNAME/maildrop_log" | |||
# | |||
if(/^Subject: *!.*$/) | |||
{ | |||
if($MATCH2 =~ /Dialup Session Report/) | if($MATCH2 =~ /Dialup Session Report/) | ||
{ | { | ||
| Line 198: | Line 198: | ||
to "$MAILDIR/domreg" | to "$MAILDIR/domreg" | ||
} | } | ||
} | |||
# end of Subject exceptions | |||
# | |||
# begin To/Cc exceptions | |||
foreach /^(To|Cc): *!.*$/ | |||
{ | |||
if($MATCH =~ /ilikespam@/) | if($MATCH =~ /ilikespam@/) | ||
{ | { | ||
| Line 219: | Line 219: | ||
to "$MAILDIR/puppy" | to "$MAILDIR/puppy" | ||
} | } | ||
} | |||
# end of To and Cc exceptions | |||
# | |||
# beginning of From exceptions | |||
if(/^From:*!.*$/) | |||
{ | |||
if($MATCH2 =~ /joejoe@uswest.com/) | if($MATCH2 =~ /joejoe@uswest.com/) | ||
{ | { | ||
| Line 246: | Line 245: | ||
to "$DEFAULT" | to "$DEFAULT" | ||
} | } | ||
} | |||
# asdf end of From: exceptions | |||
# | |||
log "Ptrn: final match" | |||
to "$SPAMCAN" | |||
</pre> | |||
---- | ---- | ||
'' | ''If you have questions, please email the [mailto:help@swcp.com SWCP Helpdesk]. | ||
Revision as of 11:34, 26 January 2009
An Introduction to Maildrop filtering syntax
SWCP uses Maildrop to handle its anti-spam filtering. However, Maildrop also allows for a lot of other types of filtering, most of which require manually editing .mailfilter files (and reading your email on the server via TWIG, pine, mutt, etc.). This tutorial covers the basics of manually editing a .mailfilter for an assortment of uses.
Additionally, SWCP provides a web interface for our end users to create a user's .mailfilter file, and most of our users use the web interface to do so. Manual editing is incompatible with web interface editing.
Getting Started
If you wish to manually edit your .mailfilter, first log into https://kumo.swcp.com/spam and set the option "Filtering" to No. Wait 15 minutes. You should have a new file called .mailfilter.swcp. From this point you can hand edit the file then rename it to .mailfilter. To keep SWCP or the web interface from mistakenly overwriting your .mailfilter file, be sure to remove the very top line:
# SWCP:MAILFILTER:neal
Variables
Variables can be declared as below.
Without Quotes
DEFAULT=/var/mail/sampleuser
With variable substitution
SPAMCAN=/var/spool/mail/spamdrop/$LOGNAME
With quotes
SUPPORT="/users/sampleuser/mail/support"
With quotes and variable substitution
HELP="/users/$LOGNAME/mail/help"
Logging your filtered email
I have found that logging filtered email makes troubleshooting much easier. To make this function operate you'll want to set the logfile variable. Then in each recipe add a log line with a comment. Here's an example.
logfile "/home/sampleuser/.mailfilter.log" ...
if (/^To:.*sampleuser@swcp.com /)
{
log "Ptrn: sampleuser@swcp.com whitelist"
to "$DEFAULT"
}
Now when this rule is matched and delivers a message your .mailfilter.log will have a set of lines in it similar to this.
Ptrn: sampleuser@swcp.com whitelist Date: Wed Apr 23 17:21:44 2003 From: Some Sender <someone@somewhere.com> Subj: Some Subject File: /var/spool/mail/sampleuser
As you can see this makes finding an elusive problem somewhat easier. There is one unfortunate side effect, of course there had to be one :-) Depending on how quickly your mailserver is getting email you may find that the 'Ptrn:' line and the 'Date: From: Subj: File:' lines are out of sync. These are difficult problems to solve without modifying the source to maildrop.
Filter Contents of the To: Cc: From: or Subject: fields.
Visit http://www.flounder.net/~mrsam/maildrop/maildropfilter.html for complete regex syntax.
if (/^To:.*sampleuser@swcp.com /)
{
to "$DEFAULT"
}
if (/^Cc:.*help@swcp.com/ )
{
to "$HELP"
}
if (/^From: My Enemy <anotheruser@swcp.com>/)
{
to "$SPAMCAN"
}
if (/^Subject: About your puppies/)
{
to "$DEFAULT"
}
Filter Contents of the header, body, both, or case.
You can match header, body, header & body, or case (upper or lower).
Header is always assumed, so you don't have to put :h after most matches Be very careful to limit the size of your search if you use :b see below.
- :h = match in the header only
- :b = match in the body only
- :w = match in the header and the body
- :D = match case
- :p = match only the first 100 lines of the body (SWCP Specific)
First Version
This version matches the words opt-in, opt in, opt-out, opt out in the body with no reguard for the size of the message.
if (/(opt-in|opt in|opt-out|opt out) /:b )
{
to "$SPAMCAN"
}
A Better Version
This version matches the words opt-in, opt in, opt-out, opt out in the body but constrains the message size to less than 500 lines and less than 15 kilobytes.
if (($LINES < 500 && $SIZE < 15000) && /(opt-in|opt in|opt-out|opt out) /:b)
{
to "$SPAMCAN"
}
Using Matching
If you have multiple entries to match say from the Subject line, consider the following.
The special character '!' tells maildrop to stick everything it matches up to the end of line '$' into one of its special MATCH variables.
Note: It should be noted that maildrop has (what I consider to be) a documented bug. Different types of matches cause different MATCH variables to be used. In particular if statements using this match syntax dump their variable contents into MATCH2, foreach matches dump their match contents into a variable called MATCH, see below.
if (/^Subject: *!.*$/)
{
if ($MATCH2 =~ /Updates from the hospital about (mom|dad|brother)/ )
{
to "$DEFAULT"
}
if ($MATCH2 =~ /Win / && $MATCH2 =~ /Opt/:D && /casino/:p)
{
to "$SPAMCAN"
}
}
Looping with Foreach
If you wish to match to & cc in the same statement you must use a foreach
foreach /^(To|Cc): *!.*$/
{
if ( $MATCH =~ /@netris.com/)
{
to "$DEFAULT"
}
if ($MATCH =~ /rob@nowhere.com / && /casino/:p )
{
to "$SPAMCAN"
}
}
Dropping a message entirely
If you want to send something to /dev/null, use the keyword 'exit'. It should send any matched email messages to /dev/null.
if ( /To: sampleuser@netris.com/)
{
exit
}
Filter Then Forward
If you want to filter then forward or cc a message, simply place a ! at the begining of your delivery line. This tells maildrop to forward all mail matching that criteria to someone@someotheraddress.com. If you want to forward all email simply put the 'cc' line outside the body of the regex.
if ( /To: sampleuser@netris.com/)
{
cc "!someone@someotheraddress.com"
}
Testing your new filter rules
Log into a a host that is running maildrop and run the following command*:
maildrop -V 4 -d logname < msg.txt
Where logname is your username and msg.txt is a file containing 1 email message saved from pine or mutt.
You'll probably want to log into a host other than your mailserver. If your system has a systemwide maildroprc you'll see all the debug from that too. That's probably not what you want :-)
A real example
MAILDIR="/users/$LOGNAME/mail"
DEFAULT="/var/mail/$LOGNAME"
SPAMCAN="/users/$LOGNAME/mail/SPAM"
logfile "/users/$LOGNAME/maildrop_log"
#
if(/^Subject: *!.*$/)
{
if($MATCH2 =~ /Dialup Session Report/)
{
log "Ptrn: Dialup Session Report"
to "$MAILDIR/portmasters"
}
if($MATCH2 =~ /OMS#.*Path Built/)
{
log "Ptrn: Path Built"
to "$MAILDIR/pathbuilt"
}
if($MATCH2 =~ /Domain request:/)
{
"Ptrn: Domain request"
to "$MAILDIR/domreg"
}
}
# end of Subject exceptions
#
# begin To/Cc exceptions
foreach /^(To|Cc): *!.*$/
{
if($MATCH =~ /ilikespam@/)
{
log "Ptrn: ilikespam spam"
to "$MAILDIR/throwaway"
}
if($MATCH =~ /abc@/)
{
log "Ptrn: abc spam"
to "$MAILDIR/throwaway"
}
if($MATCH =~ /puppyfriends@yahoogroups.com/)
{
log "Ptrn: Puppy email"
to "$MAILDIR/puppy"
}
}
# end of To and Cc exceptions
#
# beginning of From exceptions
if(/^From:*!.*$/)
{
if($MATCH2 =~ /joejoe@uswest.com/)
{
log "Ptrn: joejoe"
to "$MAILDIR/joe"
}
if($MATCH2 =~ /catchthisemail@swcp.com/)
{
log "Ptrn: catchthisemail spam"
to "$MAILDIR/junk"
}
if($MATCH2 =~ /((samplemom|sampledad|samplebrother|sistersample)@swcp.com)|marie@nm.net/)
{
log "Ptrn: family match"
to "$DEFAULT"
}
if($MATCH2 =~ /(majordomo@swcp.com|replies@opensrs.org)/)
{
log "Ptrn: majordomo-opensrs"
to "$DEFAULT"
}
}
# asdf end of From: exceptions
#
log "Ptrn: final match"
to "$SPAMCAN"
If you have questions, please email the SWCP Helpdesk.