Known Senders Database

Avoid spam by using a soft error (4xx) on any sender not known to you. Sent up a senders file that contains all of the senders that you accept. I made this very similar to the standard access database. You must have check_mail in your current sendmail see using check_* in sendmail.

sendmail.cf changes

Make a senders database definition:
# Senders list database (for spam stomping)
Ksenders dbm -o /etc/mail/senders
Now add in a Local_check_mail rule. Remember sendmail only accepts tabs and not spaces between the left hand rewrite rule and the the right hand action.
SLocal_check_mail
# R<>                 $@
R<>                   $#error $@ 4.1.8 $: "451 looks like spam"
R<$+>                 $1
R$+                   $: <$(senders $1 $:NOMATCH $)> $1
R<NOMATCH> $+ @ $+    $: <$(senders @$2 $:NOMATCH $)> $1@$2
R<NOMATCH> $+         $#error $@ 4.1.8 $: "452 no space left on device"
R<REJECT> $+          $#error $@ 5.2.1 $: "550 delivery disabled for this sender"
R<OK> $+              $@
R<TEMP> $+            $@
R<$+> $+              $#error $@ 5.7.1 $: $1          error from senders db

This also drops the null sender, but this breaks DSN. If you don't like that, uncomment the first line after SLocal_check_mail and then comment out the next line, that has "looks like spam" on it. This will let more spam through however. I don't care that DSN is broken for me.
Any one not in the sender file with an OK or TEMP will get the bogus error 452 no space left on device, and will try again later. If they have the keyword REJECT the will be hard rejected.
Now make the /etc/mail/senders file. Here is an example, remember to do the makemap dbm senders < senders too.
user@example.com	OK
spamer@yahoo.com	REJECT
@evilspammer.com	REJECT
@myfriends.com		OK
badboy@myfriends.com	REJECT
soft@err.org		452 try again later
hard@err.org		550 get lost
This accepts mail from the user user@example.com, and anyone from the domain myfriends.com with the exception of badboy@myfriends.com which gets a hard error. Also all senders from the domain evilspammer.com as well as the user spamer@yahoo.com get a hard error to go away. You can also make custom error messages for specific users if you'd like, see the last two lines. Now all other email senders get a bogus error telling them you are out of disk space so try again later. You don't need to put in a REJECT for the spammers as they will never get past unless their is an OK (or TEMP).
Now adding the email senders you want maybe tedious. So I process the mail log looking for the "no space on left device" messages, extract the email address and automatically add it to the senders list, but with the TEMP tag instead of the OK tag. This will let the email through on the next try just like an OK. But once a day I go through and remove all the TEMP lines from the senders file. That way, retries get through but only for that day. It also keeps the senders file small.

Since this is very dependant as to where the log file is located and it's format, this is left as an excersize to the reader. But a simple sample script for a unix box is as such:
#!/bin/sh
set -a
PATH=/usr/bin:/usr/sbin:/sbin:/usr/local/bin
LOG=/var/log/syslog
cd /etc/mail
tail -1f $LOG | while read a
do
	echo "$a" | grep 'no space left on device' > /dev/null 2>&1
	if [ $? -eq 0 ]
	then
		sender=`echo "$a" | sed 's/.*<//;s/>.*//'`
		echo "$sender	TEMP" >> senders
		makemap dbm senders < senders
	fi
done &


Why does this block spam? It doesn't block all of it, but it helps a lot. It seems much spam comes from mailers that don't retry and upon the first error they go away. Legit mailers always retry, but some spam does as well, like those inititing out of hotmail.

You need not have any permanent users in the senders database if you are adding in TEMP users dynamically. It will only delay legit incoming mail by 5 to 15 minutes (it depends on the senders mail configuration) for the first incomming message per sender. You can then clear them out daily or weekly.

Note: Out of all the legit mailers I have found americawest (the airline) does not retransmit on soft errors (which is a mistake on their part) so if you use them it'd be a good idea to add
@americawest.com	OK
permamnently. But now all spammers have to do is say they are from americawest to get through, but they probably won't. Also americawest uses the return domain of awavweb.com on some email they send, which does not exist, so it would not even have gotten past the standard sendmail anti-spam before the verisign wildcard of .com anyway. As a whole their email system makes them look like a spam setup, they really need a new IT department. Probably outsourced and got what they paid for.

It also appears that ebay doesn't retry on transient errors either. Oh, well, just say no to this scammers paradise.

Tar Pit Senders Using Spam Trap Email Adresses

