Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 May 1997 22:26:34 +0200
From:      Poul-Henning Kamp <phk@dk.tfs.com>
To:        isp@freebsd.org
Subject:   stopping mailspam without tears...
Message-ID:  <1057.865023994@critter.dk.tfs.com>

next in thread | raw e-mail | index | archive | help

A local ISP here had the problem that they were being used as a 
relay for various mail-spammers.

Here is a summary of the solution I am implementing.

The reason I think it is interesting is that it doesn't involve 
sendmail.cf :-)

Life is too short for sendmail.cf.

If anybody has the time to work on this to make it a suitable
option in /etc/sysconfig for freebsd...  nudge, nudge, wink, wink!

Poul-Henning

Cookbook:
---------

Make a directory /var/spool/mqueue_in, set owner, group & modes right.

Start sendmail with 

	-bd -O QueueDirectory=/var/spool/mqueue_in -O DeliveryMode=q

this makes sendmail store all incomming mail in your new directory
instead of delivering it.

Start another sendmail with
	-q5m
or similar.

Now write a small script in a language of your choice, which looks
at the qf* and df* files in /var/spool/mqueue_in and if you like the
contents, you move them to /var/spool/mqueue for delivery.

The format of the qf* files are descibed in Appendix B in
src/usr.sbin/sendmail/doc/op/op.me

TADA!

Yes, I know all the drawbacks of this scheme, but I can make checks
this way that none of the sendmail patches I have seen yet allows
me to do.

You can check all recipients all header lines and envelope information,
and you even have access to the message itself, at the same time!

Emails from spammers will just be /dev/nulled.

I include my (Tcl!) script here for all to work from 

#!/usr/bin/tclsh
#
# ----------------------------------------------------------------------------
# "THE BEER-WARE LICENSE" (Revision 42):
# <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
# ----------------------------------------------------------------------------
#
# $Id$
#

set spool_in            /var/spool/mqueue_in
set spool_out           /var/spool/mqueue
set spool_spam          /var/tmp/spam
set spool_problem       /var/spool/mqueue_problem

#################

proc Process {id qf df} {
    global spool_in spool_out spool_spam spool_problem
    set f [open $qf]

    if {![file size $qf]} {
        if {[file mtime $qf] + 600 < [clock seconds]} {
            puts "$id Stale zero size queue file"
            MoveTo $id $spool_problem
        }
        return
    }
    set rcount 0
    set triggers 0
    while {[gets $f a] >= 0} {
        # We can risk seing anything in these, so be carefull
        if {[regexp {^HSubject: } "$a"]} continue
        if {[regexp {^HX} "$a"]} continue

        # Count recipients
        if {[regexp {^R} "$a"]} {incr rcount}

        # Look for telltale signs
        if {[regexp {^HReceived.*000\.000\.000\.000} "$a"]} {incr triggers}
        if {[regexp {@savetrees\.com} "$a"]} {incr triggers}
        if {[regexp {@fun\.com} "$a"]} {incr triggers}
        if {[regexp {@public\.com} "$a"]} {incr triggers}
        if {[regexp {@mary-world\.com} "$a"]} {incr triggers}
        if {[regexp {Received: from "Cyber-Bomber"} "$a"]} {incr triggers}
        if {[regexp {Received: .*sallynet\.com} "$a"]} {incr triggers}
        if {[regexp {Received: .*marynet\.com} "$a"]} {incr triggers}
        if {[regexp {earthlink\.net} "$a"]} {incr triggers}
            
    }
    close $f
    puts "$id $rcount $triggers"
    if {$rcount > 10 && $trigger} {MoveTo $id $spool_spam}
    MoveTo $id $spool_out
}

#################

proc MoveTo {id where} {
    global spool_in
    puts "moving $id to $where"
    exec sh -c "mv $spool_in/??$id $where"
}

#################

while 1 {
    set list [glob -nocomplain $spool_in/qf*]
    if {![llength $list]} {
        exec sleep 30
    } else {
        foreach i $list {
            puts "doing $i"
            regsub "$spool_in/qf(.*)" $i {\1} b
            if {[file exists $spool_in/tf$b]} continue
            if {![file exists $spool_in/qf$b]} continue
            if {![file exists $spool_in/df$b]} continue
            set error [catch "Process $b $spool_in/qf$b $spool_in/df$b" ret]
            if {$error} {
                puts "ERROR ON ID $b MOVED TO PROBLEM"
                puts "$error"
                puts "$ret"
                MoveTo $b $spool_problem
            }
        }
        exec sleep 10
    }
}

--
Poul-Henning Kamp           | phk@FreeBSD.ORG       FreeBSD Core-team.
http://www.freebsd.org/~phk | phk@login.dknet.dk    Private mailbox.
whois: [PHK]                | phk@tfs.com	    TRW Financial Systems, Inc.
Future will arrive by its own means, progress not so.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1057.865023994>