Antispam Provisions
N.B.: If you're still running 8.8.x and can't upgrade for some reason, this page should help you. But the recommended way to deal with anti-relay problems is to upgrade to 8.9.3 or 8.10 .
The following examples are tentative and unsupported. However, they may prove useful to people who are having problems with spammers. I don't guarantee that they are complete, extensively tested, or well documented at this time. Caveat Emptor.
That said, however, many of these have evolved into FEATURE()s
in 8.9; see the Anti-Spam
Configuration Control section of the 8.9 cf/README for details. And
cf/cf/knecht.mc in the distribution is always a good
place to check for anti-spam prototypes and examples. Meanwhile,
for people still using 8.8, these ruleset can be added to your
configuration file (hint: if using the M4 method, use
LOCAL_RULESETS; if editing a .cf file directly, add them to the
end of the file) to get the effect indicated.
NOTE: If you copy rules from this page, you must change the whitespace between the fields to tabs. Sendmail will reject the rule if there are merely spaces between the fields. If your text editor changes tabs to spaces as they are entered, you may have to use another editor that does not.
Other anti-spam references
- The grand daddy of anti-spam sites, run by Scott Hazen Mueller.
- A score-based anti-spam filter by Graham Toal (requires sendmail code changes).
- Claus Aßmann's Using check_* in sendmail 8.8
- Marty Lyons' Notes on Stopping U.C.E.
- Glenn Fleishman's Putting the Bam-Bam on Spam
- MAPS TSI: Sendmail Version 8 anti-relay solutions
- Kai's SpamShield
- The Coalition Against Unsolicited Commercial E-Mail
Preventing Relaying Through Your SMTP Port
Preface
The solution below is dated and incomplete. Another check_rcpt ruleset for sendmail 8.8 rejects all known cases of unauthorized relay attempts.
Problem
Other people can connect to your SMTP port and send mail through you.
Solution
Mail must originate or terminate
locally (on this host), with exceptions made for hosts listed,
one per line, in /etc/sendmail.cR. (In this
incarnation, this ruleset does not allow relaying within your
domain, except for the hosts listed in
/etc/sendmail.cR. Note carefully, you must list
fully qualified host names for each host you wish to allow
relaying. Simply listing a domain name is not
enough. Ideally, it would only restrict relaying from outside
your domain. This is particularly useful if you are using mail
clients such as MH or Eudora that like to try to find an SMTP
relay on the local network to do outgoing mail submission.)
Code
FR-o /etc/sendmail.cR
Scheck_rcpt
# anything terminating locally is ok
R< $+ @ $=w > $@ OK
R< $+ @ $=R > $@ OK
# anything originating locally is ok
R$* $: $(dequote "" $&{client_name} $)
R$=w $@ OK
R$=R $@ OK
R$@ $@ OK
# anything else is bogus
R$* $#error $: "550 Relaying Denied"
Notes
- If you would prefer to list domains in
sendmail.cR, you can replace all occurrences of$=Rwith$* $=Rin the ruleset above. This rule doesn't block
user%other.domain.com@your.domain.com. If you want to block this type of addressing, you'll need sendmail 8.8.6 or greater and this change to the ruleset. (Downloadable version) Replace the first section:# anything terminating locally is ok R< $+ @ $=w > $@ OK R< $+ @ $=R > $@ OKwith
# anything terminating locally is ok R$* $: $>Parse0 $>3 $1 R$+ < @ $* . > $* $: $1 < @ $2 > R$+ < @ $=w > $@ OK R$+ < @ $=R > $@ OK- If your site is a backup mail server for another site (you are a higher-numbered MX record for them), be sure to add the domain names of that site to your new sendmail.cR file.
- In 8.9, relaying is disabled by default.
Refuse Mail From Selected Relays
Problem
Spam -- persistent, offensive mail from various sites.
Solution
Refuse connections from the spamming sites. This involves keeping a database of those sites; the key will be the host name of the site and the value will be what you want to say to them.
Code
Kspammers hash /etc/spammers
Scheck_relay
R$+ $| $+ $: $(spammers $1 $: OK $)
ROK $@ OK
R$+ $#error $: 521 $1
Notes
- error message (value part of database entry) isn't actually used; instead, all commands are rejected with ``550 Access denied''.
- /etc/spammers is a database map and must be created with:
makemap hash /etc/spammers < /etc/spammers - In 8.9, FEATURE(access_db) takes care of this.
Insist On Valid Host Name In MAIL FROM: Command
Problem
You want to reject mail that has bogus host names in the MAIL FROM: SMTP command. (Also includes the previous fix, but modified so that it will deliver an insulting message back to the perpetrators.)
Solution
Check for validity in the MAIL command. In this case you have to permit people in the spammers database greater access to your server (e.g., they will be able to use VRFY and EXPN), but you can still prevent them from sending mail.
Warning
This ruleset is incompatible with the DeliveryMode=defer option, since it requires that a DNS lookup be done immediately upon mail receipt.
Code
Kspammers hash /etc/spammers
Scheck_mail
# check for valid domain name
R$* $: <?> $>3 $1
R<?> $* < @ $+ . > $: <OK>
R<?> $* < @ $+ > $#error $: 451 Domain must resolve
# check relay against spammers database
R$* $: $(spammers $&{client_name} $: OK $)
ROK $@ OK
R$+ $#error $: 551 $1
Notes
- VRFY, EXPN, etc. will still work. Since it keys off the MAIL FROM: value, which is easily forged, it may be less effective than the previous solution.
- /etc/spammers is a database map and must be created with:
makemap hash /etc/spammers < /etc/spammers - In 8.9, unresolvable domains are rejected by default. Also, in 8.9, the /etc/spammers checks are replaced by the FEATURE(access_db).
Restrict Mail Acceptance
Problem
Some bozo is mail-bombing me.
Solution
Keep a database of the bad guys. In this case the database key is ``user@host'' and the value is the error message you want to return.
Code
Kbozos hash /etc/bozos
C{Protected}eric
Scheck_compat
# if the recipient isn't protected, they get the mail
R$+ $: <OK> $1
R<OK> $+ $| < $={Protected} @ $=w >
$: <PROT> $1
R<OK> $+ $@ OK
# check to see if the sender is a bozo
R<PROT> $+ $| $+ $: $(bozos $1 $: OK $)
ROK $@ OK
R$+ $#error $: 551 $1
Notes
- This one doesn't really work well because it doesn't handle angle brackets well.
- In 8.9, the FEATURE(access_db) takes over this function.