spamdyke Documentation

This documentation is updated with each version of spamdyke to reflect that version's features and behavior. If you need documentation for an older version, see the README file that was included with that version's spamdyke download.

This document applies to spamdyke version 3.1.8.

Other Documentation

The following additional documents are available:
Installation instructions: INSTALL.txt
Upgrading instructions: UPGRADING.txt
Frequently Asked Questions: FAQ.html
Changelog.txt

About spamdyke

help
version

spamdyke is a filter for monitoring and intercepting incoming SMTP connections to a qmail server. It acts as a transparent middleman, observing the conversation without interference unless it sees something it should block. Because it can silently monitor, it can also log mail traffic in several different ways.

spamdyke is ©2007 Sam Clippinger, samc (at) silence (dot) org. It is distributed under the GNU General Public License (version 2 only) from http://www.spamdyke.org/

The --help command line option will give a brief summary of the available command line options. The --version command line option will give just the version and copyright statement.

Support

spamdyke support is available from the spamdyke mailing list: www.spamdyke.org/mailman/listinfo/spamdyke-users.

The mailing list archives are searchable thanks to mail-archive.com: www.mail-archive.com/spamdyke-users@spamdyke.org.

If all else fails, email me directly at samc (at) silence (dot) org.

How spamdyke works: When a message is not blocked

