Friday, October 24, 2008

Stop undeliverable spoofed spam using maildrop and PHP

A common problem among email providers is the growing practice of spammers using legitimate email addresses in the From: header of their messages, which means that unsuspecting users get flooded with potentially thousands of undeliverable messages due to the fact that many of the To: addresses on the spammers' lists are no longer valid.
A few of our customers had this issue, so I devised a quick way to filter out the undeliverable messages via Maildrop and php.

1. Set Postfix to pass mail through Maildrop

After installing maildrop (it should be readily available in your *nix distro's packaging system) Make sure Postfix is set up to pass mail to Maildrop by putting the following line in your master.cf file:

maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} ${recipient}

(Note: adjust maildrop according to your environment - see http://www.postfix.org/MAILDROP_README.html)

2. Place the following code in /usr/local/etc/mail/maildrop_filters.php


ini_set('display_errors', 'off');
error_reporting(0);

//---------------------------------------

$recipients = array(
'recipient1@domain1.com',
'recipient2@domain2.com'
);


$bad_subjects = array(
'Undelivered Mail',
'Delivery Status Notification',
'Undeliverable mail',
'Returned Mail',
'Delayed Mail',
'Delivery Failure',
'Warning: could not send message',
'Warning: message'
);

//---------------------------------------
// Don't edit below here
//---------------------------------------
$sender_address = $argv[1];
$recipient_address = $argv[2];

$stdin = fopen('php://stdin', 'r');
$msg = '';
$header = '';

while ( $buf = fread($stdin, 500) ) {
$msg .= $buf;
}

$msg_lines = explode("\n", $msg);

if ( is_array($msg_lines) ) {
foreach( $msg_lines as $cur_line ) {

$cur_line = trim($cur_line);

if ( $cur_line == '' ) {
break;
}

$header .= $cur_line . "\n";

}
}

foreach( $recipients as $recipient ) {

if ( preg_match('/^To\:\s*\

foreach( $bad_subjects as $subj ) {

if ( preg_match("/^Subject:\s*" . preg_quote($subj) . "/im", $header) ) {
exit(1);
}
}
}
}

echo $msg;
exit(0);

?>


3. Add the following to your maildroprc file, which will probably be in /etc, /etc/mail, or /usr/local/etc/:


RECIPIENT_ADDRESS="$1"

exception {
xfilter "/usr/local/bin/php /usr/local/etc/mail/maildrop_filters.php \"${SENDER}\" \"${RECIPIENT_ADDRESS}\""
}

if ( $RETURNCODE == 1 )
{
log "${OUTER_INDENT} Message for ${RECIPIENT_ADDRESS} discarded. Returncode was ${RETURNCODE}"
EXITCODE=0
exit
}



4. Edit the $recipients array

Go back into /usr/local/etc/mail/maildrop_filters.php and edit the $recipients array as necessary - this is where you put the addresses that are being bombarded with the undeliverable mail messages:

$recipients = array(
'recipient1@domain1.com',
'recipient2@domain2.com',
'recipient3@domain3.com',
);


Additionally, you can add or remove subjects from the $bad_subjects array as required. Note that the filter matches subjects that *start* with the items listed in $bad_subjects, so "Undeliverable:" will match "Undeliverable: Mailbox not found" and "Undeliverable: Mailbox is full", and so on.

1 comment:

Anonymous said...

酒店經紀PRETTY GIRL 台北酒店經紀人 ,禮服店 酒店兼差PRETTY GIRL酒店公關 酒店小姐 彩色爆米花酒店兼職,酒店工作 彩色爆米花酒店經紀, 酒店上班,酒店工作 PRETTY GIRL酒店喝酒酒店上班 彩色爆米花台北酒店酒店小姐 PRETTY GIRL酒店上班酒店打工PRETTY GIRL酒店打工酒店經紀 彩色爆米花