ANTI BAD Mail!

    [ English / Japanese ]

# - Anti bad-mail SMTP wrapper -

## What's new?

- New variable REJECTIPINHELO introduced for rejecting emails from host whose HELO string contains its IP address octets.(1.38)
- Environment variable PERMIT_NXRCPT permit session which sends to unknown mailbox.(1.36)
- Now antibadmail can check the existence of remote SMTP server via `rq' server/client program.
- REGEXP can be used to patterns for rejection by header.(1.33)

## 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 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

To get latest version, use cvs.

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

Once you've checked out source, all you have to do when you want to get latest source is typing

    cvs -z1 up -Pd

in `antibadmail/` directory. If you want to improve this program by yourself, please feel free to email to abmusers ML. Then we'll create developer's account in CVS repository for you.

Snapshot here.
antibadmail-1.37.tar.gz

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)

- badhelo rejection

  Reject mail from host which sent HELO parameter that matches with file name in $CONTROLDIR/badhelodir/. Entries starting with period are treated as wildcard.

  Some spammer's smtp hosts send helo of bogus IP address. Almost all of them are spam. Reject them.

  More strict HELO qualification as below will be done for unknwon-host(hosts with PTR record of IP address unset).

  No dots in HELO string assumed to be a bad host.

  Much wider wildcard match for helo string, `.jp' for example, can be applied for unknown host. Put wider wildcard patterns into $CONTROLDIR/badhelodir/unknown/ by creating empty file with that name.

  If environment variable REJECTIPINHELO is set, reject when HELO string contains 4 octets of client host's IP address. This is effective to reject spam from hosts whose IP address are dynamically allocated. When REJECTIPINHELO is set to integer n(1<=n<=3), skip first n octets and the trailing 4-n octets are compared.
  eg. If REJECTIPINHELO="2" and client address is 10.2.3.4, only "3" and "4" are tested.

  In any case above, badhelo check is skipped when $RELAYCLIENT or $RELIABLECLIENT is set like qmail manner.

- badmailfrom rejection

  In the same way as badhelo rejection, you can reject certain pattern of MAIL-FROM addresses. Put the email address string you want to reject into $CONTROLDIR/badmailfromdir/. Any patterns starting with `@' means all email addresses on that domain. Any patterns starting with dot(.) matches with all email domains under that domain.

      (eg.)
      @hotmail.com      -> matches with all *@hotmail.com addresses
      .biz              -> matches with all *@*.biz addresses

  You might know there are very very very many spam under the assumed name of RANDOM@hotmail.com. Giving up receiving all @hotmail.com is a clever solution. Do you think is it a overdosing?? Read the next.

- $GOODMAILFROM for authorized mail-from domain

  Setting GOODMAILFROM to acceptable domains in tcpserver rule file. Domains listed in this variable should be accepted even if that domain is in `$CONTROLDIR/badmailfromdir/` list. With this feature, you can reject all false @hotmail.com while you get real hotmail messages from real hotmail servers. To achieve this, put

      =.hotmail.com:allow,GOODMAILFROM="@hotmail.com"

  in tcpserver's rule and then put @hotmail.com in `badmailfrom` database. Note that tcpserver for antibadmail should be invoked *WITHOUT* -H flag(-H means not to lookup remote host name).

- $GOODHELO for authorized HELO string

  Like the manner of $GOODMAILFROM, values listed in $GOODHELO should be accepted even if the string is in `$CONTROLDIR/badhelodir/`.

  USE THIS WITH CARE

  There are some ISP which provide free email service and commercial Internet connection service, such as Yahoo. Authentic Yahoo SMTP servers send correct FQDN name of them. So it is good idea to reject `HELO yahoo.com' because 100% of them are sent from badmail. You'd better to put 'yahoo.com' entry in badhelodir/ database. Do not set $GOODHELO for this case. But..

  Disgusting SMTP servers, hotmail.com for example, don't send FQDN of them. Hotmail SMTP server stupidly sends `HELO hotmail.com'. Sigh.. Use $GOODHELO only for these case.

      =.hotmail.com:allow,GOODMAILFROM="@hotmail.com",GOODHELO="hotmail.com"

  Put a line above in tcpserver's rule file and you can receive emails from silly setting servers.

- Reject mail from sender without domain-part

  Reject all mail of localpart-only sender, except messages of bounce or messages from RELAYCLIENT.