spamdyke works by acting as a middleman between qmail and the network (in Unix terms, it's a pipe). When no spamdyke filters are triggered and a message is delivered normally, spamdyke silently passes data in both directions. As the SMTP conversation takes place, spamdyke collects a few pieces of data (e.g. the sender and recipient addresses) so they can be logged.

spamdyke does modify the incoming message in one way. The SMTP protocol requires the remote sender to end every line with a two character terminator -- a carriage return and a line feed. qmail chooses to strictly enforce this requirement. If a remote sender uses only a line feed to end a line (a typical and easy mistake to make), qmail will reject the message:

451 See http://pobox.com/~djb/docs/smtplf.html.
spamdyke compensates for this behavior by silently inserting a carriage return before any bare line feed characters it sees. This doesn't affect the messages, it only prevents this error from blocking your mail.

How spamdyke works: When a message is blocked

spamdyke's filters are described in detail below. When one of them is triggered, spamdyke moves in to block the incoming message.

First, it considers SMTP AUTH. If authentication could take place but has not done so, spamdyke will wait to see if the remote sender authenticates. Authenticated connections are never filtered.

Next, once spamdyke is certain the message should be filtered, it cuts the connection between the remote sender and qmail. In the background, spamdyke sends a QUIT command to qmail, so qmail will exit normally, believing the remote sender simply gave up.

spamdyke continues sending responses to the remote server, just as qmail would have. Once the remote sender has identified the sender and recipient, spamdyke sends an error code and refuses to accept the message. The remote sender disconnects, never knowing that spamdyke hijacked the conversation. spamdyke, meanwhile, uses the sender and recipient information it gathered to construct its log messages.

Usage

spamdyke's behavior is controlled through options given on the command line or in configuration files. On the command line, long options should be prefixed with two hyphens (--). Some options have short versions, which should be prefixed with one hyphen (-). In a configuration file, only the long versions are valid and an equals sign must separate the value from the option. See Configuration Files for details.

For example, consider the max-recipients option. Suppose you wished to restrict the maximum number of recipients per message to 5. On the command line, its long version would be used like this:

spamdyke --max-recipients 5 ...
Or, since its short version has the same meaning, the command line could look like this:
spamdyke -a 5 ...
In a configuration file, only the long version is valid and an equals sign is required, so the entry would look like this:
max-recipients=5

After all options are given, spamdyke expects the rest of its command line to contain the qmail command. For example:

spamdyke -a 5 /var/qmail/bin/qmail-smtpd
Sometimes, depending on the options in use, spamdyke's command line parser can become confused. If spamdyke believes the qmail command is a parameter to one of its options, you may see the following error message:
ERROR: Missing qmail-smtpd command
To resolve this, place two hyphens (--) between the end of spamdyke's options and the qmail command. For example:
spamdyke -a 5 -- /var/qmail/bin/qmail-smtpd

The following options are only valid on the command line:

Long Version Short Version Parameter Description
config-test     Tests the configuration as much as possible and reports any errors that can be discovered without actually accepting an incoming message. Use this option with all other options that are given during normal operation. To check file permissions properly, use the config-test-user option.

See Configuration Tests for details.
config-test-smtpauth-password   PASSWORD While testing the configuration with config-test, run the commands given with smtp-auth-command or smtp-auth-command-encryption to test authentication processing. Use PASSWORD as the authentication password. This option has no effect unless config-test, config-test-smtpauth-username and either smtp-auth-command or smtp-auth-command-encryption are given.

See Configuration Tests for details.
config-test-smtpauth-username   USERNAME While testing the configuration with config-test, run the commands given with smtp-auth-command or smtp-auth-command-encryption to test authentication processing. Use USERNAME as the authentication username. This option has no effect unless config-test, config-test-smtpauth-password and either smtp-auth-command or smtp-auth-command-encryption are given.

See Configuration Tests for details.
config-test-user   USER[:GROUP] While testing the configuration with config-test, run the tests as the system user with the username or ID USER. If GROUP is provided, also use the system group with the name GROUP or ID GROUP. This option has no effect unless config-test is given.

See Configuration Tests for details.
help h   Displays a summary of spamdyke's options, then exits.
version v   Displays the spamdyke version and copyright statement, then exits.

The following options are valid on the command line and in configuration files:

Long Version Short Version
(command line only)
Parameter Description
access-file   FILE Use FILE to determine if the remote host is allowed to connect and/or relay. Only needed when using spamdyke to provide SMTP AUTH for an unpatched qmail installation. Most often, FILE is /etc/tcp.smtp.

See Relaying for details.
always-graylist-ip-file   FILE Always graylist connections from remote servers whose IP addresses match entries in FILE. This option only has effect when no-graylist-dir is given, it is ignored when graylist-dir is given.

See Graylisting / Greylisting for details.
always-graylist-rdns-dir   DIR Always graylist connections from remote servers whose rDNS names match files in DIR. This option provides much better performance than always-graylist-rdns-file for large numbers of entries. This option only has effect when no-graylist-dir is given, it is ignored when graylist-dir is given.

See Graylisting / Greylisting for details.
always-graylist-rdns-file   FILE Always graylist connections from remote servers whose rDNS names match entries in FILE. This option only has effect when no-graylist-dir is given, it is ignored when graylist-dir is given.

See Graylisting / Greylisting for details.
check-dns-whitelist   DNSWHITELIST Check the remote server's IP address against the DNS whitelist DNSWHITELIST (essentially a DNSRBL that contains whitelisted IPs). If it is found, all filters are bypassed.

See DNS Whitelists for details.
check-dnsrbl x DNSRBL Check the remote server's IP address against the realtime blackhole list DNSRBL. If it is found, the connection is rejected.

See DNS RBLs for details.
check-rhs-whitelist   RHSWHITELIST Check the remote server's domain name and the sender email address' domain name against the righthand-side whitelist RHSWHITELIST (essentially an RHSBL that contains whitelisted domains). If it is found, all filters are bypassed.

See DNS Whitelists for details.
check-rhsbl X RHSBL Check the remote server's domain name and the sender email address' domain name against the righthand-side blackhole list RHSBL. If it is found, the connection is rejected.

See DNS RHSBLs for details.
config-file f FILE Read additional configuration options from FILE as though they were given on the command line.

See Configuration Files for details.
connection-timeout-secs t SECS Forcibly disconnect after a total of SECS seconds, regardless of activity. A value of 0 disables this feature.

See Timeouts for details.
full-log-dir L DIR Log all SMTP traffic to files in DIR. Handy for troubleshooting delivery problems but not meant to be used long-term. This option imposes a performance penalty!

See Logging All Traffic for details.
graylist-dir g DIR Graylist all connections except those excluded by the never-graylist-* options and use DIR as a base for graylist files. DIR must contain a folder named for each domain that is to be graylisted (e.g. DIR/example.com). This option is mutually exclusive with no-graylist-dir.

See Graylisting / Greylisting for details.
graylist-max-secs M SECS Invalidate graylist entries after they are SECS seconds old. Requires graylist-dir or no-graylist-dir.

See Graylisting / Greylisting for details.
graylist-min-secs m SECS Require a graylist entry to be present for SECS seconds before allowing incoming mail. Requires graylist-dir or no-graylist-dir.

See Graylisting / Greylisting for details.
greeting-delay-secs e SECS Delay sending the SMTP greeting banner SECS seconds to see if the remote server begins sending data early. If it does, the connection is rejected.

See Earlytalkers for details.
hostname   NAME Use NAME as the fully qualified domain name of this host. This value is only used to create an encrypted challenge during SMTP AUTH challenge-response.

See SMTP AUTH for details.
hostname-command   COMMAND Read the fully qualified domain name of this host from the output of COMMAND. Most often, this value is /bin/hostname -f. This value is only used to create an encrypted challenge during SMTP AUTH challenge-response. This option is ignored if hostname or hostname-file are given.

See SMTP AUTH for details.
hostname-file   FILE Read the fully qualified domain name of this host from the first line of FILE. This value is only used to create an encrypted challenge during SMTP AUTH challenge-response. This option is ignored if hostname is given.

See SMTP AUTH for details.
idle-timeout-secs T SECS Forcibly disconnect after SECS seconds of inactivity. A value of 0 disables this feature.

See Timeouts for details.
ip-blacklist-file B FILE Reject the connection if the remote server's IP address matches an entry in FILE.

See Blacklists for details.
ip-in-rdns-keyword-file k FILE Search the remote server's rDNS name for its IP address and a keyword in FILE. If both are found, the connection is rejected.

See Reverse DNS for details.
ip-whitelist-file W FILE If the remote server's IP address matches an entry in FILE, bypass all filters.

See Whitelists for details.
local-domains-file d FILE Use FILE as a list of locally hosted domains (to determine if an email address is local or remote). Most often, FILE is /var/qmail/control/rcpthosts.

See Rejecting Senders and Recipients for details.
log-level l (lowercase ell) [LEVEL] Sets the log level to LEVEL: 0 = none, 1 = errors only, 2 = errors and info, 3 = errors, info and debug messages, 4 = excessive output.

See Log Messages for details.
log-target   TARGET Sends all log messages to TARGET: 1 = syslog, 0 = standard error (stderr).

See Log Messages for details.
max-recipients a NUM Allow a maximum of NUM recipients per connection for non-local senders.

See Limiting Numbers of Recipients for details.
never-graylist-ip-file   FILE Never graylist connections from remote servers whose IP addresses match entries in FILE. This option only has effect when graylist-dir is given, it is ignored when no-graylist-dir is given.

See Graylisting / Greylisting for details.
never-graylist-rdns-dir   DIR Never graylist connections from remote servers whose rDNS names match files in DIR. This option provides much better performance than never-graylist-rdns-file for large numbers of entries. This option only has effect when graylist-dir is given, it is ignored when no-graylist-dir is given.

See Graylisting / Greylisting for details.
never-graylist-rdns-file   FILE Never graylist connections from remote servers whose rDNS names match entries in FILE. This option only has effect when graylist-dir is given, it is ignored when no-graylist-dir is given.

See Graylisting / Greylisting for details.
no-graylist-dir G DIR Graylist no connections except those included by the always-graylist-* options and use DIR as a base for graylist files. DIR must contain a folder named for each domain that is to be graylisted (e.g. DIR/example.com). This option is mutually exclusive with graylist-dir.

See Graylisting / Greylisting for details.
policy-url u URL Append URL to the rejection message to explain why the rejection occurred. NOTE: most servers hide rejection messages from their users and most users don't read bounce messages. Maximum 100 characters.

See SMTP Error Codes for details.
rdns-blacklist-dir b DIR Reject the connection if the remote server's rDNS name matches a file in DIR. This option provides much better performance than rdns-blacklist-file for large numbers of entries.

See Blacklists for details.
rdns-blacklist-file   FILE Reject the connection if the remote server's rDNS name matches an entry in FILE.

See Blacklists for details.
rdns-whitelist-dir   DIR If the remote server's rDNS name matches a file in DIR, bypass all filters.

See Whitelists for details.
rdns-whitelist-file w FILE If the remote server's rDNS name matches an entry in FILE, bypass all filters.

See Whitelists for details.
recipient-blacklist-file S FILE Reject any recipient addresses that match entries in FILE.

See Rejecting Senders and Recipients for details.
recipient-whitelist-file   FILE If the recipient's email address matches an entry in FILE, bypass all filters.

See Whitelisting Senders and Recipients for details.
reject-empty-rdns r   Reject the connection if the remote server has no rDNS name.

See Reverse DNS for details.
reject-ip-in-cc-rdns c   Search the remote server's rDNS name for its IP address and a two-letter country code. If both are found, reject the connection.

See Reverse DNS for details.
reject-missing-sender-mx     Check the domain name of the sender's email address for a mail exchanger (an MX or an A record). If neither are found, reject the connection. Requires local-domains-file.

See Rejecting Senders and Recipients for details.
reject-unresolvable-rdns R   Reject the connection if the remote server's rDNS name does not resolve (search for an A record).

See Reverse DNS for details.
sender-blacklist-file s FILE Reject the connection if the sender's email address matches an entry in FILE.

See Rejecting Senders and Recipients for details.
sender-whitelist-file   FILE If the sender's email address matches an entry in FILE, bypass all filters.

See Whitelisting Senders and Recipients for details.
smtp-auth-command   COMMAND Perform SMTP AUTH verification using COMMAND. spamdyke will only advertise cleartext authentication methods (unless qmail has been patched to advertise encrypted methods). If the authentication is valid, all filters will be bypassed. Most often, COMMAND is /bin/checkpassword /bin/true.

See SMTP AUTH for details.
smtp-auth-command-encryption   COMMAND Perform SMTP AUTH verification using COMMAND. spamdyke will advertise all available authentication methods, including encrypted ones -- COMMAND must provide support for encrypted authentication. If the authentication is valid, all filters will be bypassed. Should not be used with smtp-auth-command (such usage is valid but makes no sense). Most often, COMMAND is /home/vpopmail/bin/vchkpw /bin/true.

See SMTP AUTH for details.
tls-certificate-file   FILE Offer TLS support using the SSL certificate in FILE. FILE must be in PEM format. If FILE does not also contain the private key, tls-privatekey-file must be used.

See TLS for details.
tls-privatekey-file   FILE Read the private key for the SSL certificate (from tls-certificate-file) from FILE. FILE must be in PEM format. Requires tls-certificate-file.

See TLS for details.
tls-privatekey-password   PASSWORD Use PASSWORD to decrypt the SSL private key (from tls-certificate-file or tls-privatekey-file), if necessary. NOTE: this option reveals the password in the process list! Requires tls-certificate-file and/or tls-privatekey-file.

See TLS for details.
tls-privatekey-password-file   FILE Read the password to decrypt the private key for the SSL certificate (from tls-certificate-file) from the first line of FILE, if necessary. Requires tls-certificate-file and/or tls-password-file.

See TLS for details.

Configuration Files

config-file

The configuration file format is very simple. Each line should use the following format:

OPTION=VALUE
OPTION is the long version of a spamdyke option. See Usage for details.

VALUE is the parameter for the option. Note: multi-word values on the command line (e.g. SMTP AUTH commands) must be quoted. In the configuration file, quotes are not allowed. spamdyke reads the entire VALUE after the equals sign, even if it contains spaces, so no quoting is needed.

Blank lines and lines beginning with # are ignored.

For example:

smtp-auth-command=/home/vpopmail/bin/vchkpw /bin/true
rdns-blacklist-dir=/home/vpopmail/blacklist_rdns.d
graylist-dir=/home/vpopmail/graylist.d
check-dnsrbl=dul.dnsbl.sorbs.net
check-dnsrbl=zombie.dnsbl.sorbs.net
max-recipients=5
True/false options can be given without a VALUE to activate them. yes, true and 1 are also acceptable. The options can also be explicitly deactivated with no, false or 0 (or the option can be simply removed). For example, the following lines all have the same effect:
reject-empty-rdns
reject-empty-rdns=yes
reject-empty-rdns=true
reject-empty-rdns=1
A configuration file is utilized by passing the command line option config-file to spamdyke:
spamdyke --config-file /etc/spamdyke.conf ...
The config-file option can also be used within configuration files to include other configuration files if desired. When configuration files are in use, options may still be provided on the command line as well, in any combination. If contradictory options are found, the last option scanned will be used. For example, if the following command line were used:
spamdyke --reject-empty-rdns --config-file /etc/spamdyke.conf ...
And /etc/spamdyke.conf contained the following line:
reject-empty-rdns=false
spamdyke would deactivate the reject-empty-rdns filter because the configuration file was scanned after the command line option. This can be confusing, so the best practice is to avoid specifying the same option in multiple places without good reason.

NOTE: It may seem that scanning a configuration file instead of the command line would impose a performance penalty each time spamdyke is started. However, the reverse seems to be true. Some rudimentary testing has indicated the configuration files are actually faster.

Configuration Tests

config-test
config-test-user
config-test-smtpauth-username
config-test-smtpauth-password

spamdyke has the ability to scan its configuration and look for common setup mistakes. It checks file permissions, graylist folders, directory structures, SMTP AUTH commands, TLS certificates and more. This feature was inspired by Apache's ability to check its configuration file for syntax errors.

To use the testing feature:

  1. Find and copy the entire spamdyke command from your "supervise" script or xinetd configuration file.
  2. At a command prompt, login as root and paste the spamdyke command without running it.
  3. Add the options --config-test and --config-test-user among the spamdyke options (before the qmail command). If appropriate, add the options --config-test-smtpauth-username and --config-test-smtpauth-password.
  4. Run the command and carefully read the results. More output can be obtained by increasing the logging level at your prompt (no test output goes to syslog).
The --config-test-user option should be used to give spamdyke the name (or user ID) of the account used to run the mail server. The group name (or ID) can also be given. Before spamdyke runs its configuration tests, it will change process ownership to run as the given user. That way, the filesystem permissions tests will be accurate.

If spamdyke is configured to provide SMTP AUTH (using the smtp-auth-command or smtp-auth-command-encryption options), the --config-test-smtpauth-username and --config-test-smtpauth-password options should be used to provide a valid username and password for authentication. spamdyke will run the SMTP AUTH command to test its capabilities and make recommendations.

IMPORTANT! DANGER! WARNING! DO NOT EVER PUT THE --config-test OPTION IN THE SPAMDYKE COMMAND LINE THAT IS RUN FOR INCOMING CONNECTIONS! YOUR MAIL SERVER WILL IMMEDIATELY STOP RECEIVING MAIL AND REMOTE USERS WILL SEE ONLY THE DIAGNOSTIC OUTPUT! If you make this mistake and ask for help, expect to be publicly mocked. You have been warned.

Log Messages

log-level
log-target

The log-target option controls where spamdyke logs its messages. By default, log-target is set to 1, which sends log messages to the system syslog facility. When log-target is set to 0, messages are sent to standard error (stderr) instead. For most qmail installations, this will cause spamdyke's messages to be logged by the "multilog" program, along with qmail-smtpd's output.

When spamdyke logs to syslog, it uses the LOG_MAIL facility, which typically puts the messages in /var/log/maillog. (Note: Plesk reconfigures syslog to put the messages in /usr/local/psa/var/log/maillog.)

Regardless of how the messages are logged, errors are always be preceded by the text ERROR: and are fairly self-explanatory. Whenever possible, spamdyke will recover from an error and continue processing mail. Philosophically, it's better to continue receiving spam than to block all mail.

The log-level option controls how much logging takes place. The following values are supported:

0: No logging at all, even if errors occur. This is not recommended.
1: Errors only, including authentication failures. This is the default when log-level is not given.
2: Errors and information, including mail traffic. This is the value used when log-level is given with no value.
3: Errors, information and debugging messages, including more filenames and line numbers when matches are found in various files. This level is handy for troubleshooting but it can be rather verbose.
4: Excessive debugging output, including lots of internal settings. This value should only be used for development.
Note that log-level must be used with care on the command line. Specifically, when --log-level is used, the value must be separated by an equals sign and no spaces. When -l is used, the value must not be separated by spaces or anything else. For example, the following two command lines will work:
/usr/local/bin/spamdyke --log-level=3 ...
/usr/local/bin/spamdyke -l3 ...
The log-level option may also be given with no value at all, which is the same as specifiying 2. The following two command lines are also valid:
/usr/local/bin/spamdyke --log-level ...
/usr/local/bin/spamdyke -l ...

Each traffic log entry takes the following form (error messages and debugging statements are text preceeded by ERROR: or INFO:):

CODE from: SENDER to: RECIPIENT origin_ip: IPADDRESS origin_rdns: RDNSNAME auth: USERNAME [ reason: REALCODE ]
This format makes the logs very easy to parse from other scripts for monitoring and graphing.

CODE can be one of the following:

ALLOWED
The message passed all filters. qmail may still bounce the message for other reasons, however.
ALLOWED_AUTHENTICATED
The remote client successfully authenticated using SMTP AUTH with spamdyke. If qmail is patched to provide SMTP AUTH, this code will never be used.
ALLOWED_TLS
The remote client successfully started a TLS session with spamdyke.
TIMEOUT
The connection timed out, either in total time (connection-timeout-secs) or idle time (idle-timeout-secs). If the connection was already being blocked for another reason, the code for that error is given as REALCODE.
DENIED_TOO_MANY_RECIPIENTS
The recipient was blocked because the limit (max-recipients) was reached for this connection. The SMTP connection continues after this error occurs.
DENIED_UNQUALIFIED_RECIPIENT
The recipient was blocked because the address had no domain name. The SMTP connection continues after this error occurs.
DENIED_GRAYLISTED
The recipient was blocked because the sender/recipient combination was graylisted (graylist-dir or no-graylist-dir). The SMTP connection continues after this error occurs.
DENIED_RDNS_MISSING
The connection was blocked because the remote server has no rDNS name at all (reject-empty-rdns).
DENIED_RDNS_RESOLVE
The connection was blocked because the remote server's rDNS name does not resolve (reject-unresolvable-rdns).
DENIED_IP_IN_CC_RDNS
The connection was blocked because the remote server's IP address was found in the remote server's rDNS name _and_ the remote server's rDNS name ends in a country code (reject-ip-in-cc-rdns).
DENIED_IP_IN_RDNS
The connection was blocked because the remote server's IP address was found in the remote server's rDNS name _and_ a prohibited keyword was found in the remote server's rDNS name (ip-in-rdns-keyword-file).
DENIED_EARLYTALKER
The connection was blocked because the remote server began sending data before the SMTP greeting was issued (greeting-delay-secs).
DENIED_BLACKLIST_NAME
The connection was blocked because the base domain of the remote server's rDNS name is blacklisted (rdns-blacklist-file or rdns-blacklist-dir).
DENIED_BLACKLIST_IP
The connection was blocked because the remote server's IP address is blacklisted (ip-blacklist-file).
DENIED_SENDER_BLACKLISTED
The connection was blocked because the sender's email address is blacklisted (sender-blacklist-file).
DENIED_RECIPIENT_BLACKLISTED
The recipient was blocked because the recipient email address is blacklisted (recipient-blacklist-file).
DENIED_RBL_MATCH
The connection was blocked because the remote server's IP address was found on a DNS RBL (check-dnsrbl).
DENIED_RHSBL_MATCH
The connection was blocked because the remote server's reverse DNS name was found on a righthand-side DNS blacklist (RHSBL) OR the connection was blocked because the sender's domain name was found on a righthand-side DNS blacklist (RHSBL).
DENIED_SENDER_NO_MX
The connection was blocked because the sender's domain has no mail exchanger, making the sender address invalid (reject-missing-sender-mx).
DENIED_ACCESS_DENIED
The connection was blocked because the remote server's IP address or rDNS name was found in the access file with a deny command (access-file).
DENIED_RELAYING
The recipient was blocked because the recipient's domain is not locally hosted (local-domains-file) and the remote server is not allowed to relay (access-file).
DENIED_OTHER
The connection was rejected by qmail (or another downstream filter), not spamdyke.
FAILED_AUTH
The remote server attempted to authenticate but the given username and/or password were incorrect (smtp-auth-command or smtp-auth-command-encryption).
UNKNOWN_AUTH
The remote server requested an authentication method spamdyke doesn't support. This shouldn't happen.
FAILED_TLS
The remote client attempted to start a TLS session but SSL negotiation failed.

SENDER is the sender email address, if known, or (unknown) otherwise. NOTE: According to RFC 821, it is legal to deliver messages with no sender address. Most bounce messages are delivered this way.

RECIPIENT is the recipient email address, if known, or (unknown) otherwise. If CODE is ALLOWED, the recipient email address will be known.

IPADDRESS is the IP address of the remote server. This value is always known.

RDNSNAME is the rDNS name of the remote server, if known, or (unknown) otherwise.

USERNAME is the username given during authentication, if authentication was successful, or (unknown) otherwise.

REALCODE is only present if CODE is TIMEOUT and the connection was going to be blocked anyway. For example, if a remote server has no rDNS entry and the connection is going to be blocked but the connection times out instead, CODE will be TIMEOUT and REALCODE will be DENIED_RDNS_MISSING.

SMTP Error Codes

policy-url

When spamdyke blocks a connection and returns an error code to a remote server, the error text the remote server sees is different from what appears in syslog (above). It is more user-friendly, just in case a human ever reads it (no one ever does).

The messages that correspond to the syslog codes are:

TIMEOUT
Timeout. Talk faster next time.
DENIED_TOO_MANY_RECIPIENTS
Too many recipients. Try the remaining addresses again later.
DENIED_UNQUALIFIED_RECIPIENT
Improper recipient address. Try supplying a domain name.
DENIED_GRAYLISTED
Your address has been graylisted. Try again later.
DENIED_RDNS_MISSING
Refused. You have no reverse DNS entry.
DENIED_RDNS_RESOLVE
Refused. Your reverse DNS entry does not resolve.
DENIED_IP_IN_CC_RDNS
Refused. Your reverse DNS entry contains your IP address and a country code.
DENIED_IP_IN_RDNS
Refused. Your reverse DNS entry contains your IP address and a banned keyword.
DENIED_EARLYTALKER
Refused. You are not following the SMTP protocol.
DENIED_BLACKLIST_NAME
Refused. Your domain name is blacklisted.
DENIED_BLACKLIST_IP
Refused. Your IP address is blacklisted.
DENIED_SENDER_BLACKLISTED
Refused. Your sender address has been blacklisted.
DENIED_RECIPIENT_BLACKLISTED
Refused. Mail is not being accepted at this address.
DENIED_RBL_MATCH
The text returned from the DNS RBL or if the DNS RBL does not return any text:
Refused. Your IP address is listed in the DNS RBL at [RBLNAME]
DENIED_RHSBL_MATCH
The text returned from the RHSBL or if the RHSBL does not return any text:
Refused. Your domain name is listed in the RHSBL at [RHSBLNAME]
DENIED_SENDER_NO_MX
Refused. The domain of your sender address has no mail exchanger (MX).
DENIED_ACCESS_DENIED
Refused. Access is denied.
DENIED_RELAYING
Refused. Sending to remote addresses (relaying) is not allowed.
FAILED_AUTH
Refused. Authentication failed.
UNKNOWN_AUTH
Refused. Unknown authentication method.
FAILED_TLS
Failed to negotiate TLS connection.

If a policy location URL is given with the policy-url option, it will be appended to the end of the message, just in case a human ever reads it. This is mostly useful for debugging, in case someone is troubleshooting their connection to your server, trying to figure out why their email is being blocked. Regular users whose emails bounce won't see the message though; spammers have been delivering spam through bounce messages long enough that most MTAs now block the content of the bounce message.

Even if the user does get the text, there's a very slim chance the user will read it or click on anything inside -- most people see "returned mail" and click "delete".

Logging All Traffic

full-log-dir

spamdyke has the ability to log all SMTP traffic to files. This is very helpful when debugging but (depending on the mail server traffic levels) it can generate a huge number of files.

This feature is activated with the full-log-dir option. Each connection will be logged to a different file in the folder given, with the following naming convention:

YYYYMMDD_HHMMSS_IPADDRESS_RDNSNAME
Or if the remote server has no rDNS name:
YYYYMMDD_HHMMSS_IPADDRESS

The traffic from the remote server and qmail are both logged to the file. Each transmission is preceded with a line showing its origin and destination as well as the time and date. The origin/destination markers are:

<<< = traffic sent from qmail to the remote server
>>> = traffic sent from the remote server
<FF = traffic sent from spamdyke to the remote server (imitating a server)
FF> = traffic sent from spamdyke to qmail (telling qmail to quit)
<XX = traffic sent from qmail but discarded by spamdyke

If the remote client establishes a TLS session with qmail and spamdyke passes the encrypted traffic, the logs will contain the traffic as hexadecimal bytes.

Log files are created with a 0600 mode to protect them from being read by unauthorized users. Please take other precautions to protect them and don't leave them lying around.

NOTE: This feature is intended to be used for debugging delivery problems, not for monitoring email content. Among other issues, the format of the log files does not make it easy to reconstruct a whole message. If you must monitor your users' email traffic, please use a packet sniffer on a separate machine or SMTP proxy software designed for the task.

TLS

tls-certificate-file
tls-privatekey-file
tls-privatekey-password
tls-privatekey-password-file

TLS is another name for SSL, the same encryption protocol used by secure websites. (Why did they rename it? Who knows?) TLS can be used during SMTP to provide secure communications between the remote client and the server.

spamdyke supports TLS in two ways. First, by itself with no other information, spamdyke will identify a TLS conversation and simply pass the traffic back and forth between qmail and the remote client. In this mode, spamdyke cannot read the SMTP traffic (obviously -- it's encrypted). This prevents some of its filters from functioning, including graylisting, sender and recipient blacklisting, limiting the number of recipients, checking the sender's domain name for an MX record and relaying.

Second, spamdyke can provide TLS itself. To do this, it must be compiled with TLS support, which requires the OpenSSL libraries to be available (see the Installation instructions for details). The server certificate must also be provided with the tls-certificate-file parameter. In this mode, when the client asks to start a TLS session, spamdyke intercepts the request and negotiates TLS with the client. All of spamdyke's filters can remain active. qmail doesn't ever see the TLS traffic because spamdyke decrypts everything before passing it on to qmail. Because of this, spamdyke can offer TLS even if qmail hasn't been patched to provide it!

The server certificate file must be in PEM format. If the private key is not in the certificate file, it must be provided in PEM format with the tls-privatekey-file parameter. If the private key is encrypted with a password, the password must be provided with the tls-privatekey-password parameter. Because providing the private key password on the command line is very insecure, the password can also be contained in a file and loaded using the tls-privatekey-password-file parameter.

Generating self-signed certificates is very easy with OpenSSL. Countless tutorials are available on the web.

If there are any problems reading the certificate, the private key or decrypting the private key, spamdyke will log the errors to syslog and fall back to passing the TLS traffic through to qmail, if qmail has been patched to provide TLS (or spamdyke will send the remote client an error message if qmail doesn't provide TLS). spamdyke will also log the error messages produced by OpenSSL, even though they're rarely helpful.

NOTE: spamdyke does not disable any of its filters simply because a remote client uses TLS. In SMTP, TLS is simply a method of securing the communication channel. It is not an authentication method. While it's true spammers aren't using TLS and therefore any client that does use it is unlikely to be a spammer, there's no reason to assume that will be true forever. spamdyke will only disable its filters for clients it finds on its whitelists or ones that use SMTP AUTH.

If in doubt about enabling TLS, do it. Encrypting email traffic is always a good thing.

SMTP AUTH

hostname
hostname-command
hostname-file
smtp-auth-command
smtp-auth-command-encryption

SMTP AUTH is a mechanism for remote users to authenticate before sending email (defined in RFC 2554). This is very handy when users are likely to connect from remote locations (e.g. coffee shop hotspots) and want to bypass relaying restrictions and other filters.

spamdyke supports SMTP AUTH. If qmail has been patched to provide SMTP AUTH, spamdyke will observe the authentication and trust qmail's success/failure messages. When authentication is successful, spamdyke bypasses all of its filters. When authentication is unsuccessful, spamdyke enforces the enabled filters as normal.

If qmail has not been patched to provide SMTP AUTH, spamdyke will offer to do it instead. Because spamdyke runs as a middleman between the remote server and qmail, it can already add or remove data from the inbound or outbound traffic. At a specific point in the SMTP conversation, qmail should advertise an ability to process SMTP AUTH. If it does not, spamdyke inserts the advertisement. When the remote server responds, spamdyke processes the authentication and prevents qmail from seeing the authentication traffic it won't understand. Qmail doesn't know the authentication took place and spamdyke bypasses its filters. Clever, huh?

If qmail has been patched to provide SMTP AUTH, no options need to be given to spamdyke. spamdyke will silently observe the authentication and trust qmail's responses.

If qmail has not been patched to provide SMTP AUTH, one of two options should be used: smtp-auth-command or smtp-auth-command-encryption. The parameter for both options should be the full command line of the program used to process the authentications. If, for some reason, there are multiple places authentication can be checked, the options can each be given multiple times. spamdyke will run each command in turn before rejecting the authentication.

The first option, smtp-auth-command, should be used if the program processing authentications does not have access to cleartext copies of the user passwords and therefore can't authenticate challenge/response protocols. This is the case when authenticating system accounts found in /etc/password using DJB's checkpassword program. This is also the case when vpopmail is installed but was not compiled with cleartext password support (e.g. QmailToaster). Using this option prevents spamdyke from advertising challenge/response protocols.

The second option, smtp-auth-command-encryption should be used if the program processing authentications does have access to cleartext copies of the user passwords and can authenticate challenge/response protocols. This is the case when authenticating virtual accounts through vpopmail if vpopmail was compiled with cleartext password support.

Although both options can be used, there's no reason to do so. Using smtp-auth-command-encryption even once will cause spamdyke to advertise challenge/response protocols.

For example, on a server with vpopmail installed where vpopmail has been compiled with cleartext password support, the spamdyke command might look like this:

spamdyke --smtp-auth-command-encryption "/home/vpopmail/bin/vchkpw /bin/true" /var/qmail/bin/qmail-smtpd /home/vpopmail/bin/vchkpw /bin/true
On a server with vpopmail installed where vpopmail has been compiled without cleartext password support, the spamdyke command might look like this:
spamdyke --smtp-auth-command "/home/vpopmail/bin/vchkpw /bin/true" /var/qmail/bin/qmail-smtpd /home/vpopmail/bin/vchkpw /bin/true
On a server without vpopmail, the spamdyke command might look like this:
spamdyke --smtp-auth-command "/bin/checkpassword /bin/true" /var/qmail/bin/qmail-smtpd

If you are not certain whether to use smtp-auth-command or smtp-auth-command-encryption, use the config-test option to test one of them. spamdyke will test the command and indicate which option is appropriate. See Configuration Tests for details.

When using either option in a place where quoted parameters are not allowed (for example, in stunnel's configuration file), spaces can be replaced with commas. In other words, the following:

--smtp-auth-command "/bin/checkpassword /bin/true"
can be given as:
--smtp-auth-command /bin/checkpassword,/bin/true
spamdyke will convert the comma to a space before executing the command. Neither commas nor quotes are necessary in a spamdyke configuration file, however. In those files, spaces are valid.

Some challenge/response protocols, notably CRAM-MD5, use the name of the local host as part of their encrypted challenge. This is intended to frustrate known-plaintext attacks. spamdyke will attempt to find the local host's name several different ways. If the hostname option is used, the given value will be used. If the hostname-file option is used, the first line of the given file will be read and used as the name. If the hostname-command option is used, the given command will be run and the first line of its output will be used as the name. If none of those options are given, the environment variables TCPLOCALHOST and HOSTNAME will be checked. If either is set, its value will be used as the name. If no name can be found using any of those methods, spamdyke will use the name unknown.server.unknown.domain.

Setting the host's name correctly is not critical. It's only used to construct the challenge challenge and the protocol will work fine with any value. Setting it correctly makes the protocol slightly more secure but the tiny benefit is not worth a large hassle. If you can set it, do so. If it's a problem for some reason, ignore it.

If in doubt about enabling SMTP AUTH, do it. Authenticating your users is always a good thing.

Relaying

access-file

By default, spamdyke allows all relaying. However, if an access file is given with the access-file option, spamdyke will search the file for the incoming server's IP address and/or rDNS name. If the file doesn't allow the remote server to relay, spamdyke will block any attempts to do so. Whether a recipient is local is determined by searching the local domains file (given by local-domains-file; see Rejecting Senders and Recipients for details).

NOTE: spamdyke does not consider the sender address when deciding to block a recipient for relaying. Sender addresses can be (and usually are) forged by spammers.

Each line in the access file should use one of the following formats:

REMOTE_INFO@REMOTE_IP:ACCESS
REMOTE_INFO@=REMOTE_NAME:ACCESS
REMOTE_IP:ACCESS
REMOTE_NAME:ACCESS
:ACCESS

REMOTE_INFO is the value returned from an "info" query of the remote server. spamdyke doesn't perform "info" queries but tcpserver does (by default). It sets the TCPREMOTEINFO environment variable if it gets something. spamdyke uses TCPREMOTEINFO if it's set. (Does anyone actually use "info" any more?)

REMOTE_IP is the IP address of the remote server. It can also be a partial IP address, a dotted quad with ranges, a dotted quad with a number of bits or a dotted quad with a netmask. See IP Address Files for a full explanation of the acceptable formats.

REMOTE_NAME is the rDNS name of the remote server. It can also be a partial name. See rDNS Files for a full explanation of the acceptable formats.

ACCESS is the permission setting -- either allow or deny. Connections are allowed by default (if no match is found). If access is denied, no mail is accepted at all, whether relayed or not.

Blank lines and lines starting with # are ignored.

The end of each line may optionally specify a series of environment variables to be set before qmail is started. They should use the following format and be separated by commas:

NAME="VALUE"
Confusingly, the double quotes shown above can actually be any character, if the value contains double quotes (escaped values are not supported). For example:
NAME=.VALUE.

For example, if the remote server's IP address is 11.22.33.44 and its rDNS name is mail.example.com, each of the following lines will match, allow connections and set several environment variables:

11.22.33.44:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
11.20-100.33.44:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
11.22.:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
11.22.33.0/24:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
11.22.0.0/255.255.0.0:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
=mail.example.com:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
=.example.com:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
=.com:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-
:allow,FOOVAR="foovalue",BARVAR=.barvalue.,BAZVAR=-bazvalue-

Conveniently, this is exactly the format tcpserver uses for its /etc/tcp.smtp file. NOTE: spamdyke can't read CDB files, only the plain text file, so be careful which file you list on the command line.

Remote servers are allowed to relay if the environment variable RELAYCLIENT is set to any value. Most qmail guides recommend an entry like this one:

11.22.33.44:allow,RELAYCLIENT=""

NOTE: Because tcpserver and qmail already handle relaying using this same system, there are only two reasons to use spamdyke for it. First, spamdyke will log every relaying attempt it blocks. This can be handy for troubleshooting or tracking.

Second, if you're using a qmail installation that isn't patched to provide SMTP AUTH and you're using spamdyke to provide SMTP AUTH, you need to use spamdyke to block relaying instead of qmail. Otherwise, when users authenticate from remote locations, qmail won't know about it and will still block them for relaying. In that case, using access-file is required.

Reverse DNS

ip-in-rdns-keyword-file
reject-empty-rdns
reject-ip-in-cc-rdns
reject-unresolvable-rdns

Reverse DNS is the part of the DNS system that maps IP addresses back to names. If you don't understand reverse DNS, please please please read one of the (thousands of) online tutorials on the subject. Every mail server administrator should know about reverse DNS. It's not complicated. Please take the time to learn it.

spamdyke does a lot of work with rDNS names. The first and most basic test is to make sure the remote server has an rDNS name, any name. This filter is activated with the reject-empty-rdns option. AOL and most other major ISPs use this test. By default, this filter is not run.

The next test is to make sure the remote server's rDNS name resolves. This test only attempts to get at least one IP address from the name. It does not require the rDNS name's IP address to match the remote server's IP address. For example, if the remote server's IP address is 11.22.33.44 and its rDNS name is mail.example.com, this test will lookup mail.example.com. If the IP address 66.77.88.99 is found, the test will pass. Note: The name localhost is handled specially. If the rDNS name is localhost and the IP address is not 127.0.0.1, the test fails. This filter is activated with the reject-unresolvable-rdns option. By default, this filter is not run.

NOTE: reject-unresolvable-rdns does not imply reject-empty-rdns. In other words, using just the reject-unresolvable-rdns option will block connections from servers with unresolvable rDNS names but it will not block connections from servers with no rDNS names at all. Most users will want to use reject-empty-rdns if they use reject-unresolvable-rdns.

spamdyke will also look for an IP address in the rDNS name, since that typically indicates a server sending email that shouldn't be (e.g. a virus-infected Windows machine on a cable modem). spamdyke looks for the IP address in many forms; for example, if the IP address is 11.22.33.44, spamdyke will look for the following patterns in the rDNS name (the dots in the examples below can be any single character):

11.22.33.44
011.022.033.044
44.33.22.11
44.11.22.33
33.22.11.44
44.33.1122
3344.11.22
11.22.8492 (last two octets combined and converted to an integer)
11223344
011022033044
11022033044
1122033044
112233044
44332211
044033022011
3930621781 (entire address converted to an integer)
5080d7e3 (each octet converted to hexadecimal)

If the IP address is found in the rDNS name, one of two conditions will trigger the filter. One is if the rDNS name contains a keyword listed in a specified file. This is activated with the ip-in-rdns-keyword-file option. Each keyword must be listed on its own line. Blank lines and lines beginning with # are ignored. If the ip-in-rdns-keyword-file option is given multiple times, each given keyword file will be checked before the connection is allowed.

For example, if the IP address is 11.22.33.44, the rDNS name is 11.22.33.44.dynamic.example.com and the keyword file contains dynamic, the connection will be blocked. NOTE: The keyword will not match the domain name. In other words, this test will not find example in 11.22.33.44.dynamic.example.com. To use domain names as keywords, they must be preceded with a dot. This test will block connections from 11.22.33.44.dynamic.example.com if the keyword file contains .example.com or even just .com.

Because ISPs don't use a consistent naming system for dynamic connections, sometimes more complex patterns are needed. For example, there may be a need to block connections with a keyword from a specific domain name without applying that keyword to other domain names. To do this, the keywords should be separated by spaces and put on the same line.

For example, this test will block connections from customer-11.22.33.44.example.com (IP address 11.22.33.44) if the keyword file contains customer .example.com. Connections will be allowed from customer-11.22.33.44.example.net.

One more IP/rDNS test is available. The rDNS name is searched for the IP address as above but instead of looking for a keyword, any country code will match. This is activated with the reject-ip-in-cc-rdns option. For example, if the remote server's IP address is 11.22.33.44 and its rDNS name is 11.22.33.44.example.com.us, the connection will be blocked. This test is convenient for monolingual US-based ISPs (like the author). To block a specific list of country codes, use ip-in-rdns-keyword-file and list the country codes in the keyword file (each preceeded by a dot).

Blacklists

ip-blacklist-file
rdns-blacklist-dir
rdns-blacklist-file

First, let's all agree that blacklists are evil, arbitrary, unforgiving, unfair, etc, etc, blah blah blah. OK. If you feel that way, don't use one. No one's forcing you to.

But, if you decide to use one, it can block over half the spam you would otherwise receive. Blacklists are very effective against professional spammers who buy thousands of domain names and run their own mail servers (constantly moving them around, of course). It's your call.

NOTE: Constructing and maintaining a blacklist is left as an exercise for the reader. spamdyke will use a blacklist but it won't help you build one.

spamdyke will search for the remote server's rDNS name in a file and block the connection if it is found. This is activated with the rdns-blacklist-file option. See rDNS Files for details on the format of this file. If the rdns-blacklist-file option is given multiple times, each file will be checked before the connection is allowed.

spamdyke will also search for the remote server's rDNS name in a directory structure and block the connection if it is found. For large lists of rDNS names (more than 100), the directory structure is much faster than a file. This is activated with the rdns-blacklist-dir option. See rDNS Directories for details on the structure of this directory. If the rdns-blacklist-dir option is given multiple times, each directory will be checked before the connection is allowed.

spamdyke will also search for the remote server's IP address in a file and block the connection if it is found. This is activated with the ip-blacklist-file option. See IP Address Files for details on the format of this file. If the ip-blacklist-file option is given multiple times, each blacklist file will be checked before the connection is allowed.

DNS RBLs

check-dnsrbl

DNS Realtime Blackhole Lists are services maintained by third parties that list IP addresses (presumably the IP addresses of spammers). The criteria for getting listed on a DNS RBL vary by organization and it's often very hard to get delisted. Sometimes, listings are politically motivated; some DNS RBL operators try to force large ISPs to cancel spammers' accounts by listing all of the ISP's IP addresses, innocent or guilty. If you choose to use a DNS RBL, please do some preliminary research to understand its policies and history of complaints.

spamdyke will reject connections from an IP address listed in a given DNS RBL. This feature is activated with the check-dnsrbl option. By default, spamdyke does not use a DNS RBL. If the check-dnsrbl option is given multiple times, each DNS RBL will be checked before the connection is allowed.

DNS RHSBLs

check-rhsbl

DNS Righthand-side Blacklists are services maintained by third parties that list domain names (presumably the domain names of spammers). The criteria for getting listed on a DNS RHSBL vary by organization and it's often very hard to get delisted. Sometimes, listing are politically motivated; some DNS RHSBL operators try to force large ISPs to cancel spammers' accounts by listing all of the ISP's domain names, innocent or guilty. If you choose to use a DNS RHSBL, please do some preliminary research to understand their policies and history of complaints.

spamdyke will reject connections from servers whose reverse DNS names are listed in a given DNS RHSBL. spamdyke will also reject connections from senders whose email domain names are listed in a given DNS RHSBL. These features are activated with the check-rhsbl option. By default, spamdyke does not use a DNS RHSBL. If the check-rhsbl option is given multiple times, each DNS RHSBL will be checked before the connection is allowed.

Whitelists

ip-whitelist-file
rdns-whitelist-dir
rdns-whitelist-file

spamdyke will search for the base domain name of the remote server's rDNS name in a file and skip all filters if it is found. This is activated with the rdns-whitelist-file option. See rDNS Files for details on the format of this file. If rdns-whitelist-file option is given multiple times, each whitelist file will be checked before the connection is blocked.

spamdyke will also search for the base domain name of the remote server's rDNS name in a directory structure and skip all filters if it is found. This is activated with the rdns-whitelist-dir option. See rDNS Directories for details on the format of this directory structure. If rdns-whitelist-dir option is given multiple times, each directory will be checked before the connection is blocked.

spamdyke will also search for the remote server's IP address in a file and skip all filters if it is found. This is activated with the ip-whitelist-file option. See IP Address Files for details on the format of this file. If the ip-whitelist-file option is given multiple times, each whitelist file will be checked before the connection is blocked.

Rejecting Senders and Recipients

local-domains-file
recipient-blacklist-file
reject-missing-sender-mx
sender-blacklist-file

It's rare, but sometimes spammers will choose to target a specific address and pound it with millions of messages. Most often, this happens when a spammer chooses to use one of your email addresses as the sender address on a spam run. When that happens, you'll receive bounce messages for all of their spams.

spamdyke will block all incoming messages to a specific address with the recipient-blacklist-file option. The given file must contain one email address per line. Blank lines and lines beginning with # are ignored. If the recipient-blacklist-file option is given multiple times, each blacklist file will be checked before the connection is blocked.

One form of wildcard address is supported. All usernames within a domain (and its subdomains) may be blocked by a line starting with @. For example, if the file contained the following entry:

@example.com
spamdyke will block mail to fred@example.com, fred@mail.example.com, barney@mail.internal.example.com, etc.

Similarly, spammers will rarely (but occasionally) use the same sender address for a while. spamdyke will block all incoming messages from a specific address with the sender-blacklist-file option. The file format is identical to the recipient blacklist file, described above.

spamdyke will also look at the sender's domain name to check if it has a mail exchanger or an IP address listed in DNS. If a mail exchanger is found, the mail exchanger must have an IP address. Without a valid mail exchanger or an IP address, no mail could possibly go to the sender address. This test tends to block a lot of mail from web servers that aren't supposed to be sending email. It is activated with the reject-missing-sender-mx option. By default, this test is not run.

To use the reject-missing-sender-mx option, a file must be provided that contains a list of the local domains. This is necessary because if your server is willing to receive mail for a given domain, it must be a mail exchanger for that domain, no matter what DNS says.

The local domain list is provided with the local-domains-file option. The file should contain one domain name per line. For example, if the file contained example.com, a message from fred@example.com would not be be blocked by reject-missing-sender-mx (although the message may still be blocked by other filters). If the local-domains-file option is given multiple times, each file will be checked before any action is taken.

The local domain list also supports wildcards. If a domain name in the file starts with a dot, any sender address within a subdomain will also pass the reject-missing-sender-mx filter. For example, if the provided file contained .example.com, then fred@foo.example.com, barney@bar.example.com and wilma@example.com would all pass the reject-missing-sender-mx filter, no matter what DNS records exist for their domain.

Conveniently, this wildcard system matches the system used in qmail's controls/rcpthosts file.

DNS Whitelists

check-dns-whitelist
check-rhs-whitelist

spamdyke has the ability to consult DNS whitelists and allow connections from hosts or senders who match entries on them. DNS whitelists are essentially DNS RBLs and DNS RHSBLs that list allowed IP addresses and domain names instead of blocked ones. All of the same cautionary statements apply to DNS whitelists as to DNS blacklists. See DNS RBLs and DNS RHSBLs for details.

To use a DNS Realtime Whitelist (the opposite of a DNS RBL), the option check-dns-whitelist should be given. To use a DNS Righthand-side Whitelist, the option check-rhs-whitelist should be given. By default, spamdyke does not use a DNS whitelist. If either option is given multiple times, each list will be consulted before the connection is blocked.

Whitelisting Senders and Recipients

recipient-whitelist-file
sender-whitelist-file

Sometimes, adding IP addresses and reverse DNS names to whitelist files is not enough to satisfy some users. Either they continue to receive mail from unexpected places or the just think spamdyke is blocking their email. In those cases, the last resort can be to whitelist the sender or recipient address.

NOTE: Using these features is a bad idea! Sender addresses are very easy to forge; this is why spam is so hard to block. Recipient addresses are obviously already known to the spammers; this is why spam is delivered. Whitelisting any addresses this way will allow spam to get through.

To use the sender-whitelist-file option, a file must be provided that contains a list of the sender addresses to be whitelisted. To use the recipient-whitelist-file option, a file must be provided that contains a list of recipient addresses to be whitelisted. The file formats are identical to that for recipient-blacklist-file. See Rejecting Senders and Recipients for details.

Graylisting / Greylisting

always-graylist-ip-file
always-graylist-rdns-dir
always-graylist-rdns-file
graylist-dir
graylist-max-secs
graylist-min-secs
never-graylist-ip-file
never-graylist-rdns-dir
never-graylist-rdns-file
no-graylist-dir

Graylisting is the technique of denying mail delivery the first time a sender tries to deliver to a recipient. The next time the remote server attempts to deliver the message, it is accepted. All future messages from the sender to the recipient are also allowed.

Graylisting works because spammers don't use real mail servers, so when the initial delivery fails, they don't retry it. Even if they do, they change to a different random sender address, which is also graylisted.

spamdyke's graylisting is activated first with the graylist-dir or no-graylist-dir options, then on a per-domain basis by creating a subfolder for the domain name. If it does not exist, the message is not graylisted.

The domain folders must be created before graylisting will work. This is the most common mistake when setting up spamdyke to perform graylisting.

NOTE: The names of the domain directories used for graylisting must be lowercase or spamdyke will not match them. Unfortunately, searching a case sensitive filesystem in a case insensitive manner is simply not practical.

For example, if the graylist folder is /tmp/graylist, the sender address is sender@example.com and the recipient address recipient@foo.com, spamdyke's graylisting system would use the following logic:

Test YES NO
Does the domain folder /tmp/graylist/foo.com exist? Proceed to next step. Accept the message and stop.
Does the recipient folder /tmp/graylist/foo.com/recipient exist? Proceed to next step. Create the recipient folder and proceed to the next test.
Does the sender file /tmp/graylist/foo.com/recipient/sender@example.com exist? Update the file's timestamp, accept the message and stop. Create the file, reject the message and stop.
The options graylist-min-secs and graylist-max-secs can be used to further restrict deliveries. When graylist-min-secs is used, simply finding the sender file is no longer enough. It must be at least a certain age (a number of seconds old) before it is valid. This option prevents spammers from defeating the graylist by attempting a delivery twice in rapid succession.

When graylist-max-secs is used, the sender file is invalidated (ignored) once it reaches a certain age (a number of seconds old). This option forces infrequent senders to go through the graylist process again. Note: a sender file's timestamp is updated each time a message is accepted. Frequent senders will not be affected by graylist-max-secs.

The graylist-dir option activates graylisting for all connections. If graylist-dir is given multiple times, each graylist folder is searched for the domain folder.

Connections can be exempted from graylisting if the IP address of the remote server matches a line in a file given with the never-graylist-ip-file option. See IP Address Files for details on the format of this file. If never-graylist-ip-file is given multiple times, each file will be searched before the connection is graylisted.

Connections can also be excepted from graylisting if the rDNS name of the remote server matches a line in a file given with the never-graylist-rdns-file option. See rDNS Files for details on the format of this file. If never-graylist-rdns-file is given multiple times, each file will be searched before the connection is graylisted.

Connections can also be excepted from graylisting if the rDNS name of the remote server matches a file in a directory structure specified with the never-graylist-rdns-dir option. See rDNS Directories for details on the format of this directory structure. If never-graylist-rdns-dir is given multiple times, each directory will be searched before the connection is graylisted.

The no-graylist-dir option dectivates graylisting for all connections. If no-graylist-dir is given multiple times, each graylist folder is searched for the domain folder.

When no-graylist-dir is used, connections will only be graylisted if the IP address of the remote server matches a line in a file specified with the always-graylist-ip-file option. See IP Address Files for details on the format of this file. If the always-graylist-ip-file option is given multiple times, each file will be searched before the connection is graylisted.

Alternatively, connections will be graylisted if the rDNS name of the remote server matches a line in a file specified with the always-graylist-rdns-file option. See rDNS Files for details on the format of this file. If always-graylist-rdns-file option is given multiple times, each file will be searched before the connection is graylisted.

Connections will also graylisted if the rDNS name of the remote server matches a file in a directory structure specified with the always-graylist-rdns-dir option. See rDNS Directories for details on the format of this directory structure. If always-graylist-rdns-dir is given multiple times, each directory will be searched before the connection is graylisted.

NOTE: The two options graylist-dir and no-graylist-dir are mutually exclusive; only one should be used.

Graylisting is a relatively new idea (as of 2007) and not very many ISPs are using it yet, so it's surprisingly effective. Spammers will undoubtedly work around it eventually.

Earlytalkers

greeting-delay-secs

Several years back, someone noticed that some spam software didn't follow the SMTP protocol. Specifically, spammers were opening connections to remote mail servers and pushing out all of the mail commands as quickly as they could, without waiting for (or checking) responses. By delaying the sending of the greeting banner, it's possible to catch these spammers and block them.

Unfortunately, as of 2007, spammers have mostly updated their software so this trick doesn't work any more. It still catches a few of them occasionally though.

spamdyke will delay sending the opening greeting in order to wait for the sender to send data. If that happens, spamdyke will block the connection. This is activated with the greeting-delay-secs option.

Even if it doesn't catch the spammers any more, this is still a good test to run because it slows down the rate at which spammers can send email. Making it more expensive for them is not a bad thing.

Limiting Numbers of Recipients

max-recipients

RFC 821 says an SMTP server must allow the remote server to specify as many recipients as the SMTP server has memory to hold. This allows spammers to send a single message to (potentially) thousands of users in one connection.

spamdyke offers a way to violate the RFC by limiting the number of recipients per message to some value. Once that number has been reached, the remaining recipients will be rejected. Legitimate mail servers use the multi-recipient feature as well, but they will retry their deliveries. Spammers generally don't.

This feature is activated by the max-recipients option. By default, spamdyke allows unlimited recipients per connection.

If you enable this feature, make sure all of your users are using SMTP AUTH or are allowed to relay or are whitelisted. Otherwise, their MUAs will show them error messages when they try to send to large address book mailing lists and they will complain. Loudly.

Timeouts

connection-timeout-secs
idle-timeout-secs

Most spam software is pretty stupid and doesn't handle error codes from SMTP servers. Instead, they send their commands and wait for specific responses. When those responses don't come, the software just sits forever and waits.

spamdyke will time out these connections in one of two ways. First, an absolute time limit can be imposed on a connection. This is activated with the connection-timeout-secs option. If this feature is enabled, it should be set to a very high value. Large (legitimate) messages can take a very long time to deliver, especially if the link is slow. A value of 0 disables this feature. By default, this feature is not activated.

Second, an idle time limit can be imposed on a connection. This is activated with the idle-timeout-secs option. If no data is received within the given number of seconds, the connection is closed. A value of 0 disables this feature. By default, this feature is activated with a value of 60.

Extra Utilities

There are some additional programs included with spamdyke in the utils folder. They are:

domain2path
A utility for constructing rDNS folder paths from domain names. Useful in scripts. See rDNS Directories for details on domain2path.
domainsplit
A utility for finding the base domain name of a fully qualified domain name. For example, given foo.bar.baz.example.com, domainsplit will return example.com. Also useful in scripts.
dnsa
An example program that demonstrates finding DNS A records (IP addresses) for fully qualified domain names.
dnsany
An example program that demonstrates finding DNS records of "any" type (which doesn't actually return all types) for fully qualified domain names.
dnsany_libc
An example program that demonstrates finding DNS records of "any" type (which doesn't actually return all types) for fully qualified domain names. This version uses the system resolver library instead of sending UDP packets itself.
dnscname
An example program that demonstrates finding DNS CNAME records (alias names) for fully qualified domain names.
dnsmx
An example program that demonstrates finding DNS MX records (mail exchangers) for domain names.
dnsns
An example program that demonstrates finding DNS NS records (nameservers) for domain names.
dnsptr
An example program that demonstrates finding DNS PTR records (reverse DNS names) for fully qualified domain names or IP addresses.
dnssoa
An example program that demonstrates finding DNS SOA records (start-of-authority) for domain names.
dnstxt
An example program that demonstrates finding DNS TXT records (text information) for fully qualified domain names.

None of these utilities depend on being installed in any specific folder. None of them depend on the presence of the others or spamdyke. spamdyke does not require them or use them.