Go see http://inorganic5.fdt.net/~jlewis/spam.html for a newer version. ------------------ Last updated 8-22-1997: Converted spaces to tabs in the sendmail rules. If downloaded with lynx -source, you should get tabs...other methods can convert them to spaces. ------------------ Last updated 7-5-1997: Added check_rcpt rule mods to allow certain from addresses to relay mail through even though they are from foreign IP addresses. ------------------ The following text is based on the message indicated in the header below, but has been edited and added to since the post was first sent. NOTE: Before using any of the rules here on a real system, you're strongly encouraged to _test_them_ on a workstation where it won't matter if you totally hose sendmail and reject perfectly good mail. The information here is offered with absolutely no warranty of any kind. From jlewis@INORGANIC5.FDT.NET Sun Jun 1 01:52:13 1997 Date: Thu, 29 May 1997 00:36:37 -0400 From: Jon Lewis Reply-To: Linux Servers mailing list To: SERVER-LINUX@NETSPACE.ORG Subject: Re: the war against spam (LONG) > :I managed to find some usefulish stuff on > :http://www.informatik.uni-kiel.de/~ca/email/check.html (I think that was > :the URL.) I had a problem with it, though, since most of the stuff This site is where I've gotten nearly everything I'm using. It's been invaluable, and Claus really should be thanked for making the info available there. Also, if you're serious about blocking spam, you should visit Claus's site occasionally to see the latest in anti-spam rules that he's either devised or collected. Here it all is as of today...I keep updating and adding to it. As others have warned, for those who are not used to messing with sendmail.cf, rules have the following format: Rlhs\t+rhs\t+comment or Rlhsrhscomment That's an R, the left hand side of the rule, one or more tabs, the right hand side of the rule, one or more tabs, comments. Everything after the rhs is optional. If you paste these in, and forget to convert spaces to tabs where necessary, sendmail will be pissed, and you'll get log messages like: May 27 12:12:31 tarkin sendmail[10195]: NOQUEUE: SYSERR(root): /etc/sendmail.cf: line 927: invalid rewrite line "R<^A= > ^A#error ^A@ 5.7.1^A: "571 We don't accept junk mail"" (tab expected) So...the info here all gets pasted into the end of your sendmail.cf...sorry, I don't have m4 format patches. The rest of this message is formatted >80 cols to reduce confusion in the rules. I've added in additional comments using my 2nd edition ORA sendmail book for some. This is a really big intimidating book, but well worth buying. # Junk mail sources # Individual email addresses of spammers F{Spammer} /etc/mail/sendmail.spammer # Domain names you want to ban because they seem to exist solely to serve # spammers. F{SpamDomain} /etc/mail/sendmail.spamdomain Scheck_mail # Bounce mail from known junk sources # The check_mail rule is fed the address specified in the "mail from:" # command in the smtp dialog. # I've seen check_mail rules on other web sites where these 2 steps (the # Spammer and SpamDomain classes) are combined into one, but the below # method works and lets people know exactly if they or their entire # domain are banned. The SpamDomain rules below ban entire domains with # all subdomains...so if you banned foo.org, spam.foo.org is also banned and # so is non.spam.foo.org. That's covered by the $* between the @ and # the $={SpamDomain}. R<$={Spammer}> $#error $@ 5.7.1 $: "571 We don't accept junk mail" R<$={Spammer} . > $#error $@ 5.7.1 $: "571 We don't accept junk mail" R$={Spammer} $#error $@ 5.7.1 $: "571 We don't accept junk mail" R$={Spammer} . $#error $@ 5.7.1 $: "571 We don't accept junk mail" R$* $: $>3 $1 R$* < @ $* $={SpamDomain} > $* $#error $@ 5.7.1 $: "571 We don't accept junk mail from your domain" R$* < @ $* $={SpamDomain} . > $* $#error $@ 5.7.1 $: "571 We don't accept junk mail from your domain" R$*<@[$-.$-.$-.$-]>$* $: $1 < @ $[ [ $2.$3.$4.$5 ] $] > $6 #no DNS entry? this is dangerous! # This is the nasty one that's rejecting the most mail right now from # fdt.net. What it does is take any mail from: address who's hostname is # not resolvable and not a member of the P class (pseudo domains you might # have defined that are not DNS resolvable...you probably have none, but # better safe than sorry) and reject the mail with a temporary failure # code...since DNS failure could be a temporary problem. The reality is # some mail will keep trying to get in again and again, tying up system time # and bandwidth but won't get through. It appears they will also attempt to # get through via any MX records you have. Depending on how busy your system # is, and how much bandwidth you have, and what that bandwidth costs, you # might want to replace 4.1.8/418 with 5.1.8/518, and make that a permanent # failure, due to invalid senders system address. R$*<@$*$~P>$* $#error $@ 4.1.8 $: "418 unresolvable host name, check your configuration." # The next section deals with relaying...it changes the standard "I'll relay # for anyone policy" into "I relay for nobody but a select few". # This file lists the domains you will relay for...i.e. some remote system # can send mail to one of these domains through your. This would probably be # because you are a valid secondary MX record for them, or you house their # virtual domain. F{RelayTo} /etc/mail/sendmail.relays # This file lists IP blocks you will allow to relay through you...i.e. # someone from one of these blocks can send a message to the north pole # through your system (and you're not even in the north pole). You can # specify full IP addresses or classful (A B C) blocks. i.e. an ISP would # probably list each of their "class C's" in this file...something like: # 205.229.48 # 205.229.49 # etc. F{LocalIP} /etc/mail/sendmail.locals # This file lists email addresses of those complaining users who simply # can't survive without being able to relay through your server from any # random IP address on the planet. I was against the idea of this rule, but # a vocal few users bugged me into coming up with it. F{LocalUser} /etc/mail/sendmail.locuser Scheck_rcpt # first: get client addr R$+ $: $(dequote "" $&{client_addr} $) $| $1 R0 $| $* $@ ok no client addr: directly invoked R$={LocalIP}$* $| $* $@ ok from here # not local, check rcpt R$* $| $* $: $>3 $2 # remove local part, maybe repeatedly # next rule checks to see if a remote person is sending to a domain in your # w class...domains for local delivery. R$*<@$=w.>$* $>3 $1 $3 # next rule checks to see if a remote person is sending to a system in your # domain or one of your subdomains. R$*<@$*$m.>$* $>3 $1 $3 # next rule checks to see if a remote person is sending to a domain or # subdomain of one of the domains lists in your relays file. R$*<@$*$={RelayTo}.>$* $>3 $1 $4 # addition to allow certain users to relay even from foriegn IP's # grab the "mail from:" address from the $f macro and append it to the # workspace. Then look for matches. R$+ $: $1 $| $(dequote "" $&f $) R$+ $| $={LocalUser} $@ ok # still something left? # If none of the above were true, it must be remote mail going to some # remote site...and you don't want to be Quantum Comm's latest relay, so just # say no. # note, this now ignores the junk added to the workspace in the previous # rule. R$*<@$+>$* $| $* $#error $@ 5.7.1 $: "571 we do not relay - if you believe this to be an error, contact support@your-domain-here" # These next 2 rules work on the IP address and hostname of the system # passing the mail to you. The first lets you block by IP or classful IP # block similar to the format in the sendmail.locals file, or by name. The # second deals with the hostname and it was handy to use the SpamDomain # class again here rather than maintain another file of banned hostnames. F{DeniedIP} /etc/mail/sendmail.spamip Scheck_relay R$+ $| $={DeniedIP}$* $#error $@ 5.7.1 $: "We don't accept junk mail from your domain" R$*$={SpamDomain} $| $* $#error $@ 5.7.1 $: "We don't accept junk mail from your domain" With the above, I'm blocking several thousand junkmail and spam-relay attempts per day. On big pitfall is that if you have multiple MX records...i.e. $ host gnv.fdt.net gnv.fdt.net has address 205.229.48.17 gnv.fdt.net mail is handled (pri=50) by tlh.fdt.net gnv.fdt.net mail is handled (pri=5) by gnv.fdt.net gnv.fdt.net mail is handled (pri=15) by kashmir.fdt.net Your anti-spam policies at each system must be carefully maintained, or junk mail will get into one, bounce around a few days, then go to the local postmaster as undeliverable. That was the reason for my smhup program, and the reason I put the class files in /etc/mail. /etc/mail is owned by a special user, into which root from my systems is allowed to scp files as...so I update class files on one system, and run a script that alphabetizes them and distributes them to the rest of my systems. Each system has a root crontab entry that checks every few minutes to see if /etc/mail/sendmail.relays is newer than /var/run/sendmail.pid. If it is, the class files were updated more recently than sendmail was restarted, so sendmail is restarted to load the new class files. sendmail.relays will always have a mtime of the last time class files were updated, because when the class files are distributed via scp, a creation script is also run via ssh that combines several sendmail.cw.sysname files into sendmail.relays. I alphabetize the class files so that as I add to them, I can quickly be sure I'm not adding duplicate entries. The creation script also does a sort | uniq, just in case I do add an entry twice. So...with all this, you can block known spamming domains (if they don't lie about the from address, which some do), block by IP block, and block spams that have a bogus domain from address (so you can't reply to them). You can, and probably will want to, do additional filtering based on message headers using something like procmail or other filtering software. I've heard of some sites giving their clients a web front end to .procmailrc creation/editing, and if anyone has something like that, that's publicly distributable, I'd be interested. ------------------------------------------------------------------ Jon Lewis | Unsolicited commercial e-mail will Network Administrator | be proof-read for $199/message. Florida Digital Turnpike | ________Finger jlewis@inorganic5.fdt.net for PGP public key_______