全部博文(1144)
分类: LINUX
2007-04-01 19:03:16
Introduction
maildrop is the mail filter/mail delivery agent that's used by the Courier Mail Server. You do not need to download maildrop from here if you already have Courier installed. This is a standalone build of the maildrop mail filter that can be used with other mail servers.
maildrop is a replacement for your local mail delivery agent. maildrop reads a mail message from standard input, then delivers the message to your mailbox. maildrop knows how to deliver mail to mbox-style mailboxes, and maildirs. "maildir" is a mailbox format used by Courier and Qmail.
maildrop optionally reads instructions from a file, which describe how to filter incoming mail. These instructions can direct maildrop to deliver the message to an alternate mailbox, or forward it somewhere else. Unlike procmail, maildrop uses a structured filtering language.
maildrop is written in C++, and is significantly larger than procmail. However, it uses resources much more efficiently. Unlike procmail, maildrop will not read a 10 megabyte mail message into memory. Large messages are saved in a temporary file, and are filtered from the temporary file. If the standard input to maildrop is a file, and not a pipe, a temporary file will not be necessary.
maildrop checks the mail delivery instruction syntax from the filter file, before attempting to deliver a message. Unlike procmail, if the filter file contains syntax errors, maildrop terminates without delivering the message. The user can fix the typo without causing any mail to be lost.
[edit]Installation
emerge maildrop
[edit]Configuration
[edit]Global
Edit /etc/maildroprc:
# Global maildrop filter file
#DEFAULT="$HOME/.maildir/"
#
# Define variables
#
SHELL="/bin/bash"
DEFAULT = "$HOME/.maildir"
MAILDIR = "$HOME/.maildir"
#
# Logfile destination
# After your satisifed that this is working properly, comment out all
# the lines that start with "log"
#
logfile "$HOME/.getmail/.maildrop.log"
#
# Markers for the log file
#
log "Markers: ---------------------------------------------"
log " (**) from config file, (II) informational, (WW) warning"
log "--------------------------------------------------------"
log ""
######################################################################
#
# Adding missing headers for PGP/MIME
#
BPM="-----BEGIN PGP MESSAGE-----"
EPM="-----END PGP MESSAGE-----"
BPS="-----BEGIN PGP SIGNATURE-----"
EPS="-----END PGP SIGNATURE-----"
if (!/^Content-Type: message/ && !/^Content-Type: multipart/ \
&& !/^Content-Type: application\/pgp/)
{
if (/^$BPM/:b && /^$EPM/:b)
xfilter "reformail -A 'Content-Type: application/pgp; format=text; \
x-action=encrypt'"
if (/^$BPS/:b && /^$EPS/:b)
xfilter "reformail -A 'Content-Type: application/pgp; format=text; \
x-action=sign'"
}
#####################################################################
#
# Correcting wrong signature dashes
#
if (/^--($|[ ]{2,}^)/:b)
{
xfilter "sed -r 's/^--($|[ ]{2,}^)/-- /'"
log "(II) Sig Dashes corrected"
}
# Include any rules set up for the user - this gives the
# administrator a way to override the domain's mailfilter file
#
# this is also the "suggested" way to set individual values
# for maildrop such as quota. (why do you need quota on your own PC?)
#
`test -r $HOME/.mailfilter`
if( $RETURNCODE == 0 )
{
log "(==) Including $HOME/.mailfilter"
exception {
include $HOME/.mailfilter
}
}
Per user
~/.mailfilter will be included from /etc/maildroprc
so be sure it exist and have a permission 600 (otherwise it will give you an error)
touch ~/.mailfilter
chmod 600 ~/.mailfilter
[edit]Comments at the header of the file
# - maildrop mailinglist.
#
# - Please browse the mailinglist archives for more examples.
#
# - Save this file as .mailfilter in your home directory and do
# chmod 600 .mailfilter
# - Do not edit your .mailfilter file with a DOS or WINDOWS
# texteditor!!
# - Linebreaking doesn't work inside a pattern. So the following
# rule cannot work:
#
#if (/^Subject:.*(exim|sendmail| \
# gdm|xdm|imap|cgi)/)
#
# and must be in one line:
#
# if (/^Subject:.*(exim|sendmail|gdm|xdm|imap|cgi)/)
#
#
# - Linebreaking only works for quotet text and between patterns:
#
# "Imagine this is as a \
# long text string"
#
#
#if (/^To:.*mutt/ \
# || /^[Cc][Cc]:.*mutt/)
#
Filter out messages for trash
File: ~/.mailfilter
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Spam messages with numbered subjects
#
if (/^Subject:.*[:wbreak:][:digit:][:digit:][:digit:][:digit:][:wbreak:]/ \
&& !/^Precedence: bulk/:h)
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# What we can find in the header
if ( /^X-Advertisement:.*/ \
|| /^X-Mailer:.*(Advanced Mass)/ \
|| /^X-Spam-Status: YES / \
|| /^Message-ID:*<>/:h )
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Spam addresses From:
if (/^From:.*(galamail\.com|agentoflove|absoluteagency\.com|delphi\.com|238525)/:h)
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Spam addresses To:
if (/^To:.*(spambot|undisclosed recipient)/:h )
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Long Subject spam words
# IT SHOULD BE JUST ONE LONG LINE (breaks are for wiki purpuses)
if (/^Subject:.*(SPAM|\[Vv\]iagra|offer|free|wanted|penis|chip|inch|please|pill|ydrocodone|remember|
prescription|1-800|inch|remove|XXX|sex|adults|business opportunity|unsuscribe|LANGUAGE CENTER|visit today|
penis|longer|size|GUARANTEE|\[Ll\] \[Aa\] \[Nn\] \[Gg\] \[Uu\] \[Aa\] \[Gg\] \[Ee\] )/:h )
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Trashing offtopic messages
if (/^Subject:.*(\[ot\]|\
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Trashing test messages
if (/^Subject:test$/:h)
{
exception {
to $DEFAULT/.Trash/
}
}
if (/^Subject:.*[ ]test$/:h)
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Trashing empty subjects:
if (/^subject:[ ]+$/:h)
{
exception {
to $DEFAULT/.Trash/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Trashing mails without subject lines:
if (!/^subject:/:h)
{
exception {
to $DEFAULT/.Trash/
}
}
Messages we would like to keep separate
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# .Personal
#
if ( /^From:.*(friend_1|friend_2|friend_3)/ )
{
exception {
to $DEFAULT/.Personal/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# .2root
#
if (/^Subject:.*Cron/ || /^To:.*root/ )
{
exception {
to $DEFAULT/.2root/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# .yourmailbox
#
if (/^To:.*yourmailbox/)
{
exception {
to $DEFAULT/.youmailbox/
}
}
Autoreply
Here is Rolan Yang
This is used in a completely virtual user hosted environment. A squirrelmail module add or removes this to ".mailfilter" located in the users home directory. If anyone has suggestions on improving this feel free to email me - Rolan Yang
Autoreplying adds to spam. Make sure you configure your spam filtering agent to learn and, if possible, allow users to report spam.
File: ~/.mailfilter
`test -f vacation.msg && exit 1 || exit 0`
if ($RETURNCODE==1)
{
{
if (!/^List-Unsubscribe:.*/:h )
{
if (!/^X-Spam-Flag: YES/:h )
{
RESPOND="$MAILDIR/$USER.autorespond.msg"
RESPONDDB="$MAILDIR/$USER.autorespond.db"
# The following must be one contiguous line
cc "| mailbot -t $RESPOND -d $RESPONDDB -D 1 \
-A 'From: $RECIPIENT' -s 'Auto Response: from $RECIPIENT' \
/usr/sbin/sendmail -t -f ''"
}
}
}
}
Additionally, Stefan Hornburg
File: ~/.mailfilter
/^List-Id:/ || /^Precedence: list/
[edit]mail headers manipulation
Chris Holleman
Adjust the rule for your needs.
File: ~/.mailfilter
xfilter "/usr/local/maildrop/bin/reformail -a \"X-Myheader: myheader\""
[edit]Mailing lists and Forums
File: ~/.mailfilter
####################################################################
# .mailing lists and forums
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# .gentoo-wiki
if ( /^Reply-To:.*devel@gentoo-wiki\.com/ \
|| /^Reply-To:.*users@gentoo-wiki\.com/ )
{
exception {
to $DEFAULT/.gentoo-wiki/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# .forums.gentoo-org
if (/^From:.*blackhole@forums\.gentoo\.org/ )
{
exception {
to $DEFAULT/.forums-gentoo/
}
}
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# .courier-maildrop
if (/^List-Post:.*courier-maildrop*/ )
{
exception {
to $DEFAULT/.list.courier-maildrop/
}
}
[edit]Mailbox creation and subscription
Mailbox creation and subscription
You have to create mailboxes for every single destination (without it it will complain)
maildirmake -f Folder.Name $HOME/.maildir
And subscribe for the new mailfolder
echo INBOX.Folder.Name >> $MAILDIR/courierimapsubscribed
[edit]postfix integration
You have to let postfix know that we have local derlivery agent, so
vim /etc/posfix/main.cf
# The mailbox_command parameter specifies the optional external
# command to use instead of mailbox delivery. The command is run as
# the recipient with proper HOME, SHELL and LOGNAME environment settings.
# Exception: delivery for root is done as $default_user.
#
# Other environment variables of interest: USER (recipient username),
# EXTENSION (address extension), DOMAIN (domain part of address),
# and LOCAL (the address localpart).
#
# Unlike other Postfix configuration parameters, the mailbox_command
# parameter is not subjected to $parameter substitutions. This is to
# make it easier to specify shell syntax (see example below).
#
# Avoid shell meta characters because they will force Postfix to run
# an expensive shell process. Procmail alone is expensive enough.
#
# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
#
#mailbox_command = /some/where/procmail
#mailbox_command = /some/where/procmail -a "$EXTENSION"
#
# You ARE NOT specifying the binary here. You are specifying the maildrop service.
# This is defined in master.cf which is where the path to the maildrop binary
# is defined.
#
mailbox_command = maildrop
# For virtual mail servers
virtual_transport = maildrop
## Set to 1 because Maildrop only delivers one message at a time.
maildrop_destination_recipient_limit = 1
vim /etc/postfix/master.cf i have it in line # 113
File: /etc/postfix/master.cf
maildrop unix - n n - - pipe
# next 2 lines should be joined!
flags=DRhu user=vmail:vmail argv=/usr/bin/maildrop -w 90 -d } \
${recipient} ${user} ${nexthop} ${sender} ## This needs to be part of the above line!
#
# Question
#
# So what does maildrop do with all of these variables that Postfix passes on to it? Well,
# first we need to understand what those variables are. While the variables look somewhat
# redundant, this provides the ultimate in filtering flexibility.
#
# -w 90 is telling maildrop to send a quota warning to users with 90% of quota used up
# -d is telling maildrop to run as user as specified by user=x:x
# ${user} is comprised of everything before the @ symbol in the recipient's email address.
# ${nexthop} is the domain; everything after the @ symbol in the recipient's email address.
# ${recipient} is nothing more than }
# ${sender} is complete email address of the sender
#
# Answer
#
# When Postfix passes the message to maildrop, maildrop, by default, looks for /etc/maildroprc
# and reads it. At the top of this file, you should use the maildrop command "import" to
# import the variables Postfix is passing so that you can utilise them for your filtering needs.
# For general purposes, $recipient is sufficient. In addition,
# I must put this, or something similar, in the maildropfilter:
# xfilter "reformail -I 'X-Panix-Recipient: $1'"
Restart postfix after configuration change
/etc/init.d/postfix restart
[edit]Qmail integration
add ~/.qmail file inside user mailbox folder with following:
| /usr/bin/maildrop /mail/domains/userdomain.foo/username/.mailfilter
and
~/.mailfilter file with maildrop commands
[edit]Scanning for Viruses and Spam
Scanning for viruses with ClamAV
if (`/usr/bin/clamdscan --no-summary --stdout - | grep -c 'FOUND'` == 1)
{
MAILDIR="$MAILDIR/.Quarantine"
`test -f $MAILDIR/maildirsize && exit 1 || exit 0`
if ( $RETURNCODE == 0 )
{
`maildirmake $MAILDIR`
}
to "$MAILDIR";
}
exception {
VIRUS_TAG=`clamscan -V`
VIRUS_TAG="$VIRUS_TAG on $HOSTNAME"
xfilter "reformail -A 'X-Virus-Checker-Version: $VIRUS_TAG'"
xfilter "reformail -A 'X-Virus-Status: Clean'"
}
You may also use clamassassin, which trys to act like SpamAssassin. Clamassassin still requires that ClamAV be installed and spamd must be running as a daemon.
Scanning for Spam with Spam Assassin
if ( $SIZE < 26144 )
{
exception {
xfilter "spamc -u $RECIPIENT"
}
}
if ( (/^X-Spam-Flag: YES/:h) || (/^X-Spam-Status: Yes/:h) )
{
#
# Run sa-learn: Learn as spam
#
if ( /^X-Spam-Level: *-----.*$/:h )
{
cc "| sa-learn --sync --spam"
}
MAILDIR="$MAILDIR/.Spam"
log "$TICKS : >>> TAGGED AS *** SPAM ***"
#
# deliver to maildir
#
log "$TICKS : >>> Mail successfully delivered to $MAILDIR"
exception {
to "$MAILDIR";
}
}
else
{
if ( /^X-Spam-Level: *-.*$/:h )
{
#
# Run sa-learn: Learn as ham
#
cc "| sa-learn --sync --ham"
}
}
[edit]Troubleshooting
[edit]Invalid home directory permissions - world writable.
Delivery error (command maildrop 24688 error (75, /usr/bin/maildrop:
Invalid home directory permissions - world writable.))
msg 1/1 (812 bytes), delivery error (command maildrop 24688 error (75, /usr/bin/maildrop:
Invalid home directory permissions - world writable.))
1 messages retrieved, 0 skipped
the fix
chmod 600 ~/.mailfilter
[edit]For your own good
Delivery error (command maildrop 5485 error (75, /usr/bin/maildrop: Cannot have world/group permissions on the filter file - for your own good.))
msg 1/1 (842 bytes), delivery error (command maildrop 5485 error (75, /usr/bin/maildrop:
Cannot have world/group permissions on the filter file - for your own good.))the fix
Get rid of [arguments] line in ~/.getmail/youmailbox.rc file
[edit]Unable to create a dot-lock
msg 1/1 (3612 bytes), delivery error (command maildrop 10143 error
(75, /usr/bin/maildrop: Unable to create a dot-lock.))
1 messages retrieved, 0 skipped
When maildrop is told to route a message into a directory, it tries to create a "dot-lock" file within that directory, as a signal to tell other processes that the directory is being maintained and that they should wait for this maintenance to finish before trying to make any changes within the directory. After the message has been delivered, this dot-lock file is deleted so that other processes can work with the directory as needed.
If the directory does not exist, or if maildrop doesn't have permission to create files in the directory, you will see the Unable to create a dot-lock error message.
The fix, of course, is to create the directory and make sure it is owned by (or has permissions which make it writable by) the same userid which maildrop will be running as, which will almost always be the userid which owns the mailbox itself.
Of course, finding out which directory of which user maildrop is complaining about can be quite a challenge, since the error message fails to tell you. If you have users with extremely complex maildrop files this can be near impossible.