Some spam still gets through, like the ones originating out of hotmail. To get rid of those I implemented a tar pit or spam trap. Publish an email address on all of your webpages, but make it hidden to viewers -- make it small and the same color as the background, etc. But let the web crawlers and serach engines pick it up. There's one at the bottome of this page, see if you can find it. Sign up on ebay with it, even if you do nothing on ebay. Ebay will sell it. Everytime you see a web form that asks for an email address give it that one. Now when you see email come in for that address you know you have a spammer. So I do three things: This way nothing is delivered and all subsequent attemps are rejected. Both things now eliminates about 98% of all the spam.

RBL Unknown Senders

I had not been a big fan of DNS Blacklists, becuase you have lost contol over the blocking. As a test I extracted the IP addresses of the machines from the the most recenet mail messages that I have saved which are 1478 messages. Running it through three RBLs, flagged 127 as spam. Out of those 127 that would have been rejected, 16 of them were valid and not spam (the rest were). It's a small number, but I would want to receive those emails. So my solution is not to check RBL on every message, but just those of senders you don't know, i.e. not marked with OK in the senders database. You still use the first "no space" method to induce the first retryable error, and place them in as a TEMP. But now when they come back, noted they are TEMP so run it through the RBLs. This way you must make sure you certain email address are OK as they may get black listed. Here's how to do it, if you have the sendmail FETAURE(rbl) (might be called FEATURE(dnsbl) as well) turn it off. Or comment it out of the sendmail.cf (it's probably the last secion of rules in Basic_check_relay. Now add a new function called Check_rbls (right after the end of Basic_check_relay). This checks three RBLs, njabl.org, spamhaus.org, and ordb.org.
SCheck_rbls
R$*			$: $&{client_addr}
R$-.$-.$-.$-		$: $(host $4.$3.$2.$1.dnsbl.njabl.org. $: <OK>$4.$3.$2.$1 $)
R$-.$-.$-.$-.$+		$#error $@ 5.7.1 $: "Mail from " $&{client_addr} " refused by RBL " $5
R<OK> $+		$: $(host $1.sbl.spamhaus.org. $: <OK>$1 $)
R$-.$-.$-.$-.$+		$#error $@ 5.7.1 $: "Mail from " $&{client_addr} " refused by RBL " $5
R<OK> $+		$: $(host $1.relays.ordb.org. $: <OK>$1 $)
R$-.$-.$-.$-.$+		$#error $@ 5.7.1 $: "Mail from " $&{client_addr} " refused by RBL " $5
R<OK> $+		$@

And just change one line in Local_check_mail to call it when needed, from:
R<TEMP> $+		$@
to:
R<TEMP> $+		$: $>"Check_rbls"
That's it. You'll have to keep an eye on the logs for senders that have been blocked by RBLs that you don't know, you may want to have an OK in for them. With this in place, it reduces the amount of tar pitting from step two that takes happens. All three together reduce spam by more than 99%.

Statistics Snapshot

During a total 1036 incoming mail connections made:

1a) 448 unique unknown senders soft rejected
1b) 16 connection attemps from the null sender (5 unique IPs)
1c) 201 senders never retried (45% defelction of senders)
1d) 23 connections from known good senders were let in.
2) Then 247 unique non-null senders retried making 549 connections
3a) 217 of the 549 rejected by RBLs (40% deflection of these connections)
(95.4% by njabl.org; 4.6% by ordb.org; and nothing by spamhaus.org)
3b) 152 of 549 connections reject by IP tar pitting due to a previous
email recipient was spam (see 4b, which actually happens first)
(28% deflection of connections)
3c) 9 rejections due to sender previously sent email to recipient was spam (again see 4b, which happens first)
3d) This makes for 67% deflection of these connections
(a total of 76% of all spam connections have now be deflected)
4a) the remaining 171 connections sent to 445 unique recipients
4b) 534 rejections due to recipient is a known incoming spam destination.
5) 2 pieces of spam evaded and got through (0.2% of all connections)
6) received 26 vaild emails (2.5% of all connections)

It's hard to calculate meaningful statistics since a single sender could send to multiple email addresses in one connection. So how many emails were defelected by a sender not retring or a RBL block or IP tar pit? There's at least one but maybe more (as noted by 171 connections sending in 536 emails, average of over 2 per connection). Let's just make it one, becuase that is known for sure. So 5 (null senders) + 201 (not retried) + 217 (RBL block) + 152 (IP tar pit) + 9 (sender tar pit) = 584. Plus 534 were rejected and 2 got through for a grand total of 1120 spam delivery attempts. Then 2 out out of 1120 makes for a 99.82% success rate of spam blockage.

© 2003 Cuzuco, Inc.
sending email to webmaster@cuzuco.com will do absolutely nothing for you