Current Release

5/1/2014: Version 5.0.1

Many, many bug fixes, including a large number of bugs that can cause crashes. spamdyke-qrv has also received a great deal of attention and now handles every strange configuration qmail can support.

Download spamdyke version 5.0.1

Previous Releases

1/28/2014: Version 5.0.0

Adds full recipient validation and some new sender filters. Also changes the whitelisting feature to not automatically allow relaying for whitelisted connections and fixes a number of bugs.

Download spamdyke version 5.0.0
View the upgrade notes

1/20/2012: Version 4.3.1

Corrects a bug in the new header blacklist filter that could cause erroneous errors and incorrect message rejections.

Download spamdyke 4.3.1

1/15/2012: Version 4.3.0

Adds the ability to filter messages based on the content of their headers. Also fixes some small bugs, a compile error on Debian 7 and a major series of bugs that could result in buffer overflows (possibly remotely exploitable, depending on the configuration options). Please upgrade immediately!

Download spamdyke 4.3.0

spamdyke Documentation

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

This document applies to spamdyke version 5.0.1.

Other Documentation

The following additional documents are available:
Installation instructions: INSTALL.txt
Upgrading instructions: UPGRADING.txt
Frequently Asked Questions: FAQ.html
Change log: Changelog.txt
To-do list: TODO.txt

About spamdyke

help
more-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 ©2015 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 list of the available options. The --more-help command line option will give a more detailed list of available options and their default values. The --version command line option will give just the version and copyright statement.

Support

spamdyke support is available from the spamdyke-users 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.

All of the spamdyke documentation and downloadable files are available from the spamdyke website: www.spamdyke.org.

If all else fails, email the author 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. Unlike most other mail servers, 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.
Because qmail's strict enforcement of the protocol tends to cause more problems than it solves, spamdyke silently helps mail clients avoid this error by inserting a carriage return before any bare line feed characters it sees. This doesn't affect the messages, it only allows poorly-written mail clients to send email.

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 the enabled filters and waits until there is no way the client can avoid a rejection. For example, if authentication could take place but has not done so, spamdyke will wait to see if the remote sender authenticates. Authenticated or whitelisted 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 closes the connection to qmail, so qmail will exit normally, believing the remote sender disconnected.

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 server 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 (or both).

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, which restricts the maximum number of recipients per message. On the command line, limiting the number of recipients to 5 might look 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

If the option's value contains spaces, it should be surrounded by quotes on the command line. For example, consider the rejection-text-ip-blacklist option, which changes the error message spamdyke sends if the remote server's IP address is blacklisted. On the command line, changing the message might look like this:

spamdyke --rejection-text-ip-blacklist "Go away spammer" ...
However, in a configuration file quotes are not allowed, so the entry would look like this:
rejection-text-ip-blacklist=Go away spammer

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 run-as-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 to test authentication processing. Use PASSWORD as the authentication password. This option has no effect unless config-test, config-test-smtpauth-username and smtp-auth-command are given.

If config-test-smtpauth-password is given multiple times, spamdyke will use the last value it finds.

If config-test-smtpauth-password is not given, spamdyke will not test the authentication command(s).

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 to test authentication processing. Use USERNAME as the authentication username. This option has no effect unless config-test, config-test-smtpauth-password and smtp-auth-command are given.

If config-test-smtpauth-username is given multiple times, spamdyke will use the last value it finds.

If config-test-smtpauth-username is not given, spamdyke will not test the authentication command(s).

See Configuration Tests for details.
help h   Displays a brief list of spamdyke's options, then exits.
more-help     Displays a detailed summary of spamdyke's options and their default values, 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. Some options are not valid in files within configuration directories; those options are noted below. See Configuration Directories for details.

Long Version Short Version
(command line only)
Parameter Description
config-dir   DIR Search the directory structure starting at DIR for configuration files that match the remote server's IP address, the remote server's rDNS name, the sender's email address, the recipient's email address or any combination of the four criteria.

If config-dir is given multiple times, each DIR is scanned (in the given order) until a match is found.

If config-dir is not given, spamdyke will not scan any directories for configuration files.

config-dir is not valid within configuration directories.

See Configuration Directories for details.
config-dir-search   first, all-ip, all-rdns, all-sender or all-recipient Search the directory structure given by config-dir using the given search rules.

If config-dir-search is given multiple times, the given values are used in combination.

If config-dir-search is not given, spamdyke will use a value of first.

config-dir-search is not valid within configuration directories.

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

If config-file is given multiple times, each FILE is read in the given order.

If config-file is not given, spamdyke will not read a configuration file.

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.

If connection-timeout-secs is given multiple times, spamdyke will use the last value it finds.

If connection-timeout-secs is not given, spamdyke will not enforce a connection timeout.

connection-timeout-secs is not valid within configuration directories.

See Timeouts for details.
dns-blacklist-entry x DNSRBL Check the remote server's IP address against the realtime blackhole list DNSRBL. If it is found, the connection is rejected. NOTE: Using more than a few DNS blacklists can cause serious performance problems.

If dns-blacklist-entry is given multiple times, spamdyke will check each given DNSRBL for the remote server's IP address.

If dns-blacklist-entry and dns-blacklist-file are not given, spamdyke will not check any blackhole lists.

See DNS RBLs for details.
dns-blacklist-file   FILE Check the remote server's IP address against each of the realtime blackhole lists listed in FILE. If it is found on any of the lists, the connection is rejected. NOTE: Using more than a few DNS blacklists can cause serious performance problems.

If dns-blacklist-file is given multiple times, spamdyke will check each of the blackhole lists listed in each of the files for the remote server's IP address until a match is found.

If dns-blacklist-entry and dns-blacklist-file are not given, spamdyke will not search any files for blackhole lists.

See DNS RBLs for details.
dns-level   none, normal or aggressive none: Do not perform any DNS queries. All DNS-based filters will behave as though no response was received from any nameserver.

normal: Send single DNS queries to one nameserver at a time and wait for responses. This mimics the standard system resolver library's behavior.

aggressive: Send multiple DNS queries to multiple DNS servers simultaneously to find answers as quickly as possible.

If dns-level is given multiple times, spamdyke will use the last value it finds.

If dns-level is not given, spamdyke will use a value of aggressive.

dns-level is not valid within configuration directories.

See DNS Queries for details.
dns-max-retries-primary   NUM Query the primary nameserver(s) NUM times before also querying the secondary nameserver(s). If NUM is larger than the value of dns-max-retries-total, the value of dns-max-retries-total is used instead.

If dns-max-retries-primary is given multiple times, spamdyke will use the last value it finds.

If dns-max-retries-primary is not given, spamdyke will use a value of 1.

dns-max-retries-primary is not valid within configuration directories.

See DNS Queries for details.
dns-max-retries-total   NUM Send a maximum of NUM queries to any nameserver(s), primary or secondary.

If dns-max-retries-total is given multiple times, spamdyke will use the last value it finds.

If dns-max-retries-total is not given, spamdyke will use a value of 3.

dns-max-retries-total is not valid within configuration directories.

See DNS Queries for details.
dns-query-type-a   a or cname a: Request A records when querying for IP addresses.

cname: Request CNAME records when querying for IP addresses.

If dns-query-type-a is given multiple times, spamdyke will use a combination of the given values.

If dns-query-type-a is not given, spamdyke will use a value of a and cname.

dns-query-type-a is not valid within configuration directories.

See DNS Queries for details.
dns-query-type-mx   a, cname or mx a: Request A records when querying for mail servers.

cname: Request CNAME records when querying for mail servers.

mx: Request MX records when querying for mail servers.

If dns-query-type-mx is given multiple times, spamdyke will use a combination of the given values.

If dns-query-type-mx is not given, spamdyke will use a value of a, cname and mx.

dns-query-type-mx is not valid within configuration directories.

See DNS Queries for details.
dns-query-type-ptr   cname or ptr cname: Request CNAME records when querying for reverse DNS names.

ptr: Request PTR records when querying for reverse DNS names.

If dns-query-type-ptr is given multiple times, spamdyke will use a combination of the given values.

If dns-query-type-ptr is not given, spamdyke will use a value of cname and ptr.

dns-query-type-ptr is not valid within configuration directories.

See DNS Queries for details.
dns-query-type-rbl   a, cname or txt a: Request A records when querying DNS RBLs and DNS RHSBLs.

cname: Request CNAME records when querying DNS RBLs and DNS RHSBLs.

txt: Request TXT records when querying DNS RBLs and DNS RHSBLs.

If dns-query-type-rbl is given multiple times, spamdyke will use a combination of the given values.

If dns-query-type-rbl is not given, spamdyke will use a value of a, cname and txt.

dns-query-type-rbl is not valid within configuration directories.

See DNS Queries for details.
dns-resolv-conf   FILE Read FILE for the list of system nameservers and other options (e.g. ports, timeouts).

If dns-resolv-conf is given multiple times, each of the given files will be read.

If dns-resolv-conf is not given, spamdyke will read the list of nameservers from /etc/resolv.conf.

dns-resolv-conf is not valid within configuration directories.

See DNS Queries for details.
dns-server-ip   IPADDRESS[:PORT] Use IPADDRESS as a secondary nameserver. If PORT is given, DNS queries will be send to that port number.

If dns-server-ip is given multiple times, each of the given nameservers will be queried.

If dns-server-ip and dns-server-ip-primary are not given, spamdyke will read the list of nameservers from /etc/resolv.conf.

dns-server-ip is not valid within configuration directories.

See DNS Queries for details.
dns-server-ip-primary   IPADDRESS[:PORT] Use IPADDRESS as a primary nameserver. If PORT is given, DNS queries will be send to that port number.

If dns-server-ip-primary is given multiple times, each of the given nameservers will be queried before any secondary nameservers are queried.

If dns-server-ip and dns-server-ip-primary are not given, spamdyke will read the list of nameservers from /etc/resolv.conf.

dns-server-ip-primary is not valid within configuration directories.

See DNS Queries for details.
dns-spoof   accept-all, accept-same-ip, accept-same-port or reject accept-all: Do not check for UDP packet spoofing.

accept-same-ip: Accept UDP packets from the same IP address query packets were sent to, even if the port number is different.

accept-same-port: Accept UDP packets from the same port number query packets were sent to, even if the IP address is different.

reject: Reject all UDP packets that do not come from the same IP address and port number the query packets were sent to.

If dns-spoof is given multiple times, spamdyke will use the last value it finds.

If dns-spoof is not given, spamdyke will use the value accept-all.

dns-spoof is not valid within configuration directories.

See DNS Queries for details.
dns-tcp   none or normal Control's whether spamdyke will perform DNS queries over TCP. If normal is given, spamdyke will use TCP for queries as needed (i.e. when a nameserver replies via UDP that a TCP query is required). If none is given, spamdyke will never use TCP for DNS queries.

If dns-tcp is given multiple times, spamdyke will use the last value it finds.

If dns-tcp is not given, spamdyke will use the value normal.

dns-tcp is not valid within configuration directories.

See DNS Queries for details.
dns-timeout-secs   SECS Do not take more than a total of SECS seconds to perform a DNS query, including all of the retries.

If dns-timeout-secs is given multiple times, spamdyke will use the last value it finds.

If dns-timeout-secs is not given, spamdyke will use the value 30.

dns-timeout-secs is not valid within configuration directories.

See DNS Queries for details.
dns-whitelist-entry   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. NOTE: Using more than a few DNS whitelists can cause serious performance problems.

If dns-whitelist-entry is given multiple times, spamdyke will check each given DNSWHITELIST for the remote server's IP address.

If dns-whitelist-entry and dns-whitelist-file are not given, spamdyke will not check any DNS whitelists.

See DNS Whitelists for details.
dns-whitelist-file   FILE Check the remote server's IP address against each of the DNS whitelists (essentially a DNSRBL that contains whitelisted IPs) listed in FILE. If it is found on any of the lists, all filters are bypassed. NOTE: Using more than a few DNS whitelists can cause serious performance problems.

If dns-whitelist-file is given multiple times, spamdyke will check each DNS whitelist listed in each given FILE for the remote server's IP address.

If dns-whitelist-entry and dns-whitelist-file are not given, spamdyke will not check any DNS whitelists.

See DNS Whitelists for details.
filter-level   allow-all, normal, require-auth or reject-all allow-all: Allow all connections to bypass all filters, effectively whitelisting everything.

normal: Apply enabled filters according to the options on the command line and in the configuration file(s).

require-auth: Reject all connections that haven't authenticated using SMTP AUTH.

reject-all: Reject all connections, regardless of authentication or whitelists.

If filter-level is given multiple times, spamdyke will use the last value it finds.

If filter-level is not given, spamdyke will use a value of normal.

See Filter Levels for details.
full-log-dir L DIR Log all SMTP data to files in DIR. This is handy for troubleshooting delivery problems but it is not meant to be used long-term. This option imposes a performance penalty!

If full-log-dir is given multiple times, spamdyke will use the last value it finds.

If full-log-dir is not given, spamdyke will not log all SMTP data.

full-log-dir is not valid within configuration directories.

See Logging All Data for details.
graylist-dir g DIR Search for and create graylist files in directory structures within DIR. This option has no effect unless graylist-level is given.

If graylist-dir is given multiple times, spamdyke will search each given directory in the given order for the recipient's domain directory and stop when it finds the first one.

If graylist-dir is not given, spamdyke will not graylist connections.

See Graylisting / Greylisting for details.
graylist-exception-ip-entry   IPADDRESS Reverse the behavior of the graylist filter for remote servers whose IP addresses match IPADDRESS. This option has no effect unless graylist-level and graylist-dir are given.

If graylist-exception-ip-entry is given multiple times, spamdyke will match the remote server's IP address against given IPADDRESS.

If graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry and graylist-exception-rdns-file are not given, spamdyke will graylist each connection according to the value of graylist-level.

See Graylisting / Greylisting for details.
graylist-exception-ip-file   FILE Reverse the behavior of the graylist filter for remote servers whose IP addresses match entries in FILE. This option provides better performance than graylist-exception-ip-entry for more than a few entries. This option has no effect unless graylist-level and graylist-dir are given.

If graylist-exception-ip-file is given multiple times, spamdyke will match the remote server's IP address against each entry in each given FILE.

If graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry and graylist-exception-rdns-file are not given, spamdyke will graylist each connection according to the value of graylist-level.

See Graylisting / Greylisting for details.
graylist-exception-rdns-dir   DIR Reverse the behavior of the graylist filter for remote servers whose rDNS names match files in DIR. This option provides much better performance than graylist-exception-rdns-file for large numbers of entries. This option has no effect unless graylist-level and graylist-dir are given.

