Synopsis
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 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...
According to Maildrop documentation, only one file needs to be modified for your installation (maildroprc is an optional file). However, [[vMail.Admin]] does make use of maildroprc, the first file Maildrop looks for when invoked by Postfix, or any other method. The values presented should only be used as examples.
Flowchart
Internet -> Postfix -> Maildrop -> Mailbox Delivery -> INBOX (or alternate mailbox)
^ ^
| |
| <--> SpamAssassin
DSPAM <--> |
<--> ClamAV (via clamassassin)
The beauty of Maildrop is that it can interpret shell commands so that you can handle email with nearly endless possibilities. [[vMail.Admin]] is unique in that is creates customized Maildrop scripts for users. [[vMail.Admin]] supports [[HOWTO_SpamAssassin|SpamAssassin?]] and [[HOWTO_ClamAV|ClamAV]] (clamassassin must be installed) at global, domain and user levels. [[vMail.Admin]] also supports DSPAM filtering and retraining.
To learn more about the Maildrop filtering language, please read the maildropfilter documentation.
Installation
Maildrop is a core dependancy of [[vMail.Admin]].
Compile maildrop with the following compile time options (minimum):
./configure --enable-maildirquota --enable-use-dotlock=1 --with-default-maildrop=./.maildir/ --enable-sendmail=/usr/sbin/sendmail --with-db=db
Additionally, for 2.x versions of maildrop, be sure to have [[HOWTO_Courier-IMAP|Courier-Authlib]] installed prior to installing. In order for maildrop to be able to do SQL lookups, the configure script must detect courier auth libraries otherwise it will default to file based databases.
Gentoo users
USE="authlib berkdb mysql postgres" $ emerge mail-filter/maildrop
Post installation
Files to be modified: * /etc/maildrop/maildropmysql.cf (deciated as of Maildrop 2.0) * /etc/maildroprc (create if it does not exist)
Verify that Maildrop compiled with the following:
$ maildrop -v maildrop 2.0.2 Copyright 1998-2005 Double Precision, Inc. GDBM extensions enabled. Courier Authentication Library extension enabled. Enabled Berkeley DB instead of GDBM extensions. Maildir quota extension enabled. This program is distributed under the terms of the GNU General Public License. See COPYING for additional information.
maildropmysql.cf
This file is only applicable for versions of Maildrop 1.x. In other words, if you are running any version 1.x, this file must be present. Maildrop 2.x uses Courier Authentication Libraries for database lookups and no longer needs this file. {{Box File|/etc/maildrop/maildropmysql.cf|
# # File: /etc/maildrop/maildropmysql.cf # hostname localhost port 3306 socket /var/run/mysqld/mysqld.sock database postoffice dbuser postfix dbpw **SECRET** dbtable mailbox default_uidnumber 5000 default_gidnumber 5000 default_quota 1048576000S uid_field pobox uidnumber_field uid gidnumber_field gid maildir_field maildir homedirectory_field homedir quota_field quota mailstatus_field postfix where_clause AND postfix = 'y'
}}
maildroprc
<span style="font-size:14px;font-weight:bold;">AKA: vMail.Admin:maildroprc</span>, This script has been assigned the psuedo package name of vMail.Admin:maildroprc.
maildrop does not require /etc/maildroprc to exist, however, it IS required [[vMail.Admin]] as it so it is very important that we create this file and place it in /etc. It is safe to copy and paste it but it is still suggested that you review it for consistancy.
If you plan to enable DSPAM, in addition to vMail.Admin:maildroprc you need [[HOWTO_DSPAM#DSPAM_re-training|.dspam]] placed into the home directory (not mail directory) of your global retraining alias.
This script changes with every release of [[vMail.Admin]]. Please check back to review changes and to decide whether it is relevant to your installation.
Last Update: 19 January 2007
{{Box File|/etc/maildroprc|
# $Id: /etc/maildroprc, (maildrop 2.x) 19/01/2007 juan Exp $
#
################################################################################
# #
# This script is free software for use with vMail.Admin. This script heeds #
# the same copyright as Maildrop and vMail.Admin, the software it requires. #
# #
# For more information, please visit the official Maildrop and vMail.Admin #
# websites or see COPYING (included in the Maildrop source code) and #
# README.txt (included with the vMail.Admin source code) for additional #
# information. #
# #
################################################################################
#
# Psuedo Package: vMail.Admin:maildroprc 2.0
# Author: Juan González <juan_at_gjtech_dot_net>,
# <juan_at_vmailadmin_dot_org>
# Placement: /etc/maildroprc
#
# This is the required, approved maildroprc script to be used for vMail.Admin. Once invoked,
# this script performs the following:
#
# 1. Include custom user mail filters
# 2. SpamAssassin content scanning (spam)
# 3. DSPAM re-training, delivery to .Spam box (spam)
# 4. ClamAV message scanning (for virus)
# 5. Rewrite empty subjects
# 6. Clean up PGP/MIME headers
# 7. Deliver to mailbox (final task)
#
# Script NOTICE:
#
# It is suggested to use this script without modifications and, as such, no support
# will be given for modified vMail.Admin:maildroprc scripts. However, you are free
# to modify to support your environment. Do so only if you know the maildropfilter
# language (similar to bash but not quite).
#
# Postfix NOTICE:
#
# This script depends on a special parameter (the variable '$CLASS') when invoked by Postfix. This
# parameter is unique to this script and functions as the variable that defines the type of domain
# (system or virtual) the message is being processed for and builds the proper full, path to the
# recipient's mailbox for delivery. This prevents the mailbox path from being wrong and leaving
# dotlocks in Postfix's queue. Maildrop does not have restrictions on what command line options are
# passed to it which is why this method was chosen for DSPAM retraining. This script will not train
# a corpus of mail.
#
# DSPAM NOTICE:
#
# For DSPAM spam filtering, this script assumes DSPAM was invoked as content filter from Postfix,
# scanned, tagged with DSPAM headers and reinjected for delivery (does not apply to DSPAM
# re-training). Presently, this script will not enable/disable nor handle actual content scanning
# with DSPAM, only retraining tasks. In other words, if you want spam tagged by DSPAM to be filtered
# into your .Spam folder, it must be scanned by Postfix before delivery to Maildrop.
#
# General NOTICE:
#
# 1. This script is completely untested with Maildrop 1.x.
# 2. This script no longer 'teaches' SpamAssassin (autolearn feature)
#
# <!------------------------------------------------------------->
# <!----- ----->
# <!----- Begin administrator configuration variables ----->
# <!----- ----->
# <!------------------------------------------------------------->
#
# System user home directory
#
# Path to system user home directories (usually /home)
# This does not define path to .maildir
#
SYSTEM_USER_HOMEDIR = "/home"
#
# Virtual user home directory
#
# Path to virtual user home directories (ex: /home/vmail)
# This does not define path to .maildir
#
VIRTUAL_USER_HOMEDIR = "/home/vmail"
#
# Enable Spam Scanning
#
# This option toggles spam filters (SpamAssassin and/or DSPAM)
#
# NOTE: vMail.Admin supports filtering spam based on the following headers (case insenstive):
#
# X-Spam-Flag: yes -> SpamAssassin header tag
# X-DSPAM-Result: spam -> DSPAM header tag
#
ENABLE_SPAM_FILTER = 1
#
# Enable SpamAssassin
#
# This option will enable use of SpamAssassin
#
ENABLE_SPAMASSASSIN = 1
#
# Enable DSPAM
#
# This option will enable use of DSPAM
#
# Enabling this option requires an include in your DSPAM
# global user's home directory. The file must be named .dspam
#
# If you do not implement DSPAM, simply set this to 0
#
# Ex: /home/globaluser/.dspam
#
ENABLE_DSPAM = 1
#
# DSPAM Mode
#
# Enable this option if you are running DSPAM in client/server mode
#
DSPAM_MODE = 1
#
# DSPAM training user
#
# This user must be present in dspam.conf. Setting to an empty value will cause the current
# user to invoke training.
#
# Ex: Trust globaluser
#
DSPAM_TRUST_USER = ""
#
# DSPAM (re)training alias
#
# Define the alias used to train DSPAM
#
# The default would skip all SpamAssassin checks if recipient address is:
# 1. spam-train@mydomain.tld
# 2. ham-train@mydomain.tld
#
# This parameter is directly related to the next 2 parameters:
# 1. $FN_ALIAS
# 2. $FP_ALIAS
#
# This is tricky to explain but the idea here is that you have 2 training aliases, one for
# spam and one for ham. This should not have the words (or related alias words) spam nor
# ham.
#
DSPAM_ALIAS = "-retrain@"
#
# False negative alias (when spam makes it to inbox)
#
# This variable is appended to $DSPAM_ALIAS to complete the false negative alias used to
# set the class (spam or innocent) variable. This should contain the word (or related
# alias word) spam.
#
FN_ALIAS = "spam$DSPAM_ALIAS"
#
# False positive alias (when legitimate mail is tagged as spam)
#
# This variable is appended to $DSPAM_ALIAS to complete the false positive alias used to
# set the class (spam or innocent) variable. This should contain the word (or related
# alias word) ham.
#
FP_ALIAS = "ham$DSPAM_ALIAS"
#
# Enable Virus Scanning
#
# This option toggles virus filters (ClamAV)
#
# NOTE: vMail.Admin supports filtering viruses based on the following header:
#
# X-Virus-Flag: yes -> Default ClamAV header tag
# X-Virus-Flag: virus -> Patched clamassassin header tag
#
ENABLE_VIRUS_FILTER = 1
#
# Enable ClamAV
#
# This option will enable use of ClamAV (clamassassin required)
#
ENABLE_CLAMAV = 1
#
# Enable logging
#
# This option will enable Maildrop's logging system
#
ENABLE_LOGGING = 1
#
# Enable subject rewrite
#
# This option will enable subject rewrite for empty subject lines
#
ENABLE_SUBJECT_REWRITE = 1
#
# Subject rewrite text
#
# Text to rewrite empty subject lines with
#
# NOTE: vMail.Admin supports filtering for empty subjects AND 'no subject'
# (case insensitive and without quotes). Default value is supported.
#
SUBJECT_REWRITE = "(No Subject)"
#
# Paths to executables (do not include trailing slash)
#
# Examples:
# Good: /usr/bin/program
# Bad: /usr/bin/program/
#
SENDMAIL = "/usr/sbin/sendmail"
MAILDROP = "/usr/bin/maildrop"
FORMAIL = "/usr/bin/reformail"
SPAMC = "/usr/bin/spamc"
DSPAM = "/usr/bin/dspam"
CLAMASSASSIN = "/usr/bin/clamassassin"
#
# Paths to system tools executables (do not include trailing slash)
#
# Examples:
# Good: /usr/bin/program
# Bad: /usr/bin/program/
#
SHELL = "/bin/ash"
TEST = "/usr/bin/test"
#
# Path to log directory (do not include trailing slash)
#
# Examples:
# Good: /var/log/file
# Bad: /var/log/file/
#
LOGDIR = "/var/log/maildrop"
# <!------------------------------------------------------------->
# <!----- ----->
# <!----- End administrator configuration variables ----->
# <!----- NO CHANGES PAST THIS MARKER ----->
# <!----- ----->
# <!------------------------------------------------------------->
#
# Import environment variables, passed from Postfix
#
# @integer CLASS 0 = system user (from main.cf)
# 1 = virutal user (from master.cf)
# Guarantees build of correct maildir path
# @string USER Everything preceeding the @
# @string DOMAIN Everything succeeding the @
# @string SENDER Sender of message
# @string RECIPIENT Build full email address from $USER and $DOMAIN
#
CLASS = "$1"
USER = tolower("$2")
DOMAIN = tolower("$3")
SENDER = tolower("$4")
RECIPIENT = "$USER@$DOMAIN"
#
# Set up default base directory
#
DEFAULT = "$SYSTEM_USER_HOMEDIR/$USER"
if ( $CLASS == 1 )
{
DEFAULT = "$VIRTUAL_USER_HOMEDIR/$DOMAIN/$USER"
}
#
# Set date/time
#
TIME = `date "+%b %e %H:%M:%S"`
#
# Set .clamassassin include
#
# Located in the virtual users home directory, by domain (including system domain)
#
INCLUDE_CLAMAV = "$VIRTUAL_USER_HOMEDIR/$DOMAIN/.clamassassin"
#
# Set .dspam include
#
# Located in the DSPAM 'global' user's home directory
#
INCLUDE_DSPAM = "$DEFAULT/.dspam"
#
# Set .mailfilter include
#
# Located in the user's home directory and unique to every user
#
INCLUDE_CUSTOM_FILTER = "$DEFAULT/.mailfilter"
#
# Tag header with maildrop stuff
#
MDA_VERSION = `$MAILDROP -v |grep maildrop`
MDA = "$MDA_VERSION on $HOSTNAME"
xfilter "$FORMAIL -A 'X-Delivery-Agent: $MDA'"
#
# Set PGP/MIME variables
#
BPM = "--BEGIN PGP MESSAGE--"
EPM = "--END PGP MESSAGE--"
BPS = "--BEGIN PGP SIGNATURE--"
EPS = "--END PGP SIGNATURE--"
#
# Get subject, store to variable
#
PARSE_SUBJECT = `$FORMAIL -x Subject:`
#
# Enable log writing if logging is enabled
#
if ( $ENABLE_LOGGING == 1 )
{
logfile "$LOGDIR/maildrop.log"
log "<!----------------------- LEGEND ---------------------------->"
log "<! (**) from config file, (II) informational, (WW) warning >"
log "<!----------------------------------------------------------->"
log "(II) $TIME : <!------- BEGIN Filtering for $RECIPIENT ------->"
log "(II) $TIME : <!------- Sender: $SENDER ------->"
if ( !$RECIPIENT )
{
log "(WW) $TIME : <!------- \$RECIPIENT variable empty, assuming no recipient ------->"
log "(WW) $TIME : <!------- Terminating without delivery ------->"
exit
}
}
#
# If SENDER is null, set SENDER to whatever
#
if ( !$SENDER )
{
SENDER = "<Unknown Sender>"
if ( $ENABLE_LOGGING == 1 )
{
log "(WW) $TIME : <!------- Empty Subject, setting to $SENDER ------->"
}
}
#
# Correct signature dashes
#
if (/^--($|[ ]{2,}^)/:b)
{
exception {
xfilter "sed -r 's/^--($|[ ]{2,}^)/-- /'"
if ( $ENABLE_LOGGING == 1 )
{
log "(WW) Signature Dashes corrected"
}
}
}
#
# SpamAssassin Filtering (as 2nd pass spam filtering)
# DSPAM Re-Training
#
if ( $ENABLE_SPAM_FILTER == 1 )
{
#
# DSPAM Re-Training
#
# The .dspam file should be located in the home directory (not .maildir)
# of the trusted user that will execute all dspam retraining functions.
# This method supports only one, global user.
#
if ( $ENABLE_DSPAM == 1 )
{
`$TEST -f $INCLUDE_DSPAM && exit 1 || exit 0`
if ( ($RETURNCODE == 1) && ($ENABLE_DSPAM == 1) )
{
exception {
include "$INCLUDE_DSPAM"
if ( $ENABLE_LOGGING == 1 )
{
log "(II) $TIME : <!------- @included($INCLUDE_DSPAM) ------->"
}
}
}
else
{
if ( $ENABLE_LOGGING == 1 )
{
log "(WW) $TIME : <!------- DSPAM include is unavailable. Most likely not the DSPAM global user. ------->"
}
}
}
#
# 1st pass spam scan:: DSPAM (assumed analyzed by MTA )
# 2nd pass spam scan:: SpamAssassin, if DSPAM header says it's innocent
#
if ( (!/^X-DSPAM-Result: Spam/:h) && (!/^To:.*${DSPAM_ALIAS}.*/:h) && ($ENABLE_SPAMASSASSIN == 1) )
{
exception {
xfilter "$SPAMC -u $RECIPIENT"
if ( $ENABLE_LOGGING == 1 )
{
log "(II) $TIME : <!------- xfilter -> $SPAMC -u $RECIPIENT ------->"
}
}
}
#
# DSPAM extras
#
# These options are not yet used. They might not even be needed.
#
if ( ($ENABLE_DSPAM == 1) && (/^X-DSPAM-Result: Spam/:h) )
{
#LOGGER = "/usr/bin/logger"
#FACILITY = "mail.info"
#${LOGGER} -i -p ${FACILITY} -t dspamd dspamd: identified spam
#xfilter "$FORMAIL -I 'Subject: *** SPAM *** $PARSE_SUBJECT'"
#if ( $ENABLE_LOGGING == 1 )
#{
#log "(II) $TIME : <!------- Marking message as spam ------->"
#}
}
}
else
{
if ( $ENABLE_LOGGING == 1 )
{
log "(**) $TIME : <!------- Spam Scanning Disabled ------->"
}
}
#
# Does domain have virus scanning enabled? Check for
# .clamassassin file
#
if ( $ENABLE_CLAMAV == 1 )
{
`$TEST -f $INCLUDE_CLAMAV && exit 1 || exit 0`
if ( $RETURNCODE == 1 )
{
exception {
include "$INCLUDE_CLAMAV"
if ( $ENABLE_LOGGING == 1 )
{
log "(II) $TIME : <!------- @included($INCLUDE_CLAMAV) ------->"
}
}
}
else
{
if ( $ENABLE_LOGGING == 1 )
{
log "(WW) $TIME : <!------- ClamAV include is unavailable ------->"
}
}
}
#
# Add missing headers for PGP/MIME
#
if ( !/^Content-Type: (message|multipart|application\/pgp)/:h )
{
if ( (/^$BPM/:b) && (/^$EPM/:b) )
{
xfilter "$FORMAIL -A 'Content-Type: application/pgp; format=text; x-action=encrypt'"
if ( $ENABLE_LOGGING == 1 )
{
log "(WW) $TIME : <!------- Corrected PGP/MIME Headers (BPM/EPM) ------->"
}
}
if ( (/^$BPS/:b) && (/^$EPS/:b) )
{
xfilter "$FORMAIL -A 'Content-Type: application/pgp; format=text; x-action=sign'"
if ( $ENABLE_LOGGING == 1 )
{
log "(WW) $TIME : <!------- Corrected PGP/MIME Headers (BPS/EPS) ------->"
}
}
}
#
# Reformat empty subjects for including custom user filters
#
if ( $ENABLE_SUBJECT_REWRITE == 1 )
{
if ( !$PARSE_SUBJECT )
{
xfilter "$FORMAIL -I 'Subject: $SUBJECT_REWRITE'"
if ( $ENABLE_LOGGING == 1 )
{
log "(II) $TIME : <!------- Reformatting empty subject ------->"
}
}
}
#
# Check for custom user .mailfilter file
#
`$TEST -f $INCLUDE_CUSTOM_FILTER && exit 1 || exit 0`
if ( $RETURNCODE == 1 )
{
exception {
include "$INCLUDE_CUSTOM_FILTER"
if ( $ENABLE_LOGGING == 1 )
{
log "(II) $TIME : <!------- @included($INCLUDE_CUSTOM_FILTER) ------->"
}
}
}
else
{
if ( $ENABLE_LOGGING == 1 )
{
log "(WW) $TIME : <!------- Custom filter include is unavailable ------->"
}
}
#
# If no matches are made, deliver to INBOX
#
MAILDIR = "$DEFAULT/.maildir"
if ( $ENABLE_LOGGING == 1 )
{
log "(II) $TIME : <!------- FINAL DESTINATION => $MAILDIR ------->"
}
to "$MAILDIR"
exit
#
# EOF
#
}}
Final Notes
Maildrop is a highly configurable mail delivery agent. While the scripts provided here are required for [[vMail.Admin]], feel free to modify the script only if you know the maildrop filtering language. Just remember to make a backup of the file before you start toying with it in case you break it.
DO NOT DISABLE LOGGING. Instead, set up log rotation.
To verify Maildrop authenticates against your database, run:
$ /usr/bin/maildrop -V 10 -d someuser@somedomain.com
