smtp-delay is an add-on/plug-in intended for use with qmail. It was written primarily to add banner delays and antipipelining to qmail. These two features are known to be able to block certain types of spam and virus mail sent through non-rfc-compliant SMTP engines. When I looked around for programs to add this functionality to qmail, I found only one such program, and didn't like the way it was done. BTW...I have the same objections to the way its done in sendmail 8.13.x.

Since banner delays (the server pausing for some time before issuing an SMTP banner) cause every SMTP connection to take longer, I thought it would be a good idea to somehow exempt "legitimate" mail servers...or at least not subject them to long banner delays. So I decided to tune the banner delay time based on the connecting IP's reverse DNS. IPs with no rDNS get treated the worst (longest banner delay). IPs with rDNS matching a regex intended to detect dynamic/end-user IPs get a moderate delay. All other IPs get a very short banner delay...just long enough to see if they immediately pipeline (send SMTP commands before the banner's been sent).

The original intent for smtp-delay was that it should be run before rblsmtpd, and simply set the RBLSMTPD environment variable if applicable, letting rblsmtpd issue the 4xx response. Pretty early on, I realized smtp-delay should be able to run standalone (without dependence on rblsmtpd to do its talking) and issue a 4xx response on its own. Lately, the spam load against our mail cluster has gotten so bad that I've started running smtp-delay after rblsmtpd, based on the idea that there's no point waiting out a long banner delay holding an open socket to an IP we have no intention of accepting mail from anyway. This reduced our concurrency by about 20%.

Current command line options for smtp-delay are:

smtp-delay [-d N] [-D N] [-P N] [-N N] [-S] [-v]

  -d N - delay to use for hosts with non-dynamic looking rDNS
  -D N - delay to use for hosts with dynamic looking rDNS
  -P N - delay to use for hosts with no rDNS
  Any of these delays can be supplied as either an integer number of
  seconds or a decimal number of [seconds].[fractionalseconds].
  If values are not specified via command line arguments, defaults of:
  -d 0.250000 -D 16.000000 -P 26.000000 will be used.
  These delays can also be set via the environment variables SMTPDELAYd,
  SMTPDELAYD, and SMTPDELAYP.
  -N - probability for which IPs with no PTR should be turned away with a
  421 message
  -S - standalone mode...will give the client a 451 message and terminate
  without execing whatever was to come next if they pipeline.
  -v - prints this message and exits

  "Dynamic looking" regex is currently:

((ppp|slip|pool|dyn|dinamic|guest|user|dial|dhcp|modem|port|cable|catv|cabo|docsis|kabel|kctv|ktv|acceso|televiso|dorm|newres|resnet|rescomp|reshall|residence|mobile|wireless|wlan|wless|wls|wrless|students|unassigned|unlabeled|unknown|unprovisioned|unused).*\.[^.]+\.[^.]+)|[0-9]+.[0-9]+.[0-9]+.|[0-9]{6}

The -N option is a recent addition. The idea behind it is that mail servers really should have rDNS. By rejecting mail from IPs with no rDNS with a temporary error, hopefully the senders will notice (mail getting backed up in their queue, messages taking longer to get delivered) and get some rDNS. By doing this rejection with some small probability (I'm starting out with -N 10 for a 10% chance) it's likely that mail from servers with no rDNS will get through...it just may take them more than one try.

Though not documented in the usage output above, if the environment variable RBLSMTPD="JUSTDELAY", then smtp-delay will do its banner delay and antipipelining functions, but will not set RBLSMTPD="". This only makes sense when running standalone (-S). This way, you can use it to reject pipeliners while exempting certain IPs/IP ranges from dnsbl checking. i.e. You might do this on a server that relays mail for your customers...block the infected ones trying to pipeline virus mail, but don't bother with dnsbl checks.

smtp-delay is written in C, and the latest version should always be here. You'll need to compile it with a command similar to:

gcc -Wall -s -O2 -o smtp-delay smtp-delay.c

It should build on any Unix-like system, but I've only used it on Linux. The log messages where smtp-delay tells you how long an IP waited before pipelining or closing the connection may not work properly on other OS's as I've taken advantage of a feature of select which is documented to be Linux-specific for measuring these times.

Typical usage (in your run file) might look like:

...
exec /usr/local/bin/softlimit <softlimit options> \
  /usr/local/bin/tcpserver <tcpserver options> \
  /usr/local/bin/fixcrio \
  /usr/local/bin/rblsmtpd <rblsmtpd options> \
  /usr/local/sbin/smtp-delay <smtp-delay options> \
  /var/qmail/bin/qmail-smtpd 2>&1

or

...
exec /usr/local/bin/softlimit <softlimit options> \
  /usr/local/bin/tcpserver <tcpserver options> \
  /usr/local/bin/fixcrio \
  /usr/local/sbin/smtp-delay <smtp-delay options> \
  /usr/local/bin/rblsmtpd <rblsmtpd options> \
  /var/qmail/bin/qmail-smtpd 2>&1

smtp-delay is free software, released under the GPL.