If graylist-exception-rdns-dir is given multiple times, spamdyke will search each DIR for files that match the remote server's rDNS name.

If graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry and graylist-exception-rdns-file are not given, spamdyke will graylist each connection according to the value of graylist-level.

See Graylisting / Greylisting for details.
graylist-exception-rdns-entry   RDNSNAME Reverse the behavior of the graylist filter for remote servers whose rDNS names match RDNSNAME. This option has no effect unless graylist-level and graylist-dir are given.

If graylist-exception-rdns-entry is given multiple times, spamdyke will match the remote server's rDNS name against each given RDNSNAME.

If graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry and graylist-exception-rdns-file are not given, spamdyke will graylist each connection according to the value of graylist-level.

See Graylisting / Greylisting for details.
graylist-exception-rdns-file   FILE Reverse the behavior of the graylist filter for remote servers whose rDNS names match entries in FILE. This option provides better performance than graylist-exception-rdns-entry for more than a few entries. This option has no effect unless graylist-level and graylist-dir are given.

If graylist-exception-rdns-file is given multiple times, spamdyke will match the remote server's rDNS name against each entry in each given FILE.

If graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry and graylist-exception-rdns-file are not given, spamdyke will graylist each connection according to the value of graylist-level.

See Graylisting / Greylisting for details.
graylist-level   none, always, always-create-dir, only or only-create-dir none: Do not graylist any connections.

always: Graylist all connections that have an existing recipient domain directory, except those that match one of the options graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry or graylist-exception-rdns-file. If the qmail-rcpthosts-file value is invalid, this value has no effect.

always-create-dir: Graylist all connections except those that match one of the options graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry or graylist-exception-rdns-file. If the recipient's domain directory does not exist, create it. If the qmail-rcpthosts-file value is invalid, this value has no effect.

only: Do not graylist any connections unless the recipient's domain directory exists and the connection matches one of the options graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry or graylist-exception-rdns-file. If the qmail-rcpthosts-file value is invalid, this value has no effect.

only-create-dir: Do not graylist any connections unless it matches one of the options graylist-exception-ip-entry, graylist-exception-ip-file, graylist-exception-rdns-dir, graylist-exception-rdns-entry or graylist-exception-rdns-file. If the recipient's domain directory does not exist, create it. If the qmail-rcpthosts-file value is invalid, this value has no effect.

If graylist-level is given multiple times, spamdyke will use the last value it finds.

If graylist-level is not given, spamdyke will use a value of none.

See Graylisting / Greylisting for details.
graylist-max-secs M SECS Invalidate graylist entries after they are SECS seconds old. A value of 0 prevents graylist entries from ever expiring. Requires graylist-dir and graylist-level.

If graylist-max-secs is given multiple times, spamdyke will use the last value it finds.

If graylist-max-secs is not given, spamdyke will use a value of 0.

See Graylisting / Greylisting for details.
graylist-min-secs m SECS Require a graylist entry to be present for SECS seconds before allowing incoming mail. A value of 0 will not require any delay; mail will be accepted in any connection immediately after the initial graylisting. Requires graylist-dir and graylist-level.

If graylist-min-secs is given multiple times, spamdyke will use the last value it finds.

If graylist-min-secs is not given, spamdyke will use a value of 0.

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.

If greeting-delay-secs is given multiple times, spamdyke will use the last value it finds.

If greeting-delay-secs is not given, spamdyke will use a value of 0.

See Earlytalkers for details.
header-blacklist-entry   VALUE Reject any message with a header line that matches VALUE.

If header-blacklist-entry is given multiple times, spamdyke will match the message headers against each VALUE given.

If header-blacklist-entry and header-blacklist-file are not given, spamdyke will not filter any message based on their header content.

header-blacklist-entry is valid within configuration directories but entries found there accumulate and apply to all recipients, not just one.

See Rejecting Messages by Header Content for details.
header-blacklist-file   FILE Reject any message with a header line that matches a line in FILE.

If header-blacklist-file is given multiple times, spamdyke will match the message headers against each line in each given FILE.

If header-blacklist-entry and header-blacklist-file are not given, spamdyke will not filter any message based on their header content.

header-blacklist-file is valid within configuration directories but entries found there accumulate and apply to all recipients, not just one.

See Rejecting Messages by Header Content 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 protocols.

If hostname is given multiple times, spamdyke will use the last value it finds.

If hostname, hostname-command and hostname-file are empty, spamdyke will search for the host's name in the environment or will use a default name.

hostname is not valid within configuration directories.

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 protocols. This option is ignored if hostname or hostname-file are given.

If hostname-command is given multiple times, spamdyke will use the last value it finds.

If hostname, hostname-command and hostname-file are empty, spamdyke will search for the host's name in the environment or will use a default name.

hostname-command is not valid within configuration directories.

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 protocols. This option is ignored if hostname is given.

If hostname-file is given multiple times, spamdyke will use the last value it finds.

If hostname-file is not given, spamdyke will use a value of /var/qmail/control/me.

If hostname, hostname-command and hostname-file are empty, spamdyke will search for the host's name in the environment or will use a default name.

hostname-file is not valid within configuration directories.

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

If idle-timeout-secs is given multiple times, spamdyke will use the last value it finds.

If idle-timeout-secs is not given, spamdyke will use a value of 0.

idle-timeout-secs is not valid within configuration directories.

See Timeouts for details.
ip-blacklist-entry   IPADDRESS Reject the connection if the remote server's IP address matches IPADDRESS.

If ip-blacklist-entry is given multiple times, spamdyke will check the remote server's IP address against each given IPADDRESS.

If ip-blacklist-entry and ip-blacklist-file are not given, spamdyke will not attempt to match the remote server's IP address against blacklist entries.

See Blacklists for details.
ip-blacklist-file B FILE Reject the connection if the remote server's IP address matches an entry in FILE. This option provides better performance than ip-blacklist-entry for more than a few entries.

If ip-blacklist-file is given multiple times, spamdyke will check the remote server's IP address against each entry in each given FILE.

If ip-blacklist-entry and ip-blacklist-file are not given, spamdyke will not attempt to match the remote server's IP address against blacklist entries.

See Blacklists for details.
ip-in-rdns-keyword-blacklist-entry   KEYWORD Search the remote server's rDNS name for its IP address and KEYWORD. If both are found, reject the connection.

If ip-in-rdns-keyword-blacklist-entry is given multiple times, spamdyke will search the remote server's rDNS name for its IP address and each given KEYWORD.

If ip-in-rdns-keyword-blacklist-entry and ip-in-rdns-keyword-blacklist-file are not given, spamdyke will not reject connections because the remote server's rDNS name contains its IP address.

See Reverse DNS for details.
ip-in-rdns-keyword-blacklist-file k FILE Search the remote server's rDNS name for its IP address and a keyword listed in FILE. If both are found, reject the connection. This option provides better performance than ip-in-rdns-keyword-whitelist-entry for more than a few entries.

If ip-in-rdns-keyword-blacklist-file is given multiple times, spamdyke will search the remote server's rDNS name for its IP address and each keyword listed in each given FILE.

If ip-in-rdns-keyword-blacklist-entry and ip-in-rdns-keyword-blacklist-file are not given, spamdyke will not reject connections because the remote server's rDNS name contains its IP address.

See Reverse DNS for details.
ip-in-rdns-keyword-whitelist-entry   KEYWORD Search the remote server's rDNS name for its IP address and KEYWORD. If both are found, bypass all filters.

If ip-in-rdns-keyword-whitelist-entry is given multiple times, spamdyke will search the remote server's rDNS name for its IP address and each given KEYWORD.

If ip-in-rdns-keyword-whitelist-entry and ip-in-rdns-keyword-whitelist-file are not given, spamdyke will not bypass all filters because the remote server's rDNS name contains its IP address.

See Reverse DNS for details.
ip-in-rdns-keyword-whitelist-file   FILE Search the remote server's rDNS name for its IP address and a keyword listed in FILE. If both are found, bypass all filters. This option provides better performance than ip-in-rdns-keyword-whitelist-entry for more than a few entries.

If ip-in-rdns-keyword-whitelist-file is given multiple times, spamdyke will search the remote server's rDNS name for its IP address and each keyword listed in each given FILE.

If ip-in-rdns-keyword-whitelist-entry and ip-in-rdns-keyword-whitelist-file are not given, spamdyke will not bypass all filters because the remote server's rDNS name contains its IP address.

See Reverse DNS for details.
ip-relay-entry   IPADDRESS Allow connections from the IP address IPADDRESS to relay messages (i.e. send messages to non-local recipients).

If ip-relay-entry is given multiple times, spamdyke will check the remote server's IP address against each given IPADDRESS.

If ip-relay-entry and ip-relay-file are not given, spamdyke will not allow specific connections to relay according to their IP addresses.

See Relaying for details.
ip-relay-file   FILE Allow connections from the IP addresses in the file FILE to relay messages (i.e. send messages to non-local recipients). This option provides better performance than ip-relay-entry for more than a few entries.

If ip-relay-file is given multiple times, spamdyke will check the remote server's IP address against each entry in each given FILE.

If ip-relay-entry and ip-relay-file are not given, spamdyke will not allow specific connections to relay according to their IP addresses.

See Relaying for details.
ip-whitelist-entry   IPADDRESS If the remote server's IP address matches IPADDRESS, bypass all filters.

If ip-whitelist-entry is given multiple times, spamdyke will check the remote server's IP address against each given IPADDRESS.

If ip-whitelist-entry and ip-whitelist-file are not given, spamdyke will not attempt to match the remote server's IP address against whitelist entries.

See Whitelists for details.
ip-whitelist-file W FILE If the remote server's IP address matches an entry in FILE, bypass all filters. This option provides better performance than ip-whitelist-entry for more than a few entries.

If ip-whitelist-file is given multiple times, spamdyke will check the remote server's IP address against each entry in each given FILE.

If ip-whitelist-entry and ip-whitelist-file are not given, spamdyke will not attempt to match the remote server's IP address against whitelist entries.

See Whitelists for details.
log-level l (lowercase ell) none, error, info, verbose, debug or excessive none: No logging.

error: Log errors only.

info: Everything from error plus connection messages.

verbose: Everything from info plus non-critical errors such as network errors caused by the remote host, protocol errors, config-test status messages and child process error messages.

debug: Everything from verbose plus high-level debugging messages to show the processing path within spamdyke.

excessive: Everything from debug plus low-level debugging messages to show data values and small status messages within spamdyke.

If log-level is given multiple times, spamdyke will use the last value it finds.

If log-level is not given, spamdyke will use a value of error.

log-level is not valid within configuration directories.

See Log Messages for details.
log-target   stderr or syslog stderr: Send log messages to standard error (stderr).

syslog: Send log messages to the system log file via syslogd.

If log-target is given multiple times, spamdyke will use a combination of the given values.

If log-target is not given, spamdyke will use a value of syslog.

log-target is not valid within configuration directories.

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

If max-recipients is given multiple times, spamdyke will use the last value it finds.

If max-recipients is not given, spamdyke will not limit the number of recipients.

max-recipients is not valid within configuration directories.

See Limiting Numbers of Recipients 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.

If policy-url is given multiple times, spamdyke will use the last value it finds.

If policy-url is not given, spamdyke will not append a URL to the rejection message.

See SMTP Error Codes for details.
qmail-morercpthosts-cdb   CDB Search the "constant database" (CDB) file CDB for a list of domains for which email is accepted on this server. This value should always be the same as qmail's "morercpthosts" CDB. If this file isn't the same file qmail uses, spamdyke will be unable to correctly determine if an address is "local" or not, which may result in erroneous behavior. NOTE: do not change this option's default value unless you really know what you're doing.

If qmail-morercpthosts-cdb is given multiple times, spamdyke will search each file. qmail does not do this, so providing multiple values is not recommended.

If the value of qmail-morercpthosts-cdb is invalid, spamdyke won't be able to validate recipient addresses.

If qmail-morercpthosts-cdb is not given, spamdyke will use the value /var/qmail/control/morercpthosts.cdb.

qmail-morercpthosts-cdb is not valid within configuration directories.

See Rejecting Recipients for details.
qmail-rcpthosts-file d FILE Search FILE for a list of domains for which email is accepted on this server. This value should always be the same as qmail's "rcpthosts" file. If this file isn't the same file qmail uses, spamdyke will be unable to correctly determine if an address is "local" or not, which may result in erroneous behavior. NOTE: do not change this option's default value unless you really know what you're doing.

If qmail-rcpthosts-file is given multiple times, spamdyke will search each file. qmail does not do this, so providing multiple values is not recommended.

If the value of qmail-rcpthosts-file is invalid, spamdyke will disable all filters that depend on determining "local" addresses and won't be able to validate recipient addresses.

If qmail-rcpthosts-file is not given, spamdyke will use the value /var/qmail/control/rcpthosts.

qmail-morercpthosts-cdb is not valid within configuration directories.

See Rejecting Recipients 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 better performance than rdns-blacklist-file for large numbers of entries.

If rdns-blacklist-dir is given multiple times, spamdyke will search each DIR for files that match the remote server's rDNS name.

If rdns-blacklist-dir, rdns-blacklist-entry and rdns-blacklist-file are not given, spamdyke will not attempt to match the remote server's rDNS name against blacklist entries.

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

If rdns-blacklist-entry is given multiple times, spamdyke will attempt to match the remote server's rDNS name against each given DOMAIN.

If rdns-blacklist-dir, rdns-blacklist-entry and rdns-blacklist-file are not given, spamdyke will not attempt to match the remote server's rDNS name against blacklist entries.

See Blacklists for details.
rdns-blacklist-file   FILE Reject the connection if the remote server's rDNS name matches an entry in FILE. This option provides better performance than rdns-blacklist-entry for more than a few entries.

If rdns-blacklist-file is given multiple times, spamdyke will search each given FILE for entries that match the remote server's rDNS name.

If rdns-blacklist-dir, rdns-blacklist-entry and rdns-blacklist-file are not given, spamdyke will not attempt to match the remote server's rDNS name against blacklist entries.

See Blacklists for details.
rdns-relay-entry   DOMAIN Allow relaying (i.e. sending to non-local recipients) if the remote server's rDNS name matches DOMAIN.

If rdns-relay-entry is given multiple times, spamdyke will check the remote server's rDNS name against each given DOMAIN.

If rdns-relay-entry and rdns-relay-file are not given, spamdyke will not allow specific connections to relay according to their rDNS names.

