[ English / Japanese ]

- Anti bad-mail SMTP wrapper -

What's this?

The SMTP wrapper `antibadmail' provides generic spam rejection on SMTP session. This program is a successor of my qmail patches.

Because `antibadamail' is a wrapper, it can work not only with qmail, but also with sendmail, postfix and any other RFC2821 compliances.

Unlike the `Message contents spam filter', antibadmail rejects bad mail without seeing any contents of them. Imagine if you were a large scale bad mail sender. Do you send bad mails from valid SMTP server? Do you send bad mails with your correct email addresses?

No.

Antibadmail reject all bad mails seeing the bogus parameters in SMTP session. Doing so reduces the load of mail servers because antibadmail program check only three SMTP parameters(HELO, MAIL-FROM and RCPT-TO) and smtp-client's DNS-record settings.

How to get

cvs -d :pserver:anonymous@yatex.org:/qmail co antibadmail

And join abmusers ML.

Features

The antibadmail program enables handy bad mail rejection for qmail/sendmail/Postfix as below;

($CONTROLDIR defaults to /var/qmail/control)

Note that this is not a virus scanner. Most virus-infected PC sends malicious email with infected person's email addresses. Introduction of antibadmail does not mean unnecessity of virus scanner. But `contents filter' including virus scanners always waste tremendous computing resources which are essentially unnecessary.

You'll find 60%-99% of undesirable emails are comfortably rejected by antibadmail. Save your mail server's resources!

Installation

Antibadmail should be invoked by tcpserver which is in ucspi-tcp package.

# gtar zxpf ucspi-tcp-0.88.tar.gz
# cd ucspi-tcp-0.88
# vi conf-home
(edit conf-home to define installation prefix)
# make && make setup check
  1. Installaion step to wrap sendmail/postfix smtpd
  2. Installaion step to wrap qmail-smtpd
  1. Installaion step to wrap sendmail/postfix smtpd

    1. Change smtp daemon port other than 25. 10025 for example here.

    2. Create a unprivileged user for antibadmail

      # groupadd abm
      # useradd -g abm abm
      

      User name `abm' is arbitrary. Suppose uid and gid of `abm' user are 250 and 25 respectively.

    3. Start antibadmail as follows;

      RELAYCHECK=1 tcpserver -u 250 -g 25 -x /etc/smtp.cdb 0 25 \
        antibadmail mconnect 127.0.0.1 10025
      

      Make sure antibadmail and mconnect command are located in $PATH. `mconnect' is a SMTP connection client, which comes with ucspi-tcp. /etc/smtp.cdb is the tcpserver's connection control rule database. If you are not familiar with tcpserver, see the tcpserver rule section below.

    4. Put list of domain names your server can accept.

      If your server can accept(or relay) foo.example.com and *.bar.example.net, create empty files below in /var/qmail/control/rcpthostsdir/

      foo.example.com
      .bar.example.net

      Note that not at(@)marks necessary for domain patterns, unlike patterns for bad*dir described below. RELAYCHECK=1 on a startup command line indicates enable acceptable RCPT-TO domain check. Even if RELAYCHECK=1, when the client pass SMTP-AUTH, any RCPT-TO domain the client send will be accepted by antibadmail.

      If you alter acceptable domains by "POP before SMTP" control, please ask it at the abmusers ML.

  2. Installaion step to wrap qmail-smtpd

    The qmail-smtpd daemon program is well designed to be wrapped by others. All you have to do is to add antibadmail to starting script. For example, you may already have script like this;

    tcpserver -u 250 -g 25 -x /etc/smtp.cdb 0 25 qmail-smtpd
    

    Rewrite it as follows;

    tcpserver -u 250 -g 25 -x /etc/smtp.cdb 0 25 \
        antibadmail qmail-smtpd
    

    That's all.

tcpserver rule

If you are not familiar with tcpserver yet, try this simplest rule file /etc/smtp.

127.0.0.1:allow,RELAYCLIENT=""
10.0.0.:allow,RELAYCLIENT=""
all:allow

where 10.0.0. is IP-address prefix of your LAN. RELAYCLIENT="" means setting environment variable like that at invocation of antibadmail when smtp connection comes from corresponding address. Like qmail-smtpd, antibadmail assume that the client is located in LAN when the environment variable RELAYCLIENT is set, so that connection at that time must not be abusing. Antibadmail accepts all message when RELAYCLIENT set.

If you wrote rule database in /etc/smtp, you have to convert it to cdb-format as follows.

# cd /etc
# tcprules smtp.cdb tmp < smtp

After starting tcpserver+antibadmail, try `telnet localhost smtp' to confirm it is running. If the SMTP greeting message of original smtp-daemon shows up, almost goes well.

To record the rejecting/accepting result, add the following line to /etc/syslog.conf.

local1.info                  /var/log/smtp-stat

It is more desirable to add a notation for log rotation to /etc/newsyslog.conf(BSD) or /etc/logrotate.conf(Linux).

Constructing badmail database

Antibadmail refers `datadir' database structure. Datadir is maildir-similar structure where an entity exists in a form of `file in a directory' instead of `line in a file'. By default, antibadmail referes three directories.