- Reject bounce-faking mail which claims multiple rcptto

  Null-sender is used for bounce mail. Some spammer's MTA sends emails with null-sender to multiple recipients. That's surely spam. The antibadmail program refuses null-sender emails once the client requests more than one RCPT TO.

- Rely LAN clients

  If $RELAYCLIENT or $RELIABLECLIENT is set, cancel mail-from domain check. Useful for receiving bounce mail from reliable mail server.

- Limit mailfrom-domains from certain server

  When you had old mail account on host you previously used, you want to forward emails to current mail server. In such case, you ought to know "forwarded email are full of spam!!", because your current mail server should rely the forwarding servers. Against this problem, the antibadmail program rejects all forwarded mail from such server except those listed in $PASSONLY. If you want to limit forwarded emails from old server to *.jp and *.org, put

      =old.server.previously.used:allow,PASSONLY=".jp/.org"

  in tcpserver's rule.

- badrcptto

  Reject any RCPT-TO recipient addresses listed in $CONTROLDIR/badrcpttodir/.

- $BADHOST rejection

  If the environment variable BADHOST set, reject the mail from that host with SMTP error 553. It is bad idea to refuse TCP connection from host which sends emails you want to reject, because natural action of SMTP client is to try to connect to secondary MX and/or more. Set $BADHOST by tcpserver as follows;

      =.evil.domain:allow,BADHOST=""

  It will always sends SMTP-5xx error code to smtp client that matches with above rule.

- Paranoid check

  Requires tcpserver with tcpserver-paranoid patch.

  It is true IP'addresse's DNS PTR record is not absolutely required. But almost all UBE sender disguise or omit PTR record.

  If you want to reject mail from server whose PTR record is disguising, add -p option to tcpserver

         tcpserver -p ......

  and replace tcpserver with tcpserver-paranoid patch. The antibadmail will reject mail from such host whose IP address has invalid PTR record.

- To cancel Paranoid check

  Paranoid check is too much powerful. It sometimes rejects desirable email. You can find rejection log by grep-ping "BAD_PARANOID". To forgive x.y.z.w which sends *@xyz.its.dom.ain for incorrect PTR record setting, add a rule to tcprule file as follows;

      x.y.z.w:allow,PASSONLY="@xyz.its.dom.ain"

  Emails from x.y.z.w that matches with $PASSONLY is acceptable even if x.y.z.w has wrong PTR record.

- Require PTR record for certain address block of smtp client

  In most case, spammer's computer is connected as unknown host. So it is clever to reject from unknwon host. But in fact, many desirable messages are sent from unknown host, since some mail-server administrators can't imagine the importance of correct DNS settings.

  For this problem, we should request PTR record of IP-address blocks for unfamiliar country. If you and your site's users all don't have needs to communicate with AAA-country, and IP-address block of `XXX.YYY.*.*' is allocated to AAA-country, put

      XXX.YYY.:allow,REQPTR=""

  in tcpserver's rule file. All connections from XXX.YYY.*.* without PTR record will be rejected. With PTR record, of cource, accepted.

- Require correct FQDN HELO for some address block of SMTP client

  In most case, polite SMTP clients send correct FQDN as HELO parameter. But not all. So, we can not reject all connections that send wrong HELO parameter even if it is effective.

  Requiring correct FQDN HELO can be partially activated against clients when environment variable CHECKHELODOMAIN is set.

      =*.ppp.example.net:allow,CHECKHELODOMAIN=""

  This rule request correct FQDN HELO for clients whose PTR record matches with `*.ppp.example.net`.

  Note that it is bad idea to apply CHECKHELODOMAIN to very wide range because some `good honest' clients don't send correct FQDN. Apply this for block that is apparently allocated to end-user. This rule is weeker than you imagine, because most decisions of rejection are done by other rules before this rule is applied.

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 modified version of tcpserver, which can set environment variables for both TCPREMOTEHOST match and TCPREMOTEIP match.

    cvs -d :pserver:anonymous@yatex.org:/qmail \
      co -r paranoid+bsd ucspi-tcp
    cd ucspi-tcp
    vi conf-home
    (edit conf-home to define installation prefix)
    make && make setup check

NOTE: If you use FreeBSD, checkout

    cvs -d :pserver:anonymous@yatex.org:/qmail \
      co -r paranoid+freebsd ucspi-tcp