See Relaying for details.
rdns-relay-file   FILE Allow relaying (i.e. sending to non-local recipients) if the remote server's rDNS name matches any entry in FILE. This option provides better performance than rdns-relay-entry for more than a few entries.

If rdns-relay-file is given multiple times, spamdyke will check the remote server's rDNS name against each entry in each given FILE.

If rdns-relay-entry and rdns-relay-file are not given, spamdyke will not allow specific connections to relay according to their rDNS names.

See Relaying for details.
rdns-whitelist-dir   DIR If the remote server's rDNS name matches a file in DIR, bypass all filters. This option provides better performance than rdns-whitelist-file for large numbers of entries.

If rdns-whitelist-dir is given multiple times, spamdyke will search each DIR for files that match the remote server's rDNS name.

If rdns-whitelist-dir, rdns-whitelist-entry and rdns-whitelist-file are not given, spamdyke will not attempt to match the remote server's rDNS name against whitelist entries.

See Whitelists for details.
rdns-whitelist-entry   DOMAIN If the remote server's rDNS name matches DOMAIN, bypass all filters.

If rdns-whitelist-entry is given multiple times, spamdyke will attempt to match the remote server's rDNS name against each given DOMAIN.

If rdns-whitelist-dir, rdns-whitelist-entry and rdns-whitelist-file are not given, spamdyke will not attempt to match the remote server's rDNS name against whitelist entries.

See Whitelists for details.
rdns-whitelist-file w FILE If the remote server's rDNS name matches an entry in FILE, bypass all filters. This option provides better performance than rdns-whitelist-entry for more than a few entries.

If rdns-whitelist-file is given multiple times, spamdyke will search each given FILE for entries that match the remote server's rDNS name.

If rdns-whitelist-dir, rdns-whitelist-entry and rdns-whitelist-file are not given, spamdyke will not attempt to match the remote server's rDNS name against whitelist entries.

See Whitelists for details.
recipient-blacklist-entry   ADDRESS Reject any recipient addresses that match ADDRESS.

If recipient-blacklist-entry is given multiple times, spamdyke will attempt to match each recipient address against each given ADDRESS.

If recipient-blacklist-entry and recipient-blacklist-file are not given, spamdyke will not attempt to match recipient addresses against blacklist entries.

See Rejecting Recipients for details.
recipient-blacklist-file S FILE Reject any recipient addresses that match entries in FILE. This option provides better performance than recipient-blacklist-entry for more than a few entries.

If recipient-blacklist-file is given multiple times, spamdyke will attempt to match each recipient address against each entry in each given FILE.

If recipient-blacklist-entry and recipient-blacklist-file are not given, spamdyke will not attempt to match recipient addresses against blacklist entries.

See Rejecting Recipients for details.
recipient-validation-command   COMMAND Execute command COMMAND when a recipient address needs to be validated (i.e. when reject-recipient is invalid, unavailable or both). COMMAND should be the full path to a setuid binary of the "spamdyke-qrv" utility.

If recipient-validation-command is given multiple times, spamdyke will execute each binary in order until a definite answer is returned from the command (e.g. "valid" or "invalid" or "unavailable").

If recipient-validation-command is not given, spamdyke will not attempt to validate recipient addresses.

See Rejecting Recipients for details.
recipient-whitelist-entry   ADDRESS If the recipient's address matches ADDRESS, bypass all filters.

If recipient-whitelist-entry is given multiple times, spamdyke will attempt to match each recipient address against each given ADDRESS.

If recipient-whitelist-entry and recipient-whitelist-file are not given, spamdyke will not attempt to match recipient addresses against whitelist entries.

See Whitelisting Senders and Recipients for details.
recipient-whitelist-file   FILE If the recipient's email address matches an entry in FILE, bypass all filters. This option provides better performance than recipient-whitelist-entry for more than a few entries.

If recipient-whitelist-file is given multiple times, spamdyke will attempt to match each recipient address against each entry in each given FILE.

If recipient-whitelist-entry and recipient-whitelist-file are not given, spamdyke will not attempt to match recipient addresses against whitelist entries.

See Whitelisting Senders and Recipients for details.
reject-empty-rdns r optional:
0, 1, false, true, no or yes
Reject the connection if the remote server has no rDNS name.

If reject-empty-rdns is given multiple times, spamdyke will use the last value it finds.

If reject-empty-rdns is not given, spamdyke will not reject connections with missing rDNS names.

If reject-empty-rdns is given without an argument, spamdyke will use a value of yes.

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

If reject-ip-in-cc-rdns is given multiple times, spamdyke will use the last value it finds.

If reject-ip-in-cc-rdns is not given, spamdyke will not reject connections from servers whose rDNS names contain their IP address and a country code.

If reject-ip-in-cc-rdns is given without an argument, spamdyke will use a value of yes.

See Reverse DNS for details.
reject-recipient   none, same-as-sender, invalid or unavailable none: Deactivate this option's filters.

same-as-sender: Reject any recipient address that is the same as the sender address.

invalid: Reject any recipient address that will never result in a successful delivery (e.g. any address qmail will accept and later bounce). NOTE: this value is ignored unless recipient-validation-command is also given.

unavailable: Reject any recipient address that is currently unavailable (due to file permissions or other settings). NOTE: this value is ignored unless recipient-validation-command is also given.

If reject-identical-sender-recipient is given multiple times, spamdyke will use every value it finds.

If reject-identical-sender-recipient is not given, spamdyke will use the value none.

See Rejecting Recipients for details.
reject-sender   none, no-mx, not-local, authentication-mismatch, or authentication-domain-mismatch none: Deactivate this option's filters.

no-mx: Reject any connection where the sender's domain name does not have a valid mail exchanger (an MX record or an A record).

not-local: Reject connections where the sender's domain is not local (i.e. not hosted on the local server). Values for the options qmail-rcpthosts-file or qmail-morercpthosts-cdb are required.

authentication-mismatch: Reject connections where the sender's address (user and domain) does not match the username used during authentication. NOTE: This value has no effect if the sender does not authenticate.

authentication-domain-mismatch: Reject connections where the sender's domain does not match the domain used during authentication. NOTE: This value has no effect if the sender does not authenticate or if the authentication username is not an email address.

If reject-sender is given multiple times, spamdyke will use every value it finds.

If reject-sender is not given, spamdyke will use the value none.

See Rejecting Senders for details.
reject-unresolvable-rdns R optional:
0, 1, false, true, no or yes
Reject the connection if the remote server's rDNS name does not resolve (search for an A record).

If reject-unresolvable-rdns is given multiple times, spamdyke will use the last value it finds.

If reject-unresolvable-rdns is not given, spamdyke will not reject connections from remote servers whose rDNS names do not resolve.

If reject-unresolvable-rdns is given without an argument, spamdyke will use a value of yes.

See Reverse DNS for details.
rejection-text-auth-failure   TEXT Send TEXT to the client as an error message if authentication fails for any reason.

If rejection-text-auth-failure is given multiple times, spamdyke will use the last value it finds.

If rejection-text-auth-failure is not given, spamdyke will use the text Refused. Authentication failed.

rejection-text-auth-failure is not valid within configuration directories.

See SMTP Error Codes for details.
rejection-text-auth-unknown   TEXT Send TEXT to the client as an error message if the remote server attempts to authenticate using an unsupported authentication method. This should never happen.

If rejection-text-auth-unknown is given multiple times, spamdyke will use the last value it finds.

If rejection-text-auth-unknown is not given, spamdyke will use the text Refused. Unknown authentication method.

rejection-text-auth-unknown is not valid within configuration directories.

See SMTP Error Codes for details.
rejection-text-dns-blacklist   TEXT Send TEXT to the client as an error message if the remote server's IP address is found on a DNS blacklist (RBL). The name of the matching RBL will be appended to TEXT. Note: this flag has no effect if the RBL returns a text message; that text will be used instead.

If rejection-text-dns-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-dns-blacklist is not given, spamdyke will use the text Refused. Your IP address is listed in the DNS RBL at

See SMTP Error Codes for details.
rejection-text-earlytalker   TEXT Send TEXT to the client as an error message if the remote server sends data before the SMTP greeting banner is displayed.

If rejection-text-earlytalker is given multiple times, spamdyke will use the last value it finds.

If rejection-text-earlytalker is not given, spamdyke will use the text Refused. You are not following the SMTP protocol.

See SMTP Error Codes for details.
rejection-text-empty-rdns   TEXT Send TEXT to the client as an error message if the remote server has no rDNS name.

If rejection-text-empty-rdns is given multiple times, spamdyke will use the last value it finds.

If rejection-text-empty-rdns is not given, spamdyke will use the text Refused. You have no reverse DNS entry.

See SMTP Error Codes for details.
rejection-text-graylist   TEXT Send TEXT to the client as an error message if the recipient address has been graylisted.

If rejection-text-graylist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-graylist is not given, spamdyke will use the text Your address has been graylisted. Try again later.

See SMTP Error Codes for details.
rejection-text-header-blacklist   TEXT Send TEXT to the client as an error message if the message is blocked because a header line matches a header blacklist.

If rejection-text-header-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-header-blacklist is not given, spamdyke will use the text Refused. Your message has been blocked due to its content.

If rejection-text-header-blacklist is not valid within configuration directories.

See SMTP Error Codes for details.
rejection-text-ip-blacklist   TEXT Send TEXT to the client as an error message if the remote server's IP address is found in an IP blacklist file or matches an IP blacklist entry.

If rejection-text-ip-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-ip-blacklist is not given, spamdyke will use the text Refused. Your IP address is blacklisted.

See SMTP Error Codes for details.
rejection-text-ip-in-cc-rdns   TEXT Send TEXT to the client as an error message if the remote server's rDNS name contains the remote server's IP address and ends in a two-character country code.

If rejection-text-ip-in-cc-rdns is given multiple times, spamdyke will use the last value it finds.

If rejection-text-ip-in-cc-rdns is not given, spamdyke will use the text Refused. Your reverse DNS entry contains your IP address and a country code.

See SMTP Error Codes for details.
rejection-text-ip-in-rdns-keyword-blacklist   TEXT Send TEXT to the client as an error message if the remote server's rDNS name contains the remote server's IP address and a banned keyword.

If rejection-text-ip-in-rdns-keyword-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-ip-in-rdns-keyword-blacklist is not given, spamdyke will use the text Refused. Your reverse DNS entry contains your IP address and a banned keyword.

See SMTP Error Codes for details.
rejection-text-local-recipient   TEXT Send TEXT to the client as an error message if the specified recipient does not include a domain name.

If rejection-text-local-recipient is given multiple times, spamdyke will use the last value it finds.

If rejection-text-local-recipient is not given, spamdyke will use the text Improper recipient address. Try supplying a domain name.

See SMTP Error Codes for details.
rejection-text-max-recipients   TEXT Send TEXT to the client as an error message if the remote server gives too many recipient addresses.

If rejection-text-max-recipients is given multiple times, spamdyke will use the last value it finds.

If rejection-text-max-recipients is not given, spamdyke will use the text Too many recipients. Try the remaining addresses again later.

See SMTP Error Codes for details.
rejection-text-rdns-blacklist   TEXT Send TEXT to the client as an error message if the remote server's rDNS name is found in a blacklist file or matches a blacklist entry.

If rejection-text-rdns-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-rdns-blacklist is not given, spamdyke will use the text Refused. Your domain name is blacklisted.

See SMTP Error Codes for details.
rejection-text-recipient-blacklist   TEXT Send TEXT to the client as an error message if the recipient address is blacklisted.

If rejection-text-recipient-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-recipient-blacklist is not given, spamdyke will use the text Refused. Mail is not being accepted at this address.

See SMTP Error Codes for details.
rejection-text-recipient-same-as-sender   TEXT Send TEXT to the client as an error message if the sender's email addresses is the same as the recipient's email address.

If rejection-text-recipient-same-as-sender is given multiple times, spamdyke will use the last value it finds.

If rejection-text-recipient-same-as-sender is not given, spamdyke will use the text Refused. Identical sender and recipient addresses are not allowed.

See SMTP Error Codes for details.
rejection-text-recipient-invalid   TEXT Send TEXT to the client as an error message if the recipient address is invalid and qmail would bounce the message.

If rejection-text-recipient-invalid is given multiple times, spamdyke will use the last value it finds.

If rejection-text-recipient-invalid is not given, spamdyke will use the text Refused. The recipient address does not exist.

See SMTP Error Codes for details.
rejection-text-recipient-unavailable   TEXT Send TEXT to the client as an error message if the recipient address is invalid and qmail would queue the message (until it bounced).

If rejection-text-recipient-unavailable is given multiple times, spamdyke will use the last value it finds.

If rejection-text-recipient-unavailable is not given, spamdyke will use the text Refused. The recipient is not accepting mail right now.

See SMTP Error Codes for details.
rejection-text-reject-all   TEXT Send TEXT to the client as an error message if all mail is being rejected.

If rejection-text-reject-all is given multiple times, spamdyke will use the last value it finds.

If rejection-text-reject-all is not given, spamdyke will use the text Refused. Mail is not being accepted.

See SMTP Error Codes for details.
rejection-text-relaying-denied   TEXT Send TEXT to the client as an error message if the recipient is not local and the remote server is not allowed relay.

If rejection-text-relaying-denied is given multiple times, spamdyke will use the last value it finds.

If rejection-text-relaying-denied is not given, spamdyke will use the text Refused. Sending to remote addresses (relaying) is not allowed.

See SMTP Error Codes for details.
rejection-text-rhs-blacklist   TEXT Send TEXT to the client as an error message if the remote server's rDNS name or the sender's domain name are found on a right-hand side blacklist (RHSBL). The name of the matching RHSBL will be appended to TEXT. Note: this flag has no effect if the RHSBL returns a text message; that text will be used instead.

If rejection-text-rhs-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-rhs-blacklist is not given, spamdyke will use the text Refused. Your domain name is listed in the RHSBL at

See SMTP Error Codes for details.
rejection-text-sender-authentication-mismatch   TEXT Send TEXT to the client as an error message if the sender's email address does not match the username given during authentication.

If rejection-text-sender-authentication-mismatch is given multiple times, spamdyke will use the last value it finds.

If rejection-text-sender-authentication-mismatch is not given, spamdyke will use the text Refused. Your sender address does not match your authentication username.

See SMTP Error Codes for details.
rejection-text-sender-blacklist   TEXT Send TEXT to the client as an error message if the sender's email address is blacklisted.

