Sendmail Anti-Spam M4 Hack

antispam.m4-1.2
By Steve Coile <scoile@patriot.net>

Contents

Features

These rules, when applied to your Sendmail configuration, will provide the following services:

Requirements

In order to make use of this hack, you will need to have Sendmail 8.8.5 or higher installed.  Red Hat Linux 4 systems should be using the sendmail-8.8.5-2 package provided by Red Hat Software (available as an update for 4.1 and 4.0).  You must also have the M4 configuration files installed.  RHL includes these in the sendmail-cf-8.8.5-2 package.

These instructions assume you are using the stock sendmail-8.8.5-2 and sendmail-cf-8.8.5-2 packages provided by Red Hat Software.

Installation

In order to use this hack, download the following file and place it in the /usr/lib/sendmail-cf/hack directory.  The file should be downloaded directly; do not view the file from your Web browser and cut-and-paste, as you may lose the tab characters essential for proper operation.  The file is:

http://www.patriot.net/users/scoile/isp-redhat/sendmail/antispam.m4-1.2

If you have Lynx installed, the following commands will download the file and place it in the proper location:

SOURCE="http://patriot.net/~scoile/isp-redhat/sendmail/antispam.m4-1.2"
TARGET="/usr/lib/sendmail-cf/hack/antispam.m4"
lynx -source "$SOURCE" > "$TARGET"

Then add the following line to your Sendmail M4 configuration file (the M4 configuration file supplied with the sendmail-cf-8.8.5-2 package is /usr/lib/sendmail-cf/cf/redhat.mc):

HACK(antispam)

Typically, this line is appropriately placed near the bottom of the M4 configuration file.  If the line already exists in your M4 configuration file, you need make no changes to the file at all.

Next, generate a new Sendmail configuration file by issuing the following commands.  The generated configuration file will be named "redhat.cf" and will be located in the /usr/lib/sendmail-cf/cf directory.

cd /usr/lib/sendmail-cf/cf
m4 redhat.mc > redhat.cf

You may wish to compare the newly-generated configuration file with your active configuration file before replacing the active configuration file.  One way to compare the changes is to use the "diff" command:

diff -U0 /etc/sendmail.cf redhat.cf

Before activating the new configuration, create the directory in which the new configuration will look for anti-spam related configuration files.

mkdir /etc/sendmail

It would be a good idea to at least review the descriptions of the various data files used by the filter (below) before stopping and restarting Sendmail in the next step.  More than likely, you will want to create and add entries to some configuration files, and will have to stop and restart Sendmail in order to make Sendmail aware of the configuration changes anyway, so you might as well make them now.

Finally, replace the active Sendmail configuration file with the new configuration file and restart Sendmail:

cat redhat.cf > /etc/sendmail.cf
/etc/rc.d/init.d/sendmail.init stop
sleep 3
killall sendmail
/etc/rc.d/init.d/sendmail.init start

Configuration

The anti-spam rules use six configuration files.  By default, the rules expect the files to be located in the directory, /etc/sendmail.  The standard RHL installation does not include this directory, so you will need to create it if you want to make use of the configuration files.

File Format

The configuration files are simply lists of Internet host names, Internet domain names, IP addresses, and IP address blocks, identifying hosts and domains that may and may not send and receive e-mail through your mail server.  In addition to identifying hosts and domains, you may even identify individual users!

Host and domain names should be identified in the traditional Internet name format.  For instance:

localhost
mydomain.com
relay.yourdomain.net

Domain names include all systems within the domain.  For instance, in the above, mydomain.com would match somehost.mydomain.com, too.

IP addresses and IP address blocks should be specified in dotted quad notation, surrounded by square brackets.  For instance:

[127.0.0.1]
[206.151.9]
[129.174]

Notice how the second and third examples identify class C and class B IP address blocks, respectively.

The rules attempt to resolve IP addresses associated with the sender's address.  If the address resolves, the rules will use the resolved name rather than the IP address.

You can also specify individual user addresses, using the standard user@domain format>  For example:

root@mydomain.com
webmaster@somehost.yourdomain.net
postmaster@

The domain portion of the address (the portion after the "@" sign) will be matched in the same way as a domain specification without a username portion would:  any host within the domain matches the domain name.  For instance, the first example above would also match root@computer.mydomain.com.  The third example above will match the username in any domain (use with caution!).

IP addresses and address blocks (surrounded by square brackets) may also be used with individual user addresses.

File Contents

/etc/sendmail/client.allow

This file allows you to identify clients (physical hosts) that may pass mail to you, regardless of sender or recipient address.  The file may only contain IP addresses or IP address blocks; host and domain names, as well as user specifications will be ignored.

A typical use for this file is to identify the IP address blocks within your control or assigned to trusted clients.

It is a good idea to add your local loopback address to this file.  The following is an example using the common local loopback address, 127.0.0.1:

[127.0.0.1]

Also add the IP address blocks corresponding to the portion of your network(s) containing hosts that should always be allowed to pass mail through your system, and the IP addresses or address blocks of any external secondary mail exchangers for your domain(s).

/etc/sendmail/client.deny