instead.

You need 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. Replace uid=250 and gid=25 as described below with real values on your host.

Then, build antibadmail main programs.

    gtar zxpf antibadmail-VERSION.tar.gz
    cd antibadmail-VERSION
    make all install

At the beginning of `make', you have a chance to determine installation prefix of antibadmail. Assume prefix is `/var/qmail` in latter of documetation.

The final step is to wrap running smtpd:

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. Start antibadmail as follows;

          HOSTANDIP=1 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.

   3. 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 no at-marks(@) are necessary for domain patterns, unlike patterns for bad*dir described below. RELAYCHECK=1 on a startup command line specifies enabling 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

   First, genuine netqmail is strongly recommended. If you have old qmail-1.03 plus many spam-control patches such as qmail badrcpt to patch, qmpatch or so, replace it with netqmail. Now is the chance to shift. And if you are using ancient inetd+tcpwrapper for qmail-smtpd, replace it with tcpserver.

   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;

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

   That's all. Never fail to replace tcpserver with modified version described above.

### 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 all 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.

- `/var/qmail/control/badhelodir/`

  Contains files whose names are patterns of SMTP-HELO string for rejection

- `/var/qmail/control/badmailfromdir/`

  Contains files whose names are patterns of envelope sender for rejection

- `/var/qmail/control/badrcpttodir/`

  Contains files whose names are patterns of envelope recipient for rejection

Again, you can change the prefix `/var/qmail/control` by build time setting or environment variable $CONTROLDIR at running time.

### Blacklist

A filename should be the form of one of as follows;

- name

  For badhelodir, badmailfromdir and badrcpttodir, reject all clients which send parameter same as `name'.

- .name

  For badhelodir and badmailfromdir, reject all clients which send parameter whose domain ends with `.name'. That is, wildcard matching with `*.name'.

- @name

  For badmailfromdir, reject all clients which send MAIL-FROM parameter whose domain part is the same as `@name'. That is, wildcard matching with `*@name'.

### 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. Rejection by header is a `last resort', and can't be diverted once message header matches with a pattern even if the pattern is misspelled. Use with great care. Header inspection defaults to ON. To disable header check, set environment variable HEADERCHECK to 0 at invocation of antibadmail.

    HEADERCHECK=0 tcpserver ..... antibadmail .....

When HEADERCHECK is enabled, antibadmail receives DATA, it reads header patterns from regular data-directory. The datadir structure for header rejection is little bit different from above. Datadir for one header pattern consists of as follows;

    $CONTROLDIR/badhdrdir/FieldName/EntryName/p*
    $CONTROLDIR/badhdrdir/FieldName/EntryName/v*:VAR
    $CONTROLDIR/badhdrdir/FieldName/EntryName/errmsg

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

- `p*' file for pattern definition

  Any file whose name begins with `p' is evaluated as pattern to be compared with the value of FieldName. A pattern must be written in a line. Patterns more than one line are AND-ed sequentially left-to-right. Patterns in different files are OR-ed.

- `v*:VAR' file for special pattern when $VAR set

  Any file whose name begins with `v' and ends with `:VAR' is evaluated only when environment variable `VAR' is set. You can specify very strict rule for particular hosts by which tcpserver sets environment variable VAR. Typically, you might set $REQPTR (see above) for those hosts which is located in unfamiliar country to you. You'd better have v-somename:REQPTR files in pattern directories.

- `errmsg' file

  SMTP error message to be sent for clients when their sending header matches with pattern.

Suppose you have been receiving many spams via smtp server, which is in the office you previously belonged. Messages to your old address are forwarded to current address. In case as this, antibadmail can reject forwarded spam by seeing headers. If your old server's FQDN is `oldserver.you.used', messages with these header can be assumed to be spam.

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

where `....' is any string. Both (1) and (2) are received header attached by oldserver. Let's think about (1) first. It is the typical received header of spam. So we define the first pattern as follows;

    (HELO oldserer.you.used)

Why is this bad pattren? Because "HELO oldserver.you.used" was told by spamming server when it connects to oldserver.you.used. Sending opponent's name as HELO is typical spamming behavior.

Then, think about pattern for (2). It's as follows;

    from unknown
    by oldserver.you.used

Note that pattern(2) is written in two lines so that both string ("from unknwn" and "by oldserver.you.used") must match with received header. Now define this rule set name as `foo'

    --- 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.".

