Looking over my sendmail logs, I noticed that a lot of junk was coming in from addresses without registered DNS names, or from hosts whose DNS names were just some form of the IP address plus the base domain name. So I wrote this filter to reject connections from all of these sources. This takes care of the majority of spam coming in from dialup, DSL, and cable modems.
I ran into some oddball exceptions though, like some ISPs using MAC addresses instead of IP addresses in their dynamic hostnames. So I added a regular expression parser to allow explicit accept/reject of particular hostnames. I also restructured things so that it checks the incoming connection, but doesn't send a REJECT result until it drops into the Recipient handler. This lets you see the From/To info in the syslog, so you can look thru and add more exceptions as needed.
Following a suggestion in the comp.mail.sendmail newsgroup, I've also added a 20 second delay on rejects, to keep the spammer's server busy a bit longer before telling it to go away. Maybe this will help tie them up longer, who knows.
Update:The delay is only 9 seconds by default but you can edit it to whatever value you like. Also, the code returns a temporary failure (450) instead of a permanent failure (550) now. The theory is that bulk mailers will give up anyway, but if you accidentally reject an email that you really wanted to receive, this gives you a grace period in which to add a regexp exception for that sender, and they will automatically retry the delivery at a later point. -- hyc, 2005-03-22
The source code for the filter is here badDNS.c and it's only a few KB in size. Assuming you have a recent sendmail (I used 8.12.9) already installed with milter support, building is pretty simple. On Linux I use "gcc -O2 -D_REENTRANT -o badDNS badDNS.c -lmilter -lpthread" and I'm sure the command isn't much different on other platforms.
Here's a starter for /etc/mail/regexp:
.*\...\.comcast\.net$ REJECT .*\..*\.ocn\.ne\.jp$ REJECT .*\..*\...\.charter.com$ REJECT .*\..*\.uswest\.net$ REJECT .*\..*\..*\.home.nl$ REJECT .*\..*\..*\.sprint-hsd\.net$ REJECT getdown.*\.demon\.nl$ REJECT .*\..*\.adelphia\.net$ REJECT .*\.andrew\.cmu\.edu OKI install the milter in /usr/sbin/badDNS and invoke it as
/usr/sbin/badDNS -p local:/var/run/f1.sock &Add this to sendmail.mc to use the milter in sendmail:
INPUT_MAIL_FILTER(`badDNS', `S=local:/var/run/f1.sock, F=T, T=R:30s')(You will have to remake the sendmail.cf, naturally.) The "F=T" flag says to reject all incoming messages with a "Temporary Failure" error code if the milter is unavailable. The "T=R:30s" flag says to wait up to 30 seconds for a response from the milter. The milter will return immediately for allowed sessions, but will delay for 20 seconds before rejecting a session, and by default sendmail only waits 10 seconds for the reply. It needs to wait at least 20 seconds, otherwise it will assume the milter has died and will again return a Temporary Failure result to the remote server.