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.
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.
# R<> $@
R<> $#error $@ 4.1.8 $: "451 looks like spam"
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.
firstname.lastname@example.org 452 try again later
email@example.com 550 get lost
This accepts mail from the user firstname.lastname@example.org, and anyone from the
domain myfriends.com with the exception of email@example.com which gets a hard error.
Also all senders from the domain evilspammer.com as well as the user firstname.lastname@example.org 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:
tail -1f $LOG | while read a
echo "$a" | grep 'no space left on device' > /dev/null 2>&1
if [ $? -eq 0 ]
sender=`echo "$a" | sed 's/.*<//;s/>.*//'`
echo "$sender TEMP" >> senders
makemap dbm senders < senders
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
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
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:
The sender gets changed from TEMP to 550 spam sender in the senders database. I will clear these out weekly.
The IP address of the sending machine is placed in the access database with a REJECT tag. With the exception of mailers from aol, yahoo and hotmail; as legit and spam comes from these IPs. This is cleared out daily.
The session that is currently trying to send the mail in on is terminated by killing the specific sendmail child process.
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,
And just change one line in Local_check_mail to call it when needed,
R<TEMP> $+ $@
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%.
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.