### Conditional header pattern

### More precise pattern for headers

When you are aware of the power of header rejection, you might want to describe patterns more precisely. The first character of each line determines the matching method. There are five methods for matching.

Pattern line | Meaning
--- | ---
=STRING | Whole line is exactly same as STRING
^STRING | Line is beginning with STRING
$STRING | Line is ending with STRING
/REGEX | Line is matching with regular expression REGEX
:STRING | Line has the part which match with STRING exactly
STRING Same as above

Note that all header field contents will be joined into one line, converted all lower case. Therefore all matching will be done in case-insensitive.

Regular expression engine is supplied by libc of your driving operating system. So it is different from that of Perl, Emacs-Lisp, (GNU)egrep which you may be experienced with. If you want to examine how regexp pattern matches with, use debugging mode of header module. It is obtained by typing this;

    make h

Using h command interactively as follows.

    ./h
    Received: from hogehoge.blah.example.org (HELO oldserver.you.used) by oldserver.you.used

The `h' command acquires all patterns in $CONTROLDIR/badhdrdir/*/* and apply all patterns over given strings from stdin. To change badhdrdir, set that directory to environment variable BADHDRDIR.

Be aware that although regular expression is friendly, using regexp easily causes configuration errors. It is difficult enough to confuse system administrators. Absolutely NO errors for mail configurations!

### Exclusion from blacklist

You might want to reject all false `*@hotmail.com' mails. But you might want to receive `*@hotmail.com' from real hotmail 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'.

`Domain specific control' is also available. If you and/or unprivileged users on your server hold virtualdomain, @v.example.com for example, create directory with that name and touch any files whose names are local-part for which you want to omit spam control.

    mkdir /var/qmail/control/soiledrcpttodir/@v.example.com
    cd /var/qmail/control/soiledrcpttodir/@v.example.com
    touch foo bar- ./-bar-baz ./'!bar-foo'
    ls
    !bar-foo  -bar-baz  bar-      foo

In this case above, each address are treated as follows.

local-part | spam-inspection | receive/reject
--- | --- | ---
foo | no (omitted) | receive
bar-baz | yes | depends on other parameters
bar-foo | no | REJECT
bar-any | no (omitted) | receive

Filenames are recognized as follows.

name

  No spam inspection for name@domain.

name`-`

  Wildcard. No spam inspection for any name-*@domain. It should work fine with qmail's address extension.

`-`name

  DO spam inspection for name@domain. Minus sign stands for `remove(-) from soiled entry'. Note that, this doesn't mean all messages to name will be delivered. They all will undergo spam inspection. Note also that, this minus sign can be combined with wildcard of ``-`'.

`!`name

  Reject name@domain immediately even if it might be clean message.

`ALL`

  Through all if local-part doesn't match any name in this directory.

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

## Reject unknown RCPT

For qmail users and admininstrators of secondary SMTP server, it was long time worry to stop mails to non-existent recipient. Both qmail-smtpd and secondary SMTP server don't know the existence of recipient(RCPT TO) address. Now antibadmail can drop mails for non-existent recipient.

- On primary(best preference MX) SMTP server running qmail
  (sendmail has no need to care abount this issue)

  The recipient existence check is automatically done by antibadmail. If recipient mailbox DOES NOT EXIST SURELY on the host, antibadmail reject it. Note that antibadmail checks the availability of recipient addresses with unprivileged uid, therefore all directories that contain dot-qmail files should be world-cd'able(eXecutable). If you are using vpopmail, its default settings of virtual domain holding directories are not world-cd'able. In that case, chmod +x on those directories.

- On secondary SMTP server

  You can have running remote recipient checker. Currently this checker supports the case you are running qmail on primary SMTP server.

  The `./qserver/' directory of the antibadmail source distribution contains the client/server scripts to check the existence of recipient on (remote)primary host. Two steps to set up. Suppose you administrate mail domain `@example.com' and its primary SMTP server has IP-address[192.168.1.1].

  - Server host (primary SMTP)

    1. `cd qserver; make`

    2. To allow client to connect, add client's IP-address to LOCAL.tcprule file amd type `make' again.

    3. `./run`

    If you have running daemontools on the host,

        ln -s $PWD /service

    is enough.

  - Client host (secondary SMTP on which antibadmail runs)

    1.     cd qserver
           make all install
           mkdir $CONTROLDIR/rq

    2. Create `$CONTROLDIR/rq/example.co.jp` with content as below;

           #!/bin/sh
           rq 192.168.1.1

    Then antibadmail will automatically execute `rq/example.co.jp` when it receives *@example.co.jp as RCPT TO parameter. If the script returns 0, antibadmail reject request of SMTP-client.

  You had better make sure the `run' script works fine and tcp connection from client is surely allowed on primary SMTP host by doing as follows:

      secondary% telnet 192.168.1.1 9999
      Trying 192.168.1.1...
      Connected to tmax.
      Escape character is '^]'.
      foobarbazhogehoge
      NG
      root
      OK Maybe

  Note that antibadmail NEVER REJECT non-existent recipient WHEN IT FAILS TO CONNECT TO REMOTE `./run' server. Please make sure well of `./run' server's availability beforehand.