This file allows you to identify clients (physical hosts) that may not pass mail to you, regardless of sender or recipient address.  The file may only contain IP addresses or IP address blocks; host and domain names, as well as user specifications will be ignored.

A typical use for this file is to identify the IP addresses or address blocks of abusive hosts or domains, such as those of known bulk mailers.

/etc/sendmail/from.allow

This file allows you to identify sender addresses that are to be considered trustworthy.  If a message arrives with a sender address matching an entry in this file, the message is accepted even if the recipient address is external.

If your client.allow file is configured properly, you hopefully will never need to use the from.allow file, as all of your legitimate users will be sending mail from trusted hosts.  Unfortunately, ISPs frequently have users that connect to the Internet through some other means (through another ISP, or through a connection at work) and want to be able to send mail through your mail server.  Typically, such users don't have static IP addresses (IP addresses that follow the user around), so it's difficult to impossible to add an entry to client.allow that will allow these roaming users to use your mail server without opening your mail server up to other external users.  The only option, then, is to recognize the roaming user's e-mail address:  when a message arrives on your mail server with the roaming user's address as the sender address, accept the message for delivery, regardless of destination.  This file allows you to identify user addresses, hosts, and even entire domains that, if they appear in the sender's address, messages are to be accepted from.

Adding entries to this file is a risky proposition.  Internet e-mail is rediculously easy to forge.  If an unscrupulous bulk mailer was aware of the addresses you have listed in your from.allow file, the mailer could forge messages under those addresses and bypass your deterent measures.  Add entries to this file sparingly, and try to avoid adding anything less specific than an exact user's e-mail address.

An example entry:  suppose you control the domain, somedomain.com.  A user of yours with an e-mail address of aroamer@somedomain.com, wants to be able to send e-mail through your mail server from another ISP.  You would add the following entry to your from.allow file:

aroamer@somedomain.com

The user should then configure his e-mail program so that it sends messages as aroamer@somedomain.com, rather than with his e-mail address on the other ISP.

/etc/sendmail/from.deny

This file allows you to identify sender addresses that are to be considered untrustworthy.  If a message arrives with a sender address matching an entry in this file, the message is refused regardless of client or recipient addresses.

A typical use for this file is to identify e-mail addresses, and host and domain names used by abuse hosts or domains, such as those of known bulk mailers.

/etc/sendmail/rcpt.allow

This file allows you to identify recipients for whom you will accept mail, regardless of apparent or actual sender.  In addition to the recipients listed in this file, messages to any host in the $=w class (the hosts listed in the /etc/sendmail.cw file), any host in the $=M class (hosts the mail server masquerades as), and any host in the domain described by $m (the domain of the mail server) will be accepted.

A typical use for this file is to identify the hosts and domains for which you provide secondary mail exchanger service (i.e. hosts and domains to which you legitimately relay).

/etc/sendmail/rcpt.deny

This file allows you to identify recipients for whom you will not accept mail, regardless of client or sender address.

A typical use for this file is to identify domains, hosts, or even individual users currently under mailbomb attack and should not receive further mail until the attack is stopped.

Operation

The anti-spam ruleset, once installed, is fully integrated into Sendmail, so the impact on mail servers should be minimal.

Whenever data files are modified, Sendmail must be restarted for the changes to take effect.

The logic used to evaluate an incoming message is applied in the following order:

Changes

Version 1.2

  • Handles addresses of the form, "username@", more gracefully.  Thanks to Greg Dickson for bringing this problem to my attention.

Version 1.1

  • Sender's address canonicalized before analysis.
  • Recognize second-party relay addresses of the form, "@host1:user@host2", and apply filtering only to the "user@host2" portion.

History

Having gotten fed-up with the continuous flood of unsolicited bulk mail flowing through our mail servers, I finally got around to doing some research into how to protect our systems against the abuse.  I quickly realized that there was no one way to do it, that there were many different approaches, and that they all were disjoint, inflexible, and difficult to manage.  By all appearances, the methods available were off-the-cuff solutions that worked fine as temporary solutions, but were more difficult to work with than I wanted.

The first anti-spam rules I tried were those published by Harker Systems, but they didn't actually prevent relaying.  They just refused messages from hosts without names and allowed postmasters to explicitly refuse service to domains and IP blocks.

Then I attempted to adapt Jon Lewis' anti-spam Sendmail configuration, since it seemed to be widely used and appeared to at least do the job.  I created an M4 configuration file for use with Sendmail, but never actually put the rules into production.  I was just too dissatisfied with numerous, disjoint configuration files used to identify hosts from which your server would and would not accept mail.

While trying to improve on the rules I got from Jon's page, I managed to learn something about Sendmail itself, and decided to write my own rules from scratch.  I was interested in rules that would allow for easy, intuitive configuration, that were full-featured (i.e. did everything most other rules do), and that would prevent relaying without explicit configuration (i.e. prevent relaying by default, rather than require management to identify sites that may not relay).

antispam-1.2 is the fourth public release (0.2.4 was the first).  Version 1.0 represented a significant change in approach from previous versions.  Specifically, version 1.0 made fewer assumptions about the manager's interests and required more file-based configuration.  Support for client-specific filtering was also added.