If rejection-text-sender-blacklist is given multiple times, spamdyke will use the last value it finds.

If rejection-text-sender-blacklist is not given, spamdyke will use the text Refused. Your sender address has been blacklisted.

See SMTP Error Codes for details.
rejection-text-sender-no-mx   TEXT Send TEXT to the client as an error message if the sender's domain name does not have a DNS entry for a mail exchanger (MX).

If rejection-text-sender-no-mx is given multiple times, spamdyke will use the last value it finds.

If rejection-text-sender-no-mx is not given, spamdyke will use the text Refused. The domain of your sender address has no mail exchanger (MX).

See SMTP Error Codes for details.
rejection-text-sender-not-local   TEXT Send TEXT to the client as an error message if the sender's email address is not hosted locally.

If rejection-text-sender-not-local is given multiple times, spamdyke will use the last value it finds.

If rejection-text-sender-not-local is not given, spamdyke will use the text Refused. Mail for your sender domain is not hosted here.

See SMTP Error Codes for details.
rejection-text-smtp-auth-required   TEXT Send TEXT to the client as an error message if authentication is required to send email and the remote server has not authenticated.

If rejection-text-smtp-auth-required is given multiple times, spamdyke will use the last value it finds.

If rejection-text-smtp-auth-required is not given, spamdyke will use the text Refused. Authentication is required to send mail.

See SMTP Error Codes for details.
rejection-text-timeout   TEXT Send TEXT to the client as an error message if the connection times out.

If rejection-text-text-timeout is given multiple times, spamdyke will use the last value it finds.

If rejection-text-text-timeout is not given, spamdyke will use the text Timeout. Talk faster next time.

rejection-text-timeout is not valid within configuration directories.

See SMTP Error Codes for details.
rejection-text-tls-failure   TEXT Send TEXT to the client as an error message if a SSL/TLS session cannot be started with the remote server.

If rejection-text-text-tls-failure is given multiple times, spamdyke will use the last value it finds.

If rejection-text-text-tls-failure is not given, spamdyke will use the text Failed to negotiate TLS connection.

rejection-text-tls-failure is not valid within configuration directories.

See SMTP Error Codes for details.
rejection-text-unresolvable-rdns   TEXT Send TEXT to the client as an error message if the remote server's rDNS name does not resolve.

If rejection-text-unresolvable-rdns is given multiple times, spamdyke will use the last value it finds.

If rejection-text-unresolvable-rdns is not given, spamdyke will use the text Refused. Your reverse DNS entry does not resolve.

See SMTP Error Codes for details.
rejection-text-zero-recipients   TEXT Send TEXT to the client as an error message if none of the recipients given by the remote server are accepted.

If rejection-text-zero-recipients is given multiple times, spamdyke will use the last value it finds.

If rejection-text-zero-recipients is not given, spamdyke will use the text Refused. You must specify at least one valid recipient.

rejection-text-zero-recipients is not valid within configuration directories.

See SMTP Error Codes for details.
relay-level   block-all, normal or allow-all block-all: Block all relaying attempts, even if the sender has authenticated or the access file or an environment variable should allow relaying. Messages to local recipients will still be accepted. Requires qmail-rcpthosts-file to be set to a valid filename.

normal: Do not prevent relaying; allow qmail (or another filter) to prevent relaying as appropriate.

allow-all: Allow relaying from all senders. Note: This creates an open relay and is not recommended.

If relay-level is given multiple times, spamdyke will use the last value it finds.

If relay-level is not given, spamdyke will use a value of normal.

relay-level is not valid within configuration directories.

See Relaying for details.
rhs-blacklist-entry X RHSBL Check the remote server's rDNS name and the sender email address' domain name against the right hand-side blackhole list RHSBL. If it is found, the connection is rejected. NOTE: Using more than a few RHS blacklists can cause serious performance problems.

If rhs-blacklist-entry is given multiple times, spamdyke will check each given RHSBL for the remote server's rDNS name and the sender's email address domain name.

If rhs-blacklist-entry and rhs-blacklist-file are not given, spamdyke will not check any blackhole lists for the remote server's rDNS name and the sender's email address domain name.

See DNS RHSBLs for details.
rhs-blacklist-file   FILE Check the remote server's domain name and the sender email address' domain name against each of the right hand-side blackhole lists listed in FILE. If it is found on any of the lists, the connection is rejected. NOTE: Using more than a few RHS blacklists can cause serious performance problems.

If rhs-blacklist-file is given multiple times, spamdyke will check each blackhole list listed in each given FILE for the remote server's rDNS name and the sender's email address domain name.

If rhs-blacklist-file and rhs-blacklist-file are not given, spamdyke will not check any blackhole lists for the remote server's rDNS name and the sender's email address domain name.

See DNS RHSBLs for details.
rhs-whitelist-entry   RHSWHITELIST Check the remote server's domain name and the sender email address' domain name against the right hand-side whitelist RHSWHITELIST (essentially an RHSBL that contains whitelisted domains). If it is found, all filters are bypassed. NOTE: Using more than a few RHS whitelists can cause serious performance problems.

If rhs-whitelist-entry is given multiple times, spamdyke will check each given RHSWHITELIST for the remote server's rDNS name and the sender's email address domain name.

If rhs-whitelist-entry and rhs-whitelist-file are not given, spamdyke will not check any whitelists for the remote server's rDNS name and the sender's email address domain name.

See DNS Whitelists for details.
rhs-whitelist-file   FILE Check the remote server's domain name and the sender email address' domain name against each of the right hand-side whitelists (essentially an RHSBL that contains whitelisted domains) listed in FILE. If it is found on any of the lists, all filters are bypassed. NOTE: Using more than a few RHS whitelists can cause serious performance problems.

If rhs-whitelist-file is given multiple times, spamdyke will check each whitelist listed in each given FILE for the remote server's rDNS name and the sender's email address domain name.

If rhs-whitelist-file and rhs-whitelist-file are not given, spamdyke will not check any whitelist for the remote server's rDNS name and the sender's email address domain name.

See DNS Whitelists for details.
run-as-user   USER[:GROUP] As soon as possible, change the running user identity to the user with the username or ID USER. If GROUP is provided, also change the group identity to the system group with the name GROUP or ID GROUP. This feature requires spamdyke to be started as a user with the ability to switch identities (typically the superuser).

If run-as-user is given multiple times, spamdyke will use the last value it finds.

If run-as-user is not given, spamdyke will not attempt to switch user identities.

run-as-user is not valid within configuration directories.

See Permissions for details.
sender-blacklist-entry   ADDRESS Reject the connection if the sender's email address matches ADDRESS.

If sender-blacklist-entry is given multiple times, spamdyke will reject the connection if the sender's email address matches any of the given ADDRESS values.

If sender-blacklist-entry and sender-blacklist-file are not given, spamdyke will not blacklist any sender email addresses.

See Rejecting Senders for details.
sender-blacklist-file s FILE Reject the connection if the sender's email address matches an entry in FILE. This option provides better performance than sender-blacklist-entry for more than a few entries.

If sender-blacklist-file is given multiple times, spamdyke will reject the connection if the sender's email address matches any of the entries in each given FILE.

If sender-blacklist-entry and sender-blacklist-file are not given, spamdyke will not blacklist any sender email addresses.

See Rejecting Senders for details.
sender-whitelist-entry   ADDRESS If the sender's email address matches ADDRESS, bypass all filters.

If sender-whitelist-entry is given multiple times, spamdyke will compare the sender's email address to each given ADDRESS.

If sender-whitelist-entry and sender-whitelist-file are not given, spamdyke will not whitelist any sender email addresses.

See Whitelisting Senders and Recipients for details.
sender-whitelist-file   FILE If the sender's email address matches an entry in FILE, bypass all filters. This option provides better performance than sender-whitelist-entry for more than a few entries.

If sender-whitelist-file is given multiple times, spamdyke will compare the sender's email address to each entry in each given FILE.

If sender-whitelist-entry and sender-whitelist-file are not given, spamdyke will not whitelist any sender email addresses.

See Whitelisting Senders and Recipients for details.
smtp-auth-command   COMMAND Perform SMTP AUTH verification using COMMAND. If the authentication is valid, all filters will be bypassed. This option may have no effect, depending on the value of smtp-auth-level.

If smtp-auth-command is given multiple times, spamdyke will authenticate using each given COMMAND until one of them indicates success.

If smtp-auth-command is not given, spamdyke will not process authentication. Depending on the value of smtp-auth-level, authentication may still be possible.

smtp-auth-command is not valid within configuration directories.

See SMTP AUTH for details.
smtp-auth-level   none, observe, ondemand, ondemand-encrypted, always or always-encrypted none: Do not offer or allow authentication, even if qmail has been patched to provide it.