## Environment Variables to Control Behaviour

When each variables in this table is set, antibadmail alter the action. These variables can be set via antibadmail start-up script or tcpserver according to client's IP-address/hostname.

Variable | Action when set | Negation
--- | --- | ---
`RELAYCLIENT` RELIABLECLIENT | Accept all message except when the client sends seriously bad parameter. | no
`CHECKHELODOMAIN` `CHD` | Expect HELO paramter has correct DNS record | yes
`REJECTNODOTHELO` | Reject HELO without dots. | yes
`REJECTIPINHELO` | Reject HELO which contains client IP address that is presumably hostname with dynamically allocated IP address. | yes
`PERMIT_STATIC` | In the case of `REJECTIPINHELO`, permit if client's PTR-record has substring "static". | yes
`PASSKNOWNNODOTHELO` | By default, antibadmail rejects no-dot HELO from unknwon host. Set this variable when overlook it. | yes
`PASSUNKOWNIPHELO` | By default, antibadmail rejects IP-address formed HELO from unknown host. Settng this variable passes it. | yes
`NOMFDCHECK` | Stop MAIL-FROM domain check. | yes
`PERMIT_NXRCPT` | By default, antibadmail disconnect session when clients sends non-exixtent RCPT for protection from `random dictionary attack'. When a good user sends to multiple recipients with some of them misspelled, the SMTP session will end in rejection. To rescue this, set this variable. But it is subject to dictionary attack. | yes
`BADHOST` | Reject. | yes
`NOTERM` | Keep SMTP session after it is proved to be spam. | yes
`QUICKREJECT` | Reset TCP quickly before all SMTP parameters are accepted. | yes

Negating effect of each variable can be accomplished by set its value to `"0"`.

## Public spamdb

The public spam rejection database is available via anoncvs.

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

Or just type

    make spamdb

In the top directory of antibadmail source.

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

Or just type `make' in spamdb/ directory.

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

    cd $CONTROLDIR
    ln -s $SPAMDBDIR/bad*dir .

Finally, create a Makefile to merge your site's smtp-rule and spamdb's smtp-badhost referring an example Makefile in spamdb/Makefile.tcprule.

    TR	= tcprules
    OWNER	= qmaild
    #OWNER	= abm

    SRC	= smtp smtp-badhost

    all: smtp.cdb

    smtp.cdb:	${SRC}
    	(cat ${SRC} ; \
    	 echo all:allow ) | ${TR} $@ smtp.tmp
    #       chown ${OWNER} smtp.cdb

Locate this as Makefile in smtp starting directory(eg. /service/smtpd).

    cd /service/smtpd
    ln -s $CONTROLDIR/smtp-badhost
    make

## 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. :)

## No Warranty

This program is free software and comes with absolutely NO WARRANTY. The author is not responsible for any possible defects caused by this software. You can freely modify this program for your convenience. But if you want to publish modified program, please tell me before announcement. Take it easy to write me comments and bug-reports.

yuuji@gentei.org

## Publications

Sorry, Japanese only below.

- Implementation and Verification of SMTP Wrapper for Spam Rejection - IPSJ Sig.DSM #35@Akita University
- メールサーバーで行なうスパム対策 - ソフトバンクパブリッシング UNIXUSER 2004年11月号 第1特集 Part4