SpamPD - Spam Proxy Daemon (version 2.2)
] [ --relayhost=hostname[:port]
] [ --group|g=groupname
] #[ --maxchildren|mc=n
] [ --maxrequests=n
] [ --satimeout=n
] [ --pid|p=filename
] [ --logsock=inet|unix
] [ --maxsize=n
] [ --tagall|a
] [ --log-rules-hit|rh
] [ --set-envelope-from|sef
] [ --local-only|L
] [ --debug|d
is an SMTP/LMTP proxy that marks (or tags) spam using SpamAssassin
(http://www.SpamAssassin.org/). The proxy is designed to be transparent to the
sending and receiving mail servers and at no point takes responsibility for
the message itself. If a failure occurs within spampd
then the mail servers will disconnect and the sending server is still
responsible for retrying the message for as long as it is configured to do so.
uses SpamAssassin to modify (tag) relayed messages based on their
spam score, so all SA settings apply. This is described in the SA
will by default only tell SA to tag a message if
it exceeds the spam threshold score, however you can have it rewrite all
messages passing through by adding the --tagall option (see SA for how
non-spam messages are tagged).
logs all aspects of its operation to syslog
(8), using the
mail syslog facility.
The latest version can be found at
- Time::HiRes (not actually required but
is meant to operate as an S/LMTP mail proxy which passes each
message through SpamAssassin for analysis. Note that spampd
does not do
anything other than check for spam, so it is not suitable as an anti-relay
system. It is meant to work in conjunction with your regular mail system.
Typically one would pipe any messages they wanted scanned through
after initial acceptance by your MX host. This is especially
useful for using Postfix's (http://www.postfix.org) advanced content filtering
mechanism, although certainly not limited to that application.
Please re-read the second sentence in the above paragraph. You should NOT enable
to listen on a public interface (IP address) unless you know
exactly what you're doing! It is very easy to set up an open relay this way.
Here are some simple examples (square brackets in the "diagrams"
indicate physical machines):
Running between firewall/gateway and internal mail server
Using Postfix advanced content filtering
The firewall/gateway MTA would be configured
to forward all of its mail to the port that spampd
listens on, and
would relay its messages to port 25 of your internal server.
could either run on its own host (and listen on any port) or it
could run on either mail server (and listen on any port except port 25).
Internet -> [ MX gateway (@inter.net.host:25) ->
spampd (@localhost:2025) ] ->
Internal mail (@private.host.ip:25)
Please see the FILTER_README
with the Postfix distribution. You need to have a version of Postfix which
supports this (ideally v.2 and up).
Internet -> [ Postfix (@inter.net.host:25) ->
spampd (@localhost:10025) ->
Postfix (@localhost:10026) ] -> final delivery
Note that these examples only show incoming mail delivery. Since it is usually
unnecessary to scan mail coming from your network (right?), it may be
desirable to set up a separate outbound route which bypasses spampd
If upgrading from a version prior to 2.2, please note that the --add-sc-header
option is no longer supported. Use SAs built-in header manipulation features
instead (as of SA v2.6).
Upgrading from version 1 simply involves replacing the spampd
file with the latest one. Note that the dead-letters
folder is no
longer being used and the --dead-letters option is no longer needed (though no
errors are thrown if it's present). Check the "Options" list below
for a full list of new and deprecated options. Also be sure to check out the
can be run directly from the command prompt if desired. This is
useful for testing purposes, but for long term use you probably want to put it
somewhere like /usr/bin or /usr/local/bin and execute it at system startup.
For example on Red Hat-style Linux system one can use a script in
/etc/rc.d/init.d to start spampd
(a sample script is available on the
Web page @
The options all have reasonable defaults, especially for a Postfix-centric
installation. You may want to specify the --children option if you have an
especially beefy or weak server box because spampd
is a memory-hungry
program. Check the "Options" for details on this and all other
Note that spampd replaces spamd
distribution in function. You do not need to run
in order for spampd
to work. This has apparently been the
source of some confusion, so now you know.
Here is a typical setup for Postfix "advanced" content filtering as
described in the FILTER_README
that came with the Postfix distribution
(which you really need to read):
smtp inet n - y - - smtpd
localhost:10026 inet n - n - 10 smtpd
The first entry is the main public-facing MTA which uses localhost:10025 as the
content filter for all mail. The second entry receives mail from the content
filter and does final delivery. Both smtpd instances use the same Postfix
is the process that listens on
localhost:10025 and then connects to the Postfix listener on localhost:10026.
Note that the "myhostname" options must be different between the two
instances, otherwise Postfix will think it's talking to itself and abort
For the above example you can simply start spampd
spampd --host=localhost:10025 --relayhost=localhost:10026
from the Postfix distro has more details and examples of
various setups, including how to skip the content filter for outbound mail.
Another tip for Postfix when considering what timeout values to use for
--childtimout and --satimeout options is the following command:
"# postconf | grep timeout"
This will return a list of useful timeout settings and their values. For
explanations see the relevant "man" page (smtp, smtpd, lmtp). By
is set up for the default Postfix timeout values.
- --host=ip[:port] or hostname[:port]
- Specifies what hostname/IP and port spampd listens
on. By default, it listens on 127.0.0.1 (localhost) on port 10025.
Important! You should NOT enable spampd to listen on a public
interface (IP address) unless you know exactly what you're doing!
- Specifies what port spampd listens on. By default,
it listens on port 10025. This is an alternate to using the above
- --relayhost=ip[:port] or hostname[:port]
- Specifies the hostname/IP where spampd will relay
all messages. Defaults to 127.0.0.1 (localhost). If the port is not
provided, that defaults to 25.
- Specifies what port spampd will relay to. Default is
25. This is an alternate to using the above --relayhost=ip:port
- --user=username or --u=username
- --group=groupname or --g=groupname
- Specifies the user and group that the proxy will run as.
Default is mail/mail.
- --children=n or --c=n
- Number of child servers to start and maintain (where n >
0). Each child will process up to --maxrequests (below) before exiting and
being replaced by another child. Keep this number low on systems w/out a
lot of memory. Default is 5 (which seems OK on a 512MB lightly loaded
system). Note that there is always a parent process running, so if you
specify 5 children you will actually have 6 spampd processes
You may want to set your origination mail server to limit the number of
concurrent connections to spampd to match this setting (for Postfix
this is the "xxxx_destination_concurrency_limit" setting where
'xxxx' is the transport being used, usually 'smtp', and the default is
- spampd works by forking child servers to handle each
message. The maxrequests parameter specifies how many requests will
be handled before the child exits. Since a child never gives back memory,
a large message can cause it to become quite bloated; the only way to
reclaim the memory is for the child to exit. The default is 20.
- This is the number of seconds to allow each child server
before it times out a transaction. In an S/LMTP transaction the timer is
reset for every command. This timeout includes time it would take to send
the message data, so it should not be too short. Note that it's more
likely the origination or destination mail servers will timeout first,
which is fine. This is just a "sane" failsafe. Default is 360
seconds (6 minutes).
- This is the number of seconds to allow for processing a
message with SpamAssassin (including feeding it the message, analyzing it,
and adding the headers/report if necessary). This should be less than your
origination and destination servers' timeout settings for the DATA
command. For Postfix the default is 300 seconds in both cases
(smtp_data_done_timeout and smtpd_timeout). In the event of timeout while
processing the message, the problem is logged and the message is passed on
anyway (w/out spam tagging, obviously). To fail the message with a temp
450 error, see the --dose (die-on-sa-errors) option, below. Default is 285
- --pid=filename or --p=filename
- Specifies a filename where spampd will write its
process ID so that it is easy to kill it later. The directory that will
contain this file must be writable by the spampd user. The default
- --logsock=unix or inet "(new in
- Syslog socket to use. May be either "unix" of
"inet". Default is "unix" except on HP-UX and SunOS
(Solaris) systems which seem to prefer "inet".
- --nodetach "(new in v2.20)"
- If this option is given spampd won't detach from the
console and fork into the background. This can be useful for running under
control of some daemon management tools or when configured as a win32
service under cygrunsrv's control.
- The maximum message size to send to SpamAssassin, in
KBytes. By default messages over 64KB are not scanned at all, and an
appropriate message is logged indicating this. The size includes headers
and attachments (if any).
- Acronym for (d)ie (o)n (s)pamAssassin (e)rrors. By default
if spampd encounters a problem with processing the message through
Spam Assassin (timeout or other error), it will still pass the mail on to
the destination server. If you specify this option however, the mail is
instead rejected with a temporary error (code 450, which means the
origination server should keep retrying to send it). See the related
--satimeout option, above.
- --tagall or --a
- Tells spampd to have SpamAssassin add headers to all
scanned mail, not just spam. By default spampd will only rewrite
messages which exceed the spam threshold score (as defined in the SA
settings). Note that for this option to work as of SA-2.50, the
always_add_report and/or always_add_headers settings in your
SpamAssassin local.cf need to be set to 1/true.
- --log-rules-hit or --rh
- Logs the names of each SpamAssassin rule which matched the
message being processed. This list is returned by SA.
- --set-envelope-headers or --seh "(new in
- Turns on addition of X-Envelope-To and X-Envelope-From
headers to the mail being scanned before it is passed to SpamAssassin. The
idea is to help SA process any blacklist/whitelist to/from directives on
the actual sender/recipients instead of the possibly bogus envelope
headers. This potentially exposes the list of all recipients of that mail
(even BCC'ed ones). Therefore usage of this option is discouraged.
NOTE: Even though spampd tries to prevent this leakage by removing
the X-Envelope-To header after scanning, SpamAssassin itself might add
headers itself which report one or more of the recipients which had been
listed in this header.
- --set-envelope-from or --sef "(new in
- Same as above option but only enables the addition of
X-Envelope-From header. For those that don't feel comfortable with the
possible information exposure of X-Envelope-To. The above option overrides
- --auto-whitelist or --aw
- This option is no longer relevant with SA version 3.0 and
above, which controls auto whitelist use via local.cf settings.
For SA version < 3.0, turns on the SpamAssassin global whitelist feature.
See the SA docs. Note that per-user whitelists are not available.
- --local-only or --L
- Turn off all SA network-based tests (DNS, Razor, etc).
- --config=filename or --C filename
- Use the specified filename as the config read by spampd in
addition to SpamAssassin's normal configuration files, overriding the
latter. Defaults to not using a spampd specific configuration file.
- Use the specified directory as home directory for the
spamassassin process. Defaults to /var/cache/spampd.
- --debug or --d
- Turns on SpamAssassin debug messages which print to the
system mail log (same log as spampd will log to). Also turns on more
verbose logging of what spampd is doing (new in v2). Also increases log
level of Net::Server to 4 (debug), adding yet more info (but not too much)
(new in v2.2).
- --help or --h
- Prints usage information.
The following options are no longer used but still accepted for backwards
compatibility with prevoius spampd
- Running between firewall/gateway and internal mail
- spampd listens on port 10025 on the same host as the
internal mail server.
Same as above but spampd runs on port 10025 of the same host as the
firewall/gateway and passes messages on to the internal mail server on
- Using Postfix advanced content filtering example and the SA
spampd --port=10025 --relayhost=127.0.0.1:10026 --auto-whitelist
is written and maintained by Maxim Paperno
http://www.WorldDesign.com/index.cfm/rd/mta/spampd.htm for latest info.
v2 uses two Perl modules by Bennett Todd and Copyright (C) 2001
Morgan Stanley Dean Witter. These are distributed under the GNU GPL (see
module code for more details). Both modules have been slightly modified from
the originals and are included in this file under new names.
Also thanks to Bennett Todd for the example smtpproxy script which helped create
this version of spampd
. See http://bent.latency.net/smtpprox/ .
v1 was based on code by Dave Carrigan named assassind
Trace amounts of his code or documentation may still remain. Thanks to him for
the original inspiration and code. See http://www.rudedog.org/assassind/ .
Also thanks to spamd
(included with SpamAssassin) and amavisd-new
(http://www.ijs.si/software/amavisd/) for some tricks.
Various people have contributed patches, bug reports, and ideas, all of whom I
would like to thank. I have tried to include credits in code comments and in
the change log, as appropriate.
is Copyright (c) 2002 by World Design Group, Inc. and Maxim
Portions are Copyright (C) 2001 Morgan Stanley Dean Witter as mentioned above in
the Credits section.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU GPL can be found at http://www.fsf.org/copyleft/gpl.html
None known. Please report any to MPaperno@WorldDesign.com.
Figure out how to use Net::Server::PreFork because it has cool potential for
load management. I tried but either I'm missing something or PreFork is
somewhat broken in how it works. If anyone has experience here, please let me
Add configurable option for rejecting mail outright based on spam score. It
would be nice to make this program safe enough to sit in front of a mail
server such as Postfix and be able to reject mail before it enters our
systems. The only real problem is that Postfix will see localhost as the
connecting client, so that disables any client-based checks Postfix can do and
creates a possible relay hole if localhost is trusted.