You can change the prefix /var/qmail/control by environment variable $CONTROLDIR at running time or by `CFLAGS=-DCONTROLDIR=/foo/' at compilation.

Blacklist

A filename should be one of as follows;

Rejection by header

The policy of antibadmail is ``Don't inspect contents''.

However, as to badmail forwarded by (friendly) SMTP server, we can find rejection ground only in message header.

Antibadmail can reject mails by mail header pattern. The datadir structure for rejection by header is little bit different from above. Datadir for one header pattern consists of as follows;

$CONTROLDIR/badhdrdir/FieldName/EntryName/p*
$CONTROLDIR/badhdrdir/FieldName/EntryName/errmsg

where FieldName is header-field name all lower case, EntryName is arbitrary name for pattern set.

For example, if you reject message whose header field contains as follows;

Received: from hogehoge.fugafuga.com (HELO oldserver.you.used) ....(1)
  or
Received: from unknown .... by oldserver.you.used ....(2)

where `....' is any string. You might want to reject forwarded badmails by seeing received-header added by SMTP server you previously used. Pattern for (1) is like this;

(HELO oldserer.you.used)

For (2);

from unknown
by oldserver.you.used

Note that pattern(2) is written in two lines so that each string ("from unknwn" and "by oldserver.you.used") must match with received header. As a conclusion,

--- File: $CONTROLDIR/badhdrdir/received/foo/ptn-1 ---
(HELO oldserer.you.used)

--- File: $CONTROLDIR/badhdrdir/received/foo/ptn-2 ---
from unknwon
by oldserer.you.used

--- File: $CONTROLDIR/badhdrdir/received/foo/errmsg ---
We cannot receive suspicious messages.

refuses the messages which have received-header that matches with "(HELO oldserer.you.used)", or matches with both "from unknwon" and "by oldserer.you.used", returning the SMTP error message of "We cannot receive suspicious messages.".

Blacklist avoidance

You might want to reject all false `*@hotmail.com' mails. But you might want to receive `*@hotmail.com' from real hostmail server. In this case, do as follows;

  1. Put reject pattern in badmailfromdir/
    # touch /var/qmail/control/badmailfromdir/@hotmail.com
    
  2. Authorize client whose PTR-record matches with *.hotmai.com. Put the following line to /etc/smtp and convert it to smtp.cdb.
    =.hotmail.com:allow,GOODMAILFROM="@hotmail.com"
    

If you want to receive any message from certain server, Set environment variable RELIABLECLIENT for the server.

=smtp.server.you.wantto.rely:allow,RELIABLECLIENT=""

Antibadmail stops all rejection check except extremely insecure parameter when RELIABLECLIENT is set.

Soiled recipient address

If you or users of your SMTP server want to receive all email even if the sender's SMTP server has wrong DNS-record settings. Suppose when you apply web-shoping, auction, mail-magazine or so. Those sites as a whole are held in ill-mannered service provider. Many of them don't have correct settings of DNS(A and PTR record) nor SMTP-HELO. Althogh antibadmail reject emails from those incorrect servers by default, you can stop rejection upon certain receipient addresses.

You can make `soiled recipient address' as follows.

  1. Create datadir for soiled recipients.

    # mkdir /var/qmail/control/soiledrcpttodir
    
  2. Make the entry of recipient address for no rejection.

    # mkdir /var/qmail/control/soiledrcpttodir/local-foo@your.domain
    

Then antibadmail will pass all emails for `local-foo@your.domain'.

For qmail, wildcard patterns acceptable for soiledrcpttodir are as follows.

Note that rejection avoidance don't occur when smtp client sends parameter which matches strictly with entry of one of badhelodir, badmailfromdir and badrcpttodir.

Public spamdb

The public spam rejection database is available via anoncvs.

cvs -d :pserver:anonymous@yatex.org:/qmail co spamdb

This database is in plain text format, not datadir structure. You can convert plain text database to datadir struct by f2d command, which comes with antibadmail package.

You can convert, for example, badmailfrom file from spamdb to badmailfromdir/ structure by executing f2d as follows.

f2d -d ./badmailfromdir badmailfrom

Note that ./badmailfromdir/ and badmailfrom is accessible from working directory.

The Datadir structure

Any database which has multiple records in a file always suffers from these difficulties;

  1. file locking, which is the goal of `Don Quixote'
  2. one data file corruption means whole data corruption
  3. Updating data file without atomic-operation causes another referer to confusion

With `Datadir' structure, there's no need for file locking because all the updation on an entity can be done without referring any other entities. All addition/deletion operation is automatically atomic because they are file creation or file deletion.

Antibadmail Users ML

There is Mailing List for discussing about development and trouble shooting related to antibadmail. Please join it to nourish antibadmail!

To join the antibadmail users ML(abmusers), send your self introduction(more than 5 lines) to abmusers@ml.gentei.org with subject="subscribe". Here is an example.

To: abmusers@ml.gentei.org
Subject: subscribe
--
(Self-introduction more than 5 lines)
I'm newbie administrator of FOO company.
I love email!
I don't like spam!
---
YourMail@foo.comp....

Do not mimic above. :)

Publications

Sorry, Japanese only below.