observe: Observe authentication only (and trust qmail's responses), do not offer it. This value has no effect if qmail has not been patched to offer authentication.

ondemand: If qmail offers authentication, observe any authentication attempts and trust qmail's responses. If qmail does not offer authentication, spamdyke will offer cleartext authentication, then process it using the value of smtp-auth-command.

ondemand-encrypted: If qmail offers authentication, observe any authentication attempts and trust qmail's responses. If qmail does not offer authentication, spamdyke will offer cleartext and encrypted authentication, then process it using the value of smtp-auth-command.

always: Always offer cleartext authentication, then process it using the value of smtp-auth-command. If qmail attempts to offer authentication, spamdyke will hide qmail's offer and prevent the authentication data from reaching qmail.

always-encrypted: Always offer cleartext and encrypted authentication, then process it using the value of smtp-auth-command. If qmail attempts to offer authentication, spamdyke will hide qmail's offer and prevent the authentication data from reaching qmail.

If smtp-auth-level is given multiple times, spamdyke will use the last value it finds.

If smtp-auth-level is not given, spamdyke will use a value of observe.

smtp-auth-level is not valid within configuration directories.

See SMTP AUTH for details.
tls-certificate-file   FILE Decrypt SSL/TLS traffic using the SSL certificate in FILE. The certificate must be in PEM format. If FILE does not also contain the private key, tls-privatekey-file must be used. This option has no effect unless tls-level is also given.

If tls-certificate-file is given multiple times, spamdyke will use the last value it finds.

If tls-certificate-file is not given, spamdyke will not decrypt SSL/TLS traffic. The encrypted traffic will be passed through to qmail.

tls-certificate-file is not valid within configuration directories.

See TLS for details.
tls-cipher-list   STRING During SSL/TLS connections, use the list ciphers given in STRING. Normally this is not needed, the default list of ciphers is adequate for most usages. This option has no effect unless tls-level is also given.

If tls-cipher-list is given multiple times, spamdyke will use the last value it finds.

tls-cipher-list is not valid within configuration directories.

See TLS for details.
tls-dhparams-file   FILE During SSL/TLS connections, use the contents of FILE for creating ephemeral DH keys. Normally this is not needed, since the default ciphers do not use ephemeral DH keys. This option has no effect unless tls-level is also given.

If tls-dhparams-file is given multiple times, spamdyke will use the last value it finds.

tls-dhparams-file is not valid within configuration directories.

See TLS for details.
tls-level   none, smtp smtp-no-passthrough or smtps none: Do not offer or allow SSL/TLS, even if qmail supports it.

smtp: If tls-certificate-file is given, offer TLS during the SMTP conversation and decrypt the traffic. If tls-certificate-file is not given, allow qmail to offer TLS (if it has been patched to provide TLS) and pass the encrypted traffic to qmail.

smtp-no-passthrough: If tls-certificate-file is given, offer TLS during the SMTP conversation and decrypt the traffic. If tls-certificate-file is not given, prevent TLS from starting.

smtps: Initiate a SSL session at the beginning of the connection, before SMTP begins.

If tls-level is given multiple times, spamdyke will use the last value it finds.

If tls-level is not given, spamdyke will use a value of smtp.

tls-level is not valid within configuration directories.

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

If tls-privatekey-file is given multiple times, spamdyke will use the last value it finds.

If tls-privatekey-file is not given, spamdyke will look for the private key in the certificate file.

tls-privatekey-file is not valid within configuration directories.

See TLS for details.
tls-privatekey-password   PASSWORD Use PASSWORD to decrypt the SSL private key (given with 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.

If tls-privatekey-password is given multiple times, spamdyke will use the last value it finds.

If tls-privatekey-password and tls-privatekey-password-file are not given, spamdyke will attempt to load the private key without a password.

tls-privatekey-password is not valid within configuration directories.

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.

If tls-privatekey-password-file is given multiple times, spamdyke will use the last value it finds.

If tls-privatekey-password and tls-privatekey-password-file are not given, spamdyke will attempt to load the private key without a password.

tls-privatekey-password-file is not valid within configuration directories.

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: While multi-word values must be quoted on the command line, quotes are not allowed in configuration files. 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 option in the configuration file 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 is read after the command line has been scanned. This can be confusing, so the best practice is to avoid specifying the same option in multiple places without good reason.

Some options can be given multiple times and spamdyke will use all of the values it finds. For example, if the following lines are given, spamdyke will search each of the files for a match to the sender's email address:

sender-blacklist-file=/home/vpopmail/sender_blacklist.txt
sender-blacklist-file=/home/vpopmail/more_sender_blacklist.txt
sender-blacklist-file=/home/vpopmail/additional_sender_blacklist.txt
However, in some situations, it may be necessary to remove one or all of the values. Most commonly, this occurs when the values are set in a global configuration file and are unset in a configuration directory. To remove one specific value from a list, the value should be specified with an exclamation point preceeding the value:
OPTION=!VALUE
For example:
sender-blacklist-file=!/home/vpopmail/sender_blacklist.txt
If the given value was not previously set, no action will be taken.

To clear all values from a list, three exclamation points should be given instead of a value:

OPTION=!!!
For example, if the following line is given, the sender-blacklist-file option will be cleared and spamdyke will behave as though sender-blacklist-file had never appeared:
sender-blacklist-file=!!!

Note: spamdyke processes configuration directives in the order they are read. If an option is cleared and later set again, the option will retain the last value. For example, if the following five lines appear in this order:

sender-blacklist-file=/home/vpopmail/sender_blacklist.txt
sender-blacklist-file=/home/vpopmail/more_sender_blacklist.txt
sender-blacklist-file=/home/vpopmail/additional_sender_blacklist.txt
sender-blacklist-file=!!!
sender-blacklist-file=/home/vpopmail/last_blacklist.txt
spamdyke will set the first three values, clear them, then set the last value. When the sender blacklist filter runs, it will search the file /home/vpopmail/last_blacklist.txt.

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. This is likely due to inefficiencies in GNU's getopt_long() function.

Configuration Directories

config-dir
config-dir-search

Configuration directories allow spamdyke's behavior to be altered based on the remote server's IP address, the remote server's rDNS name, the sender's email address, the recipient's email address or any combination of those things. This can be very useful when, for example, graylisting should be deactivated for a specific sender. Or when RBL filters should be disabled for a specific IP address. Or perhaps when extra filters should be enabled for only a few recipients.

Configuration directories could be used to allow domain administrators or even individual users to set their own options, such as whitelisting or blacklisting IPs or senders without affecting other domains/users on the server. Creating a web-based control panel to do this would be relatively easy.

Configuration directories are given with the config-dir option. The option's value should be the path to the directory that contains the subdirectories explained below. If config-dir is given multiple times, spamdyke will search each given directory structure and load all of the matching files before it continues processing the SMTP connection.

In essence, a configuration directory is a special directory structure that contains configuration files. spamdyke determines which files to load based on the names of the directories and the details of the SMTP connection. Not all options are valid within configuration directories, but in all other respects the files follow the same rules as global configuration files. See Usage for details of which options are valid within configuration directories. See Configuration Files for details of the configuration file format.

When spamdyke loads a file from a configuration directory, it will do so because the names of the directories and the name of the file match all or part of the information from the SMTP connection. The last piece of information should always be used as the name of the file, not the name of a directory.

To create a file using the IP address of the remote server, first create a directory structure that begins with _ip_ and uses the first three octets of the address as directory names. For example, if the IP address is 11.22.33.44, the directory structure should look like this:

.../_ip_/11/22/33
Use the fourth octet as the name of the configuration file. For example:
.../_ip_/11/22/33/44

To create a file using the rDNS name of the remote server, first create a directory structure that begins with _rdns_ and contains directories named using the rDNS name with its words reversed. For example, if the rDNS name is mail.internal.headquarters.example.com, the directory structure should look like this:

.../_rdns_/com/example/headquarters/internal
The last word of the rDNS name is used as the name of the configuration file. For example:
.../_rdns_/com/example/headquarters/internal/mail

To create a file using the sender's email address, first create a directory structure that begins with _sender_ and contains directories using the domain portion of the sender's email address with its words reversed and ending in _at_. For example, if the sender's email address is mom@home.example.com, the directory structure should look like this:

.../_sender_/com/example/home/_at_
The sender's username is used as the name of the configuration file. For example:
.../_sender_/com/example/home/_at_/mom

To create a file using the recipient's email address, first create a directory structure that begins with _recipient_ and contains directories using the domain portion of the recipient's email address with its words reversed and ending in _at_. For example, if the recipient's email address is kid@school.example.com, the directory structure should look like this:

.../_recipient_/com/example/school/_at_
The recipient's username is used as the name of the configuration file. For example:
.../_recipient_/com/example/school/_at_/kid
spamdyke will match partial IP addresses, rDNS names, sender email addresses or recipient email addresses left-most portions of the directory structure are omitted. Note: spamdyke will never read a configuration file named _at_. If the sender's or recipient's username are omitted, the _at_ directory must be omitted as well. For example, if the IP address is 11.22.33.44, the rDNS name is mail.internal.headquarters.example.com, the sender's email address is mom@home.example.com and the recipient's email address is kid@school.example.com, spamdyke will look for configuration files with the following paths:
.../_ip_/11/22/33/44
.../_ip_/11/22/33
.../_ip_/11/22
.../_ip_/11
.../_rdns_/com/example/headquarters/internal/mail
.../_rdns_/com/example/headquarters/internal
.../_rdns_/com/example/headquarters
.../_rdns_/com/example
.../_rdns_/com
.../_recipient_/com/example/school/_at_/kid
.../_recipient_/com/example/school
.../_recipient_/com/example
.../_recipient_/com
.../_sender_/com/example/home/_at_/mom
.../_sender_/com/example/home
.../_sender_/com/example
.../_sender_/com

Configuration directories can be nested to create more specific targets. For example, if the IP address of the remote server is 11.22.33.44 and the sender's email address is mom@home.example.com, spamdyke will read a configuration file if its path is either of the following:

.../_ip_/11/22/33/44/_sender_/com/example/home/_at_/mom
.../_sender_/com/example/home/_at_/mom/_ip_/11/22/33/44
If only portions of the IP address or sender address are used, the possible list of file paths increases dramatically:
.../_ip_/11/22/33/44/_sender_/com/example/home
.../_ip_/11/22/33/44/_sender_/com/example
.../_ip_/11/22/33/44/_sender_/com
.../_ip_/11/22/33/_sender_/com/example/home/_at_/mom
.../_ip_/11/22/_sender_/com/example/home/_at_/mom
.../_ip_/11/_sender_/com/example/home/_at_/mom
.../_sender_/com/example/home/_ip_/11/22/33
.../_sender_/com/example/_ip_/11/22
.../_sender_/com/_ip_/11
spamdyke will check for every possible combination of partial paths (not all permutations are listed here). rDNS name directories and recipient directories can also be nested to create configuration files that will only be loaded if all four pieces of information match.

If all of that isn't confusing enough, spamdyke will only read one file from a _ip_, _rdns_, _sender_ or _recipient_ directory, even if more matches are possible. For example, if the remote IP address is 11.22.33.44, the sender's email address is mom@home.example.com and the recipient's email address is kid@school.example.com and two files exist with the following paths:

.../_ip_/11/22/33/44/_sender_/com/example/home/_at_/mom
.../_ip_/11/22/33/44/_recipient_/com/example/school/_at_/kid
spamdyke will only read one of the files because the _ip_ directory cannot be matched more than once. This behavior can be changed with the config-dir-search option.

config-dir-search can be given multiple times; the values will be added together to create a composite value. The possible values are:

  • first: Match each _ip_, _rdns_, _sender_ or _recipient directory only once. NOTE: The first value erases the composite value created from the other possible values, essentially "resetting" the config-dir-search option.
  • all-ip: Match each _ip_ directory as many times as possible.
  • all-rdns: Match each _rdns_ directory as many times as possible.
  • all-sender: Match each _sender_ directory as many times as possible.
  • all-recipient: Match each _recipient_ directory as many times as possible.

To aid with troubleshooting, spamdyke will log the paths it searches if the log-level option is debug or higher.

Configuration Tests

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

spamdyke has the ability to scan its configuration and look for common configuration mistakes. It checks file paths, 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 line from your "supervise" script or xinetd configuration file, including the qmail command(s).
  2. At a command prompt, login as root and paste the spamdyke command without running it.
  3. Add the option --config-test 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 (no test output goes to syslog).
If the run-as-user option is not given in your spamdyke configuration, it should be used on the command line 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-level and smtp-auth-command 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 syslog, which sends log messages to the system syslog facility. When log-target is set to stderr, 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. If log-target is given multiple times with different values, spamdyke will send its output to each given target.

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:

  • none: No logging at all, even if errors occur. This is not recommended.
  • error: Critical errors only, including authentication failures. This is the default when log-level is not given.
  • info: Everything from error plus logging of messages (sender, recipient, IP address, rDNS name and authenticated username). This is the value used when log-level is given with no value.
  • verbose: Everything from info plus non-critical errors such as network errors caused by the remote host, protocol errors, config-test status messages and child process error messages. At this level, spamdyke will also print messages to show which filter blocked the connection (if applicable) and some details about the filter's settings. These messages will be prefixed with FILTER:.
  • debug: Everything from verbose plus high-level debugging messages, intended to show the processing path within spamdyke. This level is handy for troubleshooting but it can be rather noisy. Extra messages generated by this level will be prefixed with DEBUG(): and will show the file and line number within the spamdyke source code where the message was produced. NOTE: If the configure script is run with the --without-debug-output option, spamdyke will accept the debug value but it will not print any more output than if verbose were used.
  • excessive: Everything from debug plus lots of internal status messages. This value should only be used for development. Extra messages generated by this level will be prefixed with EXCESSIVE(): and will show the file and line number within the spamdyke source code where the message was produced. NOTE: Unless the configure script is run with the --with-excessive-output option, spamdyke will not produce any more output for excessive than if debug were used.
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=verbose ...
/usr/local/bin/spamdyke -lverbose ...
The log-level option may also be given with no value at all, which is the same as specifiying info. The following two command lines are also valid:
/usr/local/bin/spamdyke --log-level ...
/usr/local/bin/spamdyke -l ...

Error messages and debugging statements are always preceeded by ERROR, DEBUG or EXCESSIVE, followed by the function name, the filename and the line number that produced it. Messages showing when a filter is triggered are preceeded by FILTER and do not include the location information. Each message log entry (produced when the value of log-level is info or higher) takes the following form:

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

The possible values of CODE are listed below:

CODE Description Related Option(s)
ALLOWED The message passed all filters. qmail may still bounce the message later for other reasons beyond spamdyke's control, however.

REASON will contain the text of qmail's response.
 
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. This message is only printed in full log files (see Logging All Data); the normal log will only contain ALLOWED.  
ALLOWED_TLS The remote client successfully started a TLS session with spamdyke. This message is only printed in full log files (see Logging All Data); the normal log will only contain ALLOWED.  
DENIED_AUTH_REQUIRED The message was blocked because the remote server has not authenticated, which is required. filter-level
DENIED_BLACKLIST_IP The connection was blocked because the remote server's IP address is blacklisted.

REASON will contain the matching entry if ip-blacklist-entry was used or the filename and matching line number if ip-blacklist-file was used.
ip-blacklist-entry
ip-blacklist-file
DENIED_BLACKLIST_NAME The connection was blocked because the remote server's rDNS name is blacklisted.

REASON will contain:
  • the matching entry if rdns-blacklist-entry was used,
  • the filename and matchine line number if rdns-blacklist-file was used, or
  • the full path to the matching file if rdns-blacklist-dir was used.
rdns-blacklist-entry
rdns-blacklist-file
rdns-blacklist-dir
DENIED_EARLYTALKER The connection was blocked because the remote server began sending data before the SMTP greeting was issued. greeting-delay-secs
DENIED_GRAYLISTED The recipient was blocked because the sender/recipient combination was graylisted. The SMTP connection continues after this error occurs. graylist-level
DENIED_HEADER_BLACKLISTED The message was blocked because one or more header lines matched a header blacklist.

REASON will contain the matching entry if header-blacklist-entry was used or the filename and matching line number if header-blacklist-file was used.
header-blacklist-entry
header-blacklist-file
DENIED_IDENTICAL_SENDER_RECIPIENT The connection was blocked because the sender's email address is the same as the recipient's email address. reject-recipient
DENIED_INVALID_RECIPIENT The recipient was rejected because the address does not exist. The SMTP connection continues after this error occurs. reject-recipient
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.

REASON will contain the matching entry if ip-in-rdns-keyword-blacklist-entry was used or the filename and matching line if ip-in-rdns-keyword-blacklist-file was used.
ip-in-rdns-keyword-blacklist-entry
ip-in-rdns-keyword-blacklist-file
DENIED_OTHER The connection was rejected by qmail (or another downstream filter), not spamdyke.

REASON will contain the rejection message given by qmail (or other downstream filter).
 
DENIED_RBL_MATCH The connection was blocked because the remote server's IP address was found on a DNS RBL.

REASON will contain the name of the matched RBL and the text it returned (if any).
dns-blacklist-entry
dns-blacklist-file
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_RHSBL_MATCH The connection was blocked because the remote server's reverse DNS name was found on a right hand-side DNS blacklist (RHSBL) OR because the sender's domain name was found on a right hand-side DNS blacklist (RHSBL).

REASON will contain the name of the matched RBL and the text it returned (if any).
rhs-blacklist-entry
rhs-blacklist-file
DENIED_RECIPIENT_BLACKLISTED The recipient was blocked because the recipient email address is blacklisted.

REASON will contain the matching entry if recipient-blacklist-entry was used or the filename and matching line if recipient-blacklist-file was used.
recipient-blacklist-entry
recipient-blacklist-file
DENIED_REJECT_ALL The message was blocked because all mail is being rejected. filter-level
DENIED_RELAYING The recipient was blocked because the recipient's domain is not locally hosted and the remote server is not allowed to relay. relay-level
DENIED_SENDER_BLACKLISTED The connection was blocked because the sender's email address is blacklisted.

REASON will contain the matching entry if sender-blacklist-entry was used or the filename and matching line if sender-blacklist-file was used.
sender-blacklist-entry
sender-blacklist-file
DENIED_SENDER_NO_MX The connection was blocked because the sender's domain has no mail exchanger, making the sender address invalid. reject-sender
DENIED_SENDER_NOT_AUTH The connection was blocked because the sender's address does not match the username used for authentication. reject-sender
DENIED_SENDER_NOT_LOCAL The connection was blocked because the sender's domain is not hosted on the local server. reject-sender
DENIED_TOO_MANY_RECIPIENTS The recipient was blocked because the limit was reached for this connection. The SMTP connection continues after this error occurs. max-recipients
DENIED_UNQUALIFIED_RECIPIENT The recipient was blocked because the recipient address had no domain name. The SMTP connection continues after this error occurs.  
DENIED_UNAVAILABLE_RECIPIENT The recipient was blocked because the recipient address is not receiving email at this time. The SMTP connection continues after this error occurs. reject-recipient
DENIED_ZERO_RECIPIENTS The message was blocked because no valid recipients have been specified.  
FAILED_AUTH The remote server attempted to authenticate but the given username and/or password were incorrect. smtp-auth-level
FAILED_TLS The remote client attempted to start a TLS session but SSL negotiation failed.  
TIMEOUT The connection timed out, either in total time or idle time. If the connection was already being blocked for another reason, the code for that error is given as REASON. connection-timeout-secs
idle-timeout-secs
TLS_ENCRYPTED The remote server has started a TLS session with qmail. spamdyke does not have access to the server's certificate file, so it cannot decrypt the traffic to log any information about senders or recipients. tls-level
UNKNOWN_AUTH The remote server requested an authentication method spamdyke doesn't support. This shouldn't happen.  

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.

TYPE is the type of encryption used during the connection. The possible values are listed below:

TYPE Description
(none) The connection is not encrypted.
TLS_PASSTHROUGH The client started a TLS connection with qmail, not with spamdyke. spamdyke is passing the encrypted traffic between the server and client, but cannot decrypt the data. As a result, some filters will not be able to run.
TLS The connection has been encrypted since the client started a TLS connection with spamdyke. All filters can run normally.
SSL The connection has been encrypted since the very beginning because the client connected using SSL (SMTPS). All filters can run normally.

REASON is provided to give an explanation of why a connection was blocked. See the table above for the possible values.

SMTP Error Codes

policy-url
rejection-text-auth-failure
rejection-text-auth-unknown
rejection-text-dns-blacklist
rejection-text-earlytalker
rejection-text-empty-rdns
rejection-text-graylist
rejection-text-header-blacklist
rejection-text-ip-blacklist
rejection-text-ip-in-cc-rdns
rejection-text-ip-in-rdns-keyword-blacklist
rejection-text-local-recipient
rejection-text-max-recipients
rejection-text-missing-sender-mx
rejection-text-rdns-blacklist
rejection-text-recipient-blacklist
rejection-text-recipient-invalid
rejection-text-recipient-same-as-sender
rejection-text-recipient-unavailable
rejection-text-reject-all
rejection-text-relaying-denied
rejection-text-rhs-blacklist
rejection-text-sender-authentication-mismatch
rejection-text-sender-blacklist
rejection-text-sender-not-local
rejection-text-smtp-auth-required
rejection-text-timeout
rejection-text-tls-failure
rejection-text-unresolvable-rdns
rejection-text-zero-recipients

When spamdyke blocks a connection and returns an error code to a remote server, the text it sends is different from what appears in the logs (above). It is more user-friendly, just in case a human ever reads it (some, but not all, mail servers display the rejection message in bounce messages).

The messages can be changed using the options that are listed in the third column of the table below.

The messages that correspond to the syslog codes are:

syslog code SMTP message Option to change message
DENIED_AUTH_REQUIRED Refused. Authentication is required to send mail. rejection-text-smtp-auth-required
DENIED_BLACKLIST_IP Refused. Your IP address is blacklisted. rejection-text-ip-blacklist
DENIED_BLACKLIST_NAME Refused. Your domain name is blacklisted. rejection-text-rdns-blacklist
DENIED_EARLYTALKER Refused. You are not following the SMTP protocol. rejection-text-earlytalker
DENIED_GRAYLISTED Your address has been graylisted. Try again later. rejection-text-graylist
DENIED_HEADER_BLACKLISTED Refused. Your message has been blocked due to its content. rejection-text-header-blacklist
DENIED_IDENTICAL_SENDER_RECIPIENT Refused. Identical sender and recipient addresses are not allowed. rejection-text-recipient-same-as-sender
DENIED_INVALID_RECIPIENT Refused. The recipient address does not exist. rejection-text-recipient-invalid
DENIED_IP_IN_CC_RDNS Refused. Your reverse DNS entry contains your IP address and a country code. rejection-text-ip-in-cc-rdns
DENIED_IP_IN_RDNS Refused. Your reverse DNS entry contains your IP address and a banned keyword. rejection-text-ip-in-rdns-keyword-blacklist
DENIED_OTHER The text returned by qmail (or the downstream filter that generated the rejection).  
DENIED_RBL_MATCH The text returned by the DNS RBL (if any) or
Refused. Your IP address is listed in the RBL at name.
rejection-text-dns-blacklist
DENIED_RDNS_MISSING Refused. You have no reverse DNS entry. rejection-text-empty-rdns
DENIED_RDNS_RESOLVE Refused. Your reverse DNS entry does not resolve. rejection-text-unresolvable-rdns
DENIED_RHSBL_MATCH The text returned by the RHSBL (if any) or
Refused. Your domain name is listed in the RHSBL at name.
rejection-text-rhs-blacklist
DENIED_RECIPIENT_BLACKLISTED Refused. Mail is not being accepted at this address. rejection-text-recipient-blacklist
DENIED_REJECT_ALL Refused. Mail is not being accepted. rejection-text-reject-all
DENIED_RELAYING Refused. Sending to remote addresses (relaying) is not allowed. rejection-text-relaying-denied
DENIED_SENDER_NOT_AUTH Refused. Your sender address does not match your authentication username. rejection-text-sender-authentication-mismatch
DENIED_SENDER_BLACKLISTED Refused. Your sender address has been blacklisted. rejection-text-sender-blacklist
DENIED_SENDER_NOT_LOCAL Refused. Mail for your sender domain is not hosted here. rejection-text-sender-not-local
DENIED_SENDER_NO_MX Refused. The domain of your sender address has no mail exchanger (MX). rejection-text-missing-sender-mx
DENIED_TOO_MANY_RECIPIENTS Too many recipients. Try the remaining addresses again later. rejection-text-max-recipients
DENIED_UNAVAILABLE_RECIPIENT Refused. The recipient is not accepting mail right now. rejection-text-recipient-unavailable
DENIED_UNQUALIFIED_RECIPIENT Improper recipient address. Try supplying a domain name. rejection-text-local-recipient
DENIED_ZERO_RECIPIENTS Refused. You must specify at least one valid recipient. rejection-text-zero-recipients
FAILURE_AUTH Refused. Authentication failed. rejection-text-auth-failure
FAILURE_TLS Failed to negotiate TLS connection. rejection-text-tls-failure
TIMEOUT Timeout. Talk faster next time. rejection-text-timeout
UNKNOWN_AUTH Refused. Unknown authentication method. rejection-text-auth-unknown

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 option should always be used. When a legitimate remote user is incorrectly blocked, the URL should provide your contact information so the error can be corrected.

spamdyke will always append the syslog code to the policy URL so a web browser will jump to an anchor within the HTML document. Most of the time, the code is prefixed with a # character. For example, if the policy URL is:

http://www.example.com/policy.html
spamdyke would generate the following URL for a rejection due to a missing reverse DNS entry:
http://www.example.com/policy.html#DENIED_RDNS_MISSING
However, if the policy URL ends in an equals sign (=), spamdyke will assume the URL is for a dynamic page and will not add the # character. For example, if the policy URL is:
http://www.example.com/policy?code=
spamdyke would generate the following URL for a rejection due to a missing reverse DNS entry:
http://www.example.com/policy?code=DENIED_RDNS_MISSING

Logging All Data

full-log-dir

spamdyke has the ability to log all SMTP data 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 a naming convention that incorporates the current date and time, the process ID of the spamdyke process and a random number:

YYYYMMDD_HHMMSS_PID_RANDOMNUM

The data 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.

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

The logs will contain all debugging output spamdyke can produce, the same output that would be produced if log-level were set to its highest level. spamdyke will also print its current configuration into the log file every time it processes a configuration file, to show what options are active and what their values are.

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 data, please use a packet sniffer on a separate machine or SMTP proxy software designed for the task.

Permissions

run-as-user

On most Unix-based systems, only the superuser can start a daemon that listens on port 25 (the SMTP port). However, since running daemons as the superuser should be avoided whenever possible, most qmail installations use utilities to switch the daemon's owner to a normal user before qmail actually runs.

Some older qmail installations lack this ability, notably ones that use the inetd "superserver" to start qmail. To help provide security in these situations, spamdyke provides the run-as-user option to force spamdyke to switch to a different user account as soon as it starts. All of spamdyke's child processes (including qmail) will run under the new user account.

The value of run-as-user takes the following form:

USER[:GROUP]
USER should be the name or user ID of a valid system user. If GROUP is not provided, spamdyke will join USER's default group. If GROUP is provided, it can be the name or group ID of a valid system group.

On systems where qmail does not run as the superuser, run-as-user can be used to force spamdyke to change accounts when the config-test option is used, so that its tests of filesystem permissions will be meaningful.

DNS Queries

dns-level
dns-max-retries-primary
dns-max-retries-total
dns-query-type-a
dns-query-type-mx
dns-query-type-ptr
dns-query-type-rbl
dns-resolv-conf
dns-server-ip
dns-server-ip-primary
dns-spoof
dns-tcp
dns-timeout-secs

Because so many of spamdyke's filters rely so heavily on DNS queries, spamdyke provides a number of options to tune its DNS activities. Take care when using any of these options, as setting them incorrectly can prevent spamdyke from functioning correctly. Most of the time, there is no need to use them -- spamdyke will read its DNS information from /etc/resolv.conf and the environment, as documented in the system resolver(5) manual page. If the option dns-resolv-conf is given, spamdyke will read the given file instead of /etc/resolv.conf. NOTE: spamdyke does not read the /etc/hosts file.

spamdyke ranks nameservers into two categories: "primary" and "secondary". Primary nameservers are queried first; secondary nameservers are only queried if no response is received from a primary nameserver.

Normally, spamdyke reads its list of nameservers from /etc/resolv.conf (or another file given with dns-resolv-conf), just like any other program. It considers the first nameserver it finds in that file to be a primary nameserver. All others are considered to be secondary nameservers. This list can be overridden, however, using the dns-server-ip and dns-server-ip-primary options. spamdyke also honors the port, timeout and options directives (if any) in the /etc/resolv.conf file (or another file given with dns-resolv-conf). If the environment variable RES_OPTIONS is present, spamdyke will parse it for a timeout value.

If either dns-server-ip or dns-server-ip-primary are used, the file /etc/resolv.conf is not loaded. Both options take values in the same format:

IPADDRESS[:PORT]
The IP address must be given in dotted-quad format (e.g. 11.22.33.44). The port number, if it is provided, must be an integer between 1 and 65535, inclusive. If the port number is not given, the value 53 is used.

dns-server-ip and dns-server-ip-primary can each be given multiple times to specify multiple servers in each category.

If dns-server-ip and dns-server-ip-primary are not given and no nameservers can be found by reading /etc/resolv.conf, the IP address 127.0.0.1 (the localhost address) is used.

By default, spamdyke will attempt to query its primary nameserver once, then all of its nameservers twice more, taking no more than 30 seconds total. The option dns-max-retries-total controls the total number of attempts spamdyke makes to contact its nameservers (the number of query packets actually sent may be much greater than this value; see below). The option dns-max-retries-primary controls how long spamdyke sends queries only to its primary nameservers. This value must be less than or equal to dns-max-retries-total.

The option dns-timeout-secs controls the total time spamdyke will spend waiting for the results of a single query. All of its retries will be carried out within this time limit. NOTE: The timeout value must be large enough for nameservers to complete their work and respond. If it is too low, spamdyke will never successfully complete a query.

The dns-level option controls how aggressively spamdyke queries its nameservers. It takes the following values:

  • aggressive: Query all primary nameservers simultaneously until dns-max-retries-primary is reached, then query all nameservers simultaneously until dns-max-retries-total is reached. This is the default. For example, if there are 2 primary nameservers, 3 secondary nameservers, dns-max-retries-primary is 4 and dns-max-retries-total is 6, spamdyke will: send a simultaneous query to each of the 2 primary nameservers 4 times, for a total of 8 queries. It will then send a simultaneous query to all 5 nameservers 2 more times, for a grand total of 18 queries.
  • normal: Imitate the standard system resolver's behavior by sending queries to one nameserver at a time. spamdyke will send queries to each of the primary nameservers in sequence until dns-max-retries-primary is reached, then it will add the secondary nameservers to the sequence and continue sending queries until dns-max-retries-total is reached. Depending on the number of nameservers and the values of dns-max-retries-primary and dns-max-retries-total, some nameservers may never be queried.
  • none: Do not query any nameservers at all. All DNS-based features will behave as though their queries returned no results.

Depending on the type of query spamdyke is performing, multiple packets are typically sent to each nameserver. By default, when querying a DNS RBL, a "query" consists of 3 packets -- one requesting A records, one requesting TXT records and one requesting CNAME records. In the aggressive example above, the 18 queries would result in 52 data packets. This behavior can be controlled through the use of several options:

dns-query-type-a: Sets the types of queries that are performed when seeking an IP address when looking up a reverse DNS name. The following values can be given:
  • a: Request and process DNS A records in response to queries.
  • cname: Request and process DNS CNAME records in response to queries. This is desirable if the target name is simply an alias for another name.
dns-query-type-mx: Sets the types of queries that are performed when seeking a mail server record within the "reject-missing-sender-mx" filter. The following values can be given:
  • a: Request and process DNS A records in response to queries. This is desirable if the name is a specific machine instead of a domain name.
  • cname: Request and process DNS CNAME records in response to queries. This is desirable if the target name is simply an alias for another name.
  • mx: Request and process DNS MX records in response to queries.
dns-query-type-ptr: Sets the types of queries that are performed when seeking a reverse DNS name. The following values can be given:
  • cname: Request and process DNS CNAME records in response to queries. This is desirable if the target name is simply an alias for another name. Many ISPs delegate PTR control this way.
  • ptr: Request and process DNS PTR records in response to queries.
dns-query-type-rbl: Sets the types of queries that are performed when querying a DNS RBL, RHSBL, DNS whitelist or RHSWL. The following values can be given:
  • a: Request and process DNS A records in response to queries.
  • cname: Request and process DNS CNAME records in response to queries.
  • txt: Request and process DNS TXT records in response to queries.
NOTE: It is not normally necessary to set these options; they are only useful in very specific situations where a local DNS server does not respond quickly to a specific type of query.

Most DNS queries are performed using UDP packets, which can carry no more than 512 bytes of data. This is enough data for typical DNS data, but occasionally some records are too big to fit in 512 bytes. When that happens, the nameserver should reply with a UDP packet that indicates the data is too large. The solution is to then resend the query via TCP, which can handle data of any size. spamdyke will fall back to TCP if the dns-tcp option is set to normal. If it is none, spamdyke will not use TCP at all; it will ignore the response entirely and continue its normal query pattern.

UDP packets are stateless, which means any server on the internet can send a UDP packet to any other server at any time. In theory, if spamdyke sends a DNS query via UDP and a malicious server sends a UDP response at the right moment, spamdyke will accept it as the answer to its query. (This would be extremely difficult, as the malicious server would have to know a lot about spamdyke's internal state to create an acceptable reply, but it is possible).

To prevent this from happening, spamdyke always checks the response ID against the query IDs and dicards any responses that don't match. In addition, spamdyke can check the IP address and port number of the remote server to see if they match the IP and port to which the query packet(s) were sent. The following values of the dns-spoof option control spamdyke's behavior:

  • accept-all: Accept any response from any server. This is the default.
  • accept-same-ip: Accept any response as long as the IP address of the sending server is the same as the IP address the query was sent to. The port number may be different.
  • accept-same-port: Accept any response as long as the port number on the sending server is the same as the port number the query was sent to. The IP address may be different. (This option may not be very useful.)
  • reject: Only accept responses where the IP address and port number of the sending server match the IP address and port number the query was sent to.
NOTE: Be very careful when setting the dns-spoof option. Some DNS servers may send responses from different port numbers as part of their normal operation. Moreover, multi-homed servers may send responses from different IP addresses. If you don't need to use this option, don't.

Filter Levels

filter-level

spamdyke's overall filter behavior can be controlled with the filter-level option. NOTE: filter-level takes precedence over all other filters and features, including authentication and whitelisting.

The possible values are:

  • allow-all: Allow all connections, effectively whitelisting everything.
  • normal: Allow only the connections that pass the enabled filters. This is the default.
  • require-auth: Allow only authenticated connections, even the ones that match a whitelist entry.
  • reject-all: Reject all connections, even if they are whitelisted or authenticated.

The values allow-all and reject-all are most useful within configuration directories, where they can be set e.g. for specific recipients.

TLS

tls-certificate-file
tls-cipher-list
tls-dhparams-file
tls-level
tls-privatekey-file
tls-privatekey-password
tls-privatekey-password-file

TLS is another name for SSL, the same encryption protocol used by secure websites (it's called SSL when the entire connection is encrypted from the start, it's called TLS when the encryption is started later during the connection). TLS can be used during SMTP to provide secure communications between the remote client and the server.

spamdyke supports TLS in several ways. First, with no TLS options given, spamdyke will identify a TLS conversation and simply pass the data back and forth between qmail and the remote client. In this mode, spamdyke cannot read the SMTP data (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 OpenSSL libraries on the server (see the Installation instructions for details). The value of the tls-level option controls how TLS is provided:

  • none: Do not provide or allow TLS, even if qmail supports it. qmail's attempt to advertise its TLS support will be hidden and the remote server's request for TLS will be denied.
  • smtp: Provide TLS during the SMTP session, so it can be started if the remote server requests it. spamdyke will decrypt all of the data and pass the plaintext to qmail. qmail will not be aware TLS is happening. In this mode, qmail does not need to be patched to provide TLS. However, if the SSL library cannot be initialized for some reason (e.g. missing certificate, bad cipher list), the TLS data will be passed through to qmail in encrypted format so qmail can provide TLS (assuming qmail has been patched to support it). In this mode, spamdyke will not be able to read the data, so some of its filters will not function.
  • smtp-no-passthrough: Provide TLS during the SMTP session, so it can be started if the remote server requests it. spamdyke will decrypt all of the data and pass the plaintext to qmail. qmail will not be aware TLS is happening. In this mode, qmail does not need to be patched to provide TLS. If spamdyke cannot start TLS for any reason, the encrypted data will not be passed through to qmail.
  • smtps: Start an SSL session as soon as the connection is opened. This mode is called "SMTP over SSL" or "SMTPS". The remote client must support this method. Typically, SMTPS is offered on port 465, not port 25.

If tls-level is smtp, smtp-no-passthrough or smtps, the server certificate must also be provided with the tls-certificate-file parameter.

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.

Rarely, some situations will require specifying the list of encryption algorithms (ciphers) to be used during TLS. In those cases, the tls-cipher-list option can be used to pass a list of ciphers in the format expected by the OpenSSL library. The vast majority of spamdyke installations will not need this option -- the default list of ciphers is usually fine. To see the full list of available ciphers, run the command openssl ciphers. For details on how to construct the list, see www.openssl.org/docs/apps/ciphers.html. NOTE: Be careful to check the list of ciphers very carefully -- invalid ciphers (typos) are allowed and will be silently ignored. The OpenSSL library will only produce an error if none of the ciphers in the list can be used.

Some ciphers will generate "ephemeral" keys for encrypting the connection, which provides an extra level of security (referred to as "forward security"). In order to do this, an additional "DH params" file must be provided in PEM format with the tls-dhparams-file option. The file can be generated using the openssl dhparam command. NOTE: This option is unneeded unless the tls-cipher-list option is also used to specify a cipher that requires a "DH params" file.

If there are any problems reading the certificate, the private key, decrypting the private key or initializing the ciphers, spamdyke will log the errors to syslog and fall back to passing the TLS data 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 or SSL. In SMTP, TLS/SSL is simply a method of securing the communication channel. It is not an authentication method and spammers are using TLS. 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 data is always a good thing.

SMTP AUTH

hostname
hostname-command
hostname-file
smtp-auth-command
smtp-auth-level

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 shops, hotels) and want to bypass relaying restrictions and other filters. spamdyke will disable all of its filters for authenticated connections unless the filter-level option overrides this behavior. See Filter Levels for details.

spamdyke supports SMTP AUTH according to the value of the smtp-auth-level option:

  • none: Do not offer or allow SMTP AUTH. If qmail has been patched to provide SMTP AUTH, spamdyke will block its advertisement of SMTP AUTH and will prevent the remote server from authenticating.
  • observe: If qmail has been patched to provide SMTP AUTH, simply observe the authentication and trust qmail's response. If qmail has not been patched to provide SMTP AUTH, do not provide SMTP AUTH. This is the default.
  • ondemand: If qmail has been patched to provide SMTP AUTH, simply observe the authentication and trust qmail's response. If qmail has not been patched to provide SMTP AUTH, offer it and process the authentication without letting qmail know it took place.
  • ondemand-encrypted: Offer SMTP AUTH as needed, just like ondemand, but also offer the encrypted protocol CRAM-MD5. See below for a full description.
  • always: Always offer and process SMTP AUTH, even if qmail has been patched to provide SMTP AUTH. This value should only be used if qmail's authentication is malfunctioning for some reason.
  • always-encrypted: Always offer and process SMTP AUTH, just like always, but also offer the encrypted protocol CRAM-MD5. See below for a full description.

When the value of smtp-auth-level is ondemand, ondemand-encrypted, always or always-encrypted, the option smtp-auth-command must also be given to provide spamdyke with the command for processing authentication. If multiple commands are available, smtp-auth-command may be given multiple times. spamdyke will run each command in order until one of them is successful.

For bare qmail installations where the users are stored in /etc/passwd the value of smtp-auth-command is usually:

/bin/checkpassword /bin/true
For vpopmail users, the value of smtp-auth-command is usually:
/home/vpopmail/bin/vchkpw /bin/true

For Plesk users, the values of smtp-auth-command are usually:

/var/qmail/bin/smtp_auth /var/qmail/bin/true
/var/qmail/bin/cmd5checkpw /var/qmail/bin/true

Some background on encrypted authentication: SMTP AUTH can be done using one of several protocols, defined by RFC 2554. Two of them are very simple: LOGIN and PLAIN. Although they work slightly differently, LOGIN and PLAIN both send the username and password to the server, which authenticates them. With these protocols, the server does not have to store the user's password in an unencrypted format. If the passwords are encrypted on the server, the authentication process can simply encrypt the password it receives and compare the two encrypted versions. If they match, the password must have been correct.

Unfortunately, this means that the password must be sent to the server in an unencrypted format so the authentication process can encrypt it for comparison. Unless an external encryption protocol is used (e.g. TLS or SMTPS), the passwords are theoretically vulnerable to eavesdropping.

For this reason, another protocol was created called CRAM-MD5. CRAM-MD5 is a "challenge/response" protocol, which allows authentication to take place without sending the password to the server in an unencrypted form. In essence, the protocol starts when the server generates some random text and sends it to the remote client (the "challenge"). The remote client encrypts the text with the user's password and sends it back to the server (the "response"). The server also encrypts the text with the user's password and compares the result to the response from the client. If they match, the remote client must have the correct password.

The challenge text is generated from several sources, including the name of the local server. The hostname, hostname-command or hostname-file option can be used to provide the local server's name for this reason. When hostname is used, the value should be the server's name. When hostname-command is used, the value should be a command that will print the server's name as its first line of output. When hostname-file is used, the value should be the path to a file that contains the server's name as its first line. By default, hostname-file is set to /var/qmail/control/me. NOTE: If the local server's name is not provided, CRAM-MD5 will still work and it will still generate random challenge text. Using the local server's name only makes it slightly more secure. It's not worth a large effort to provide it.

Unfortunately, this means that the password must be stored on the server in an unencrypted format so the authentication process can use it to encrypt the challenge text. Theoretically, this leaves the passwords vulnerable to theft by an intruder who breaks into the server.

When smtp-auth-level is ondemand-encryption or always-encryption, spamdyke will offer the CRAM-MD5 protocol to the remote client. However, if the passwords are not stored on the server in an unencrypted format or if the authentication command does not understand CRAM-MD5, CRAM-MD5 will always fail.

If you're not sure which value to use, run spamdyke with the config-test option. It will test the authentication commands and recommend a value. See Configuration Tests for details.

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

Relaying

ip-relay-entry
ip-relay-file
rdns-relay-entry
rdns-relay-file
relay-level

A little background: when a message is delivered for a recipient that isn't hosted on the local server, that message is said to be "relayed". Most servers do not allow relaying except from authorized sources, in order to prevent abuse by spammers or poorly-configured software. When a server allows every connection to relay messages without authentication, it is called an "open relay". Open relays are quickly blacklisted all across the internet because spammers quickly exploit them for sending massive amounts of email.

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 in the /etc/tcp.smtp file:

11.22.33.44:allow,RELAYCLIENT=""

spamdyke's relay-level option controls how spamdyke controls relaying. The available options are:

  • block-all: Block all attempts at relaying, even if the remote server has authenticated.
  • normal: Do not check for or prevent relaying and do not interfere with qmail's relay filter. Authenticated connections and any servers identified by the options ip-relay-entry, ip-relay-file, rdns-relay-entry and rdns-relay-file are allowed to relay. This is the default.
  • allow-all: Allow all connections to relay messages (create an open relay). This is not recommended.

spamdyke will allow relaying from IP addresses listed in a file and given with the option ip-relay-file. See IP Address Files for details on the format of this file. If the ip-relay-file option is given multiple times, each file will be checked for the remote IP address; relaying will be allowed if the IP address is found in any of the files.

If only a few IP addresses should be allowed to relay, the option ip-relay-entry may be used instead. The entries should follow the format as the lines in an IP address file.

Alternatively, spamdyke will allow relaying from rDNS names listed in a file and given with the option rdns-relay-file. See rDNS Files for details on the format of this file. If the rdns-relay-file option is given multiple times, each file will be checked for the rDNS name; relaying will be allowed if the rDNS name is found in any of the files.

If only a few rDNS names should be allowed to relay, the option rdns-relay-entry may be used instead. The entries should follow the format as the lines in an rDNS file.

Reverse DNS

ip-in-rdns-keyword-blacklist-entry
ip-in-rdns-keyword-blacklist-file
ip-in-rdns-keyword-whitelist-entry
ip-in-rdns-keyword-whitelist-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 query mail.example.com. Even if it resolves to 66.77.88.99, 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 also has several filters that 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). If the rDNS name contains the IP address and a keyword given with the ip-in-rdns-keyword-blacklist-entry option, spamdyke will block the connection.

Simple keywords can be provided. For example, dynamic will match an rDNS name like 11.22.33.44.dynamic.example.com. NOTE: The keyword will not be matched in the domain name (i.e. the keyword example would not be found).

Domain names can be provided if they are preceded by a dot. For example, .example.com (or just .com) will match 11.22.33.44.dynamic.example.com.

Complex patterns can also be provided to match multiple keywords in sequence. When the keywords are separated by spaces, spamdyke will only find a match if all of the keywords are found. For example, cable dynamic .example.com will match 11.22.33.44.cable.modem.dynamic.customer.example.com but it will not match 11.22.33.44.cable.modem.static.customer.example.com.

All keyword searches are case-insensitive.

If more than a few keywords are provided, the ip-in-rdns-keyword-blacklist-file option is much more efficient. The keywords (or patterns) should be listed one per line. Blank lines and lines beginning with # will be ignored.

spamdyke also accepts the ip-in-keyword-whitelist-entry and ip-in-keyword-whitelist-file options that match keywords exactly the same way as the blacklist options. The whitelist options bypass all filters when a connection matches, however, instead of blocking the connection.

spamdyke offers one other option that searches for an IP address in the rDNS name: reject-ip-in-cc-rdns. In essence, this option is the same as using ip-in-rdns-keyword-blacklist-entry for every two-letter country code (e.g. .us). This option is not very useful for large servers or servers outside the United States. As ICANN begins allowing arbitrary top-level domains, two-letter domains will no longer be a reliable way of detecting non-US servers.

When matching an IP address in an rDNS name, 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
11.022.033.044
11.22.033.044
11.22.33.044
44.33.22.11
44.33.22.011
44.33.022.011
44.033.022.011
044.033.022.011
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
11.22.3344
11.223344
011022033044
11022033044
1122033044
112233044
44332211
044033022011
3930621781 (entire address converted to an integer)
5080d7e3 (each octet converted to hexadecimal)

Blacklists

ip-blacklist-entry
ip-blacklist-file
rdns-blacklist-dir
rdns-blacklist-entry
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.

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

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.

If only a few rDNS names should be blacklisted, the option rdns-blacklist-entry can be used instead. The entries should follow the same format as the lines in an rDNS file.

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.

If only a few IP addresses should be blacklisted, the option ip-blacklist-entry can be used instead. The entries should follow the same format as the lines in an IP address file.

DNS RBLs

dns-blacklist-entry
dns-blacklist-file

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 dns-blacklist-entry option. By default, spamdyke does not use a DNS RBL. If the dns-blacklist-entry option is given multiple times, each DNS RBL will be checked before the connection is allowed.

If more than a few DNS RBLs are needed, the dns-blacklist-file option is more efficient than dns-blacklist-entry. Each line in the file should contain the name of one DNS RBL.

NOTE: Checking DNS RBLs can impose a serious performance penalty. Using more than three DNS RBLs is not recommended.

DNS RHSBLs

rhs-blacklist-entry
rhs-blacklist-file

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 rhs-blacklist-entry option. By default, spamdyke does not use a DNS RHSBL. If the rhs-blacklist-entry option is given multiple times, each DNS RHSBL will be checked before the connection is allowed.

If more than a few DNS RHSBLs are needed, the rhs-blacklist-file option is more efficient than rhs-blacklist-entry. Each line in the file should contain the name of one DNS RHSBL.

NOTE: Checking DNS RHSBLs can impose a serious performance penalty. Using more than three DNS RHSBLs is not recommended.

Whitelists

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

spamdyke will match the remote server's rDNS name against a list given with the rdns-whitelist-entry option and skip all filters if it is found. If more than a few entries are given, the rdns-whitelist-file option is much more efficient; it can be used to put the entries in a file, one per line. 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 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 list of entries and skip all filters if it is found. This is activated with the ip-whitelist-entry option. If more than a few entries are given, the ip-whitelist-file option is more efficient; it can be used to put the entries in a file. 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

reject-sender
sender-blacklist-entry
sender-blacklist-file

Before using spamdyke's options to block senders, it's important to understand the difference between a "sender address" (sometimes call the "envelope sender") and the "from address". The "sender address" is the email address given to the mail server when the message arrives and it's where a bounce message will be sent. The "from address" is what the user sees in their email client on the "from" line. The two addresses can be completely different and totally unrelated. To use an analogy, the "sender address" is like the return address written on the outside of a snail mail envelope. If the envelope can't be delivered, the post office will send it back to the sender address. The "from address" is like the address on the top of the letter inside the envelope. The post office never sees the letter inside the envelope, so it they can't use it. spamdyke (and qmail) is like the post office -- it uses only the "sender" address. That's why the filters described in this section work on the "sender" address, not the "from" address. To block messages based on the "from" address, see Rejecting Messages by Header Content.

spamdyke will block all incoming messages from a specific address with the sender-blacklist-entry option. If more than a few addresses are given, the sender-blacklist-file option is more efficient. The given file must contain one email address per line. Blank lines and lines beginning with # are ignored. If the sender-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.

spamdyke's reject-sender option controls several other filters for blocking senders and it can be used multiple times to enable more than one filter. The available options are:

  • none: Disable the reject-sender filters. This is the default.
  • no-mx: Use DNS to check if a sender's domain name can receive email. To pass this filter, the sender's domain name must have a valid mail exchanger (MX record) and the mail exchanger must have an IP address (A record). This filter tends to block a lot of mail from compromised web servers that aren't supposed to be sending email.
  • not-local: Senders are only accepted if their domain name is hosted on the local server. This is determined by searching the files given using the qmail-rcpthosts-file and qmail-morercpthosts-cdb options. Those options have default values but if the files do not exist or those options are cleared, this value has no effect. See Rejecting Recipients for more details on those options.
  • authentication-mismatch: Senders are only accepted if the sender address is the same as the username that was used for authentication. This filter enforces an exact match. For example, if the mail client authenticated with the username fred@example.com, the sender must be exactly fred@example.com. If the mail client authenticated with a username that wasn't an email address, this filter will only match the username portion of the sender address. For example, if the mail client authenticated with just barney, this filter will allow both barney@example.com and barney@somethingelse.net, because they both begin with barney@. NOTE: if the mail client does not authenticate, this value has no effect.
  • authentication-domain-mismatch: Senders are only accepted if the sender's domain name is the same as the domain name of the email address used for authentication. For example, if the mail client authenticated with the username wilma@bedrock.com, the sender address barney@bedrock.com will be accepted but fred@flintstone.com will not. If the mail client authenticates with a username that isn't an email address, this value has no effect. NOTE: if the mail client does not authenticate, this value has no effect.

Rejecting Recipients

qmail-morercpthosts-cdb
qmail-rcpthosts-file
recipient-blacklist-entry
recipient-blacklist-file
recipient-validation-command
reject-recipient

There are lots of different reasons for wanting to block messages to specific recipient addresses. Sometimes spammers will choose to target a specific address and send it thousands of messages. Sometimes a spammer will use one of your email addresses as the sender address on thousands of spam messages and you receive bounce messages for all of their spams. (This is commonly referred to as a "joe job".) Many spammers attempt to send messages that are "from" and "to" the same address, hoping to bypass spam filters. spamdyke can stop those messages as well.

But most often, qmail administrators need a way to stop "backscatter spam". This is the name given to spam that is sent to invalid addresses. If the mail server accepts the message and later tries to send a bounce message, it results in "backscatter" because the "from" address is almost always invalid, which makes the bounce message land in some other victim's mailbox. qmail will do this, because it was created before spam was really a problem. spamdyke can validate recipient addresses as they come in and reject invalid addresses, which stops backscatter spam in its tracks.

spamdyke will block all incoming messages to a specific address with the recipient-blacklist-entry option. If more than a few addresses are given, the recipient-blacklist-file option is much more efficient. 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.

spamdyke's other recipient filters are activated through the reject-recipient option, which has the following options:

  • none: Disable the reject-recipient filters. This is the default.
  • same-as-sender: Reject any recipient address that is the same as the sender address.
  • invalid: Reject any invalid recipient address. This filter rejects any address that will result in a bounce message from qmail.
  • unavailable: Reject any recipient address that is currently unavailable. Under certain conditions (usually depending upon permission settings on specific files), qmail will queue messages to an address until the conditions are resolved. If the message is queued too long, it will bounce. This feature may have been useful a few decades ago (maybe), when everyone used text-based mail readers and routinely logged into shell accounts on their mail servers. These days however, it has techically become a "misfeature". If these conditions are ever triggered, they are almost certainly an accident and won't be corrected before the message bounces. It's usually best to use this value whenever invalid is also in use.

In order for spamdyke to reject invalid or unavailable recipients, it must have access to a number of qmail's control files. Two files are used by spamdyke itself: the "rcpthosts" file and the "morercpthosts" CDB file. The path to the "rcpthosts" file is usually /var/qmail/control/rcpthosts, but this default value can be changed with the qmail-rcpthosts-file. Similarly, the path to the "morercpthosts" CDB file is usually /var/qmail/control/morercpthosts.cdb, but this default value can be changed with qmail-morercpthosts-cdb (be sure to provide the path to the CDB file, not the text that was used to create it). NOTE: The only reason to change the paths to these two files is if qmail was compiled to use files in a different location. If different input files are provided to spamdyke and qmail, the recipient validation procedure will not function properly.

For the remainder of the recipient validation process, a number of other qmail configuration files must be accessed, along with the recipients' mail configuration files (often stored in their home directories). Unfortunately, there is only one user (on most systems) who can access all the needed files: root. spamdyke does not normally run as root because it is started by the tcpserver process, which is typically run with a non-root account. For this reason, the recipient validation procedure is contained in spamdyke-qrv, which is intended to be run as root (technically "setuid root"). spamdyke-qrv will validate an address and return its result to spamdyke, which allows spamdyke to function while running as a non-root user. In order to use spamdyke-qrv, the recipient-validation-command option must be given with the full path to the spamdyke-qrv binary (spamdyke will not search the PATH for spamdyke-qrv).

For full details on spamdyke-qrv and how it works, see Recipient Validation With spamdyke-qrv.

DNS Whitelists

dns-whitelist-entry
dns-whitelist-file
rhs-whitelist-entry
rhs-whitelist-file

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 dns-whitelist-entry should be given. To use a DNS Righthand-side Whitelist, the option rhs-whitelist-entry 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.

If more than a few lists are given, the dns-whitelist-file or rhs-whitelist-file options may be used to provide the lists in files.

NOTE: Checking DNS whitelists can impose a serious performance penalty. Using more than three DNS whitelists is not recommended.

Whitelisting Senders and Recipients

recipient-whitelist-entry
recipient-whitelist-file
sender-whitelist-entry
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 they just think spamdyke is blocking their email. In those cases, a 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 whitelist a sender or recipient address, the sender-whitelist-entry or recipient-whitelist-entry option should be used, respectively. The entries can use the same formats as those for sender-blacklist-entry and recipient-blacklist-entry; see Rejecting Recipients for details.

Whitelist entries can be placed in files and referenced with sender-whitelist-file or recipient-whitelist-file. This is more efficient for more than a few entries.

Graylisting / Greylisting

graylist-dir
graylist-exception-ip-entry
graylist-exception-ip-file
graylist-exception-rdns-dir
graylist-exception-rdns-entry
graylist-exception-rdns-file
graylist-level
graylist-max-secs
graylist-min-secs

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-level option, which will accept the following values:

  • none: Do not graylist any connections. This is the default.
  • always: Always graylist connections if a domain folder exists for the recipient and the remote server's IP address or rDNS name are not found on one of the exception lists.
  • always-create-dir: Always graylist connections unless the remote server's IP address or rDNS name are found on one of the exception lists. If a domain folder does not exist for the recipient, create it.
  • only: Do not graylist any connections unless a domain folder exists for the recipient and the remote server's IP address or rDNS name are found on one of the exception lists.
  • only-create-dir: Do not graylist any connections unless the remote server's IP address or rDNS name are found on one of the exception lists. If a domain folder does not exist for the recipient, create it.

The option graylist-dir is required if graylist-level is not none. The value of graylist-dir must be the path to a directory where spamdyke has permission to create folders and write files.

A list of local domains must also be provided with qmail-rcpthosts-file. Without a list of local domains, spamdyke cannot know which domains should be graylisted. See Rejecting Recipients for details.

The "domain directories" required by graylist-level's always and only values are just folders named using the recipient's domain name. For example, if the value of graylist-dir is:

/var/tmp/graylist.d
and the recipient's domain is example.com, the domain directory would be:
/var/tmp/graylist.d/example.com
Domain directories allow graylisting to be selectively activated for only some domains. If all domains should be graylisted, use always-create-dir or only-create-dir instead.

NOTE: Domain directories must be named in lowercase. Unfortunately, spamdyke cannot perform a case insensitive search for directory paths.

If graylist-dir is given multiple times, spamdyke will search each given directory for the recipient's domain folder. If the domain folder is not found and the value of graylist-level is always-create-dir or only-create-dir, spamdyke will create a domain folder in the last directory given.

As spamdyke creates graylist entries, it breaks apart the sender's and recipient's addresses to create folders. For example, a graylist entry for messages from sender@remote.com to recipient@local.com will be a file with the following path:

.../local.com/recipient/remote.com/sender@remote.com
NOTE: This directory structure is different from the one created by spamdyke prior to version 4.0.0. If spamdyke encounters an old-style directory structure, it will silently convert the entries to the new structure as they are used.

If the options graylist-exception-ip-entry or graylist-exception-rdns-entry are given, spamdyke will reverse its graylist policy for remote servers whose IP addresses or rDNS names, respectively, match the given entries.

If more than a few IP address or rDNS entries are given, the options graylist-exception-ip-file and graylist-exception-rdns-file are more efficient. See IP Address Files and rDNS Files for details on the formats of these files.

If more than 100 entries are given in an rDNS file, the option graylist-exception-rdns-dir is more efficient than graylist-exception-rdns-file. See rDNS Directories for details.

spamdyke accepts two options to control the lifetimes of its graylist entries. The option graylist-min-secs controls the minimum amount of time an entry must exist before it is valid. For example, if the value 300 is given, a graylist entry is not valid until it has existed for at least 5 minutes. This prevents a spammer from attempting delivery twice in rapid succession.

The option graylist-max-secs controls the maximum amount of time an entry will remain valid after it is created. For example, if the value 604800 is given, a graylist entry will become invalid after 7 days. If the sender attempts to deliver a message after the entry has expired, they will be graylisted again. NOTE: A graylist entry's expiration date is reset each time a message passes the filter. If the maximum age is 2 weeks and the sender sends a message every day, their entry will never expire because it is continually reset.

As of 2013, graylisting is becoming more and more widespread. Spammers are adapting by sending their spam through legitimate servers, which aren't stopped by graylisting. There are still enough botnets using unintelligent spam software to make graylisting worthwhile but its effectiveness is definitely declining.

NOTE: Because spamdyke's graylist filter creates lots (and lots) of small files, it can threaten a server's filesystem by consuming all of the available inodes (especially on busy servers). Be sure to monitor the number of available inodes in case this becomes a problem.

Earlytalkers

greeting-delay-secs

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

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.

It may seem strange that spamdyke will accept the greeting-delay-secs in a configuration directory, since the delay must take place long before the sender or recipient addresses are known. There is one allowed scenario however -- the command line or global configuration file may activate the earlytalker filter and the configuration directory may deactivate it. In that case, the connection will be delayed but the results of the test will be ignored. The reverse is not possible however -- the configuration directory cannot activate the filter or change its delay amount. See Configuration Directories for more information.

Unfortunately, spammers have mostly updated their software so this trick doesn't work any more. It still catches badly written botnet spam sources though.

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

Rejecting Messages by Header Content

header-blacklist-entry
header-blacklist-file

Email messages are divided into two parts: the header and the body. The header is composed of data fields that are parsed by mail agents so the data can be shown to the user in a useful way. For example, the subject line and the date are part of the header. The message body contains all of the text (often HTML these days) and attachment data.

spamdyke has the ability to filter incoming messages based on header content. Every header line is supposed to use the following format:
NAME: VALUE
For example:
Subject: Fantastic news!
When header-blacklist-entry is used, its value will be matched against each line in the incoming message header. If one or more lines match, the message will be rejected. header-blacklist-file works much the same way, except the values are read from the given file, one per line.

Before attempting to match values to headers, spamdyke first compresses any whitespace by converting runs of multiple whitespace characters to a single space. If the header line in the message occupies multiple lines, spamdyke "unfolds" it into a single line. The values are then compared in a case-insensitive manner. All values must contain at least one colon (:) or they will be ignored.

Shell-style wildcards are allowed ("globbing"):
  • An asterisk (*) will match zero or more characters.
  • A question mark (?) will match a single character.
  • A bracketed series of characters (e.g. [abcd]) will match any one of the bracketed characters.
  • ...probably more, depending on the implementation of fnmatch() on your system.
For example, this value:
Subject:*c?a[i1]is*
Will match any of the following:
Subject: cialis
Subject: Got some cialis for you
Subject: Need cXalis?
Subject: Order cia1is today

NOTE: Be very careful when adding header blacklists. Spammers are very clever about avoiding content filtering (they have decades of experience) but normal users are not. It is very easy to create a blacklist entry that will block legitimate email without blocking any spam at all.

NOTE: In order to filter headers, spamdyke must buffer the header content in memory while the message is being delivered. It will allocate up to 512K to do this. If you are using DJB's "softlimit" program to prevent excessive memory allocation, you should remove it, period. See this FAQ question for more details.

When header-blacklist-entry or header-blacklist-file are used within per-recipient configuration directories, they don't behave like other options. Most options can be set per-recipient and only affect delivery to that recipient. Header blacklisting is an all-or-nothing affair, so when those options are found in a per-recipient configuration directory, they are cumulative. For example, suppose two recipients have configuration directories. In the first recipient's directory, the following option is found:
header-blacklist-entry=Subject: Cialis
In the second recipient's directory, another option is found:
header-blacklist-entry=Subject: Viagra
When spamdyke applies the header blacklist filter, both values will be used. If either one matches, the message will be rejected for both recipients (assuming the incoming message is being delivered to both recipients simultaneously).

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 not activated.

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.
timefilter
A utility for filtering log files to display log entries from within a given date range. Only really useful in scripts.

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.