| SPAMPD(8) | Spam Proxy Daemon | SPAMPD(8) |
SpamPD - Spam Proxy Daemon
Documentation for SpamPD version 2.62.
spampd 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 (or SpamAssassin) 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.
spampd uses SpamAssassin to modify (tag) relayed messages based on their spam score, so all SA settings apply. This is described in the SA documentation. spampd 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).
spampd logs all aspects of its operation to syslog(8), using the mail syslog facility.
The latest version can be found at <https://github.com/mpaperno/spampd>.
spampd [ options ]
Options:
--config <filename> Load options from file(s).
--host <host>[:<port>] Hostname/IP and optional port to listen on.
--port <n> Port to listen on (alternate syntax to above).
--socket <socketpath> UNIX socket to listen on.
--socket-perms <mode> The octal mode to set on the UNIX socket.
--relayhost <hst>[:<prt>] Host and optional port to relay mail to.
--relayport <n> Port to relay to (alternate syntax to above).
--relaysocket <sockpath> UNIX socket to relay to.
--min-servers | -mns <n> The minimum number of servers to keep running.
--min-spare | -mnsp <n> The minimum number of servers to have waiting.
--max-spare | -mxsp <n> The maximum number of servers to have waiting.
--max-servers | -mxs <n> The maximum number of child servers to start.
--maxrequests or -r <n> Maximum requests that each child can process.
--childtimeout <n> Time out children after this many seconds.
--satimeout <n> Time out SpamAssassin after this many seconds.
--child-name-template [s] Template for formatting child process name.
--pid or -p <filename> Store the daemon's process ID in this file.
--user or -u <user> Specifies the user that the daemon runs as.
--group or -g <group> Specifies the group that the daemon runs as.
--[no]detach Detach from the console daemonize (default).
--[no]setsid Completely detach from stderr with setsid().
--maxsize n Maximum size of mail to scan (in KB).
--dose (D)ie (o)n (s)pamAssassin (e)rrors.
--tagall Tag all messages with SA headers, not just spam.
--set-envelope-headers Set X-Envelope-From and X-Envelope-To headers.
--set-envelope-from Set X-Envelope-From header only.
--local-only or -L Turn off all SA network-based tests.
--homedir <path> Use the specified directory as SA home.
--saconfig <filename> Use the file for SA "user_prefs" configuration.
--logfile or -o <dest> Destination for logs (syslog|stderr|<filename>).
--logsock or -ls <sock> Allows specifying the syslog socket type.
--logident or -li <name> Specify syslog identity name.
--logfacility or -lf <nm> Specify syslog facility (log name).
--log-rules-hit or -rh Log the names of each matched SA test per mail.
--debug or -d [<areas>] Controls extra debug logging.
--help | -h | -? [txt] Show basic command-line usage.
-hh | -?? [txt] Show short option descriptions (this text).
-hhh | -??? [txt] Show usage summary and full option descriptions.
--man [html|txt] Show full docs a man page or HTML/plain text.
--show defaults|<thing> Print default option values or <thing> and exit.
--version Print version information and exit.
Compatibility with previous SpamPD versions:
--children or -c <n> Same as --max-servers | -mxs (since v2.60).
Deprecated since SpamAssassin v3:
--auto-whitelist or -aw Use the SA global auto-whitelist feature.
Perl modules:
spampd 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 spampd 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 spampd 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):
Internet ->
[ MX gateway (@inter.net.host:25) -> spampd (@localhost:2025) ] ->
[ Internal mail (@private.host.ip:25) ]
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 often unnecessary to scan mail coming from your network, it may be desirable to set up a separate outbound route which bypasses spampd.
Since v2.60 spampd can optionally run in "scalable mode" which dynamically adjusts the number of child servers which can process requests simultaneously. This is activated automatically if the "--min-servers" option is specifically set to be lower than "--max-servers".
Historically SpamPD inherited from the module Net::Server::PreForkSimple which only allows for a static number of child servers to be running at once. This new option essentially allows for inheriting from Net::Server::PreFork which features dynamic allocation of child servers, with some tunable parameters. (The reason PreFork wasn't used to begin with is because older versions of it didn't seem to work... it was an old TODO to try again later.)
Here is what the Net::Server::PreFork documentation has to say (option names changed to match spampd):
"This personality binds to one or more ports and then forks "--min-servers" child process. The server will make sure that at any given time there are "--min-spare" servers available to receive a client request, up to "--max-servers". Each of these children will process up to "--maxrequests" client connections. This type is good for a heavily hit site, and should scale well for most applications."
Some experimentation and tuning will likely be needed to get the best performance vs. efficiency. Keep in mind that a SIGHUP sent to the parent process will reload configuration files and restart child servers gracefully (handy for tuning a busy site).
See the documentation for "--min-servers", "--max-servers", "--min-spare", and "--max-spare" options, and also the section about "Other Net::Server Options" for tuning parameters and links to further documentation.
spampd 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 <https://github.com/mpaperno/spampd/tree/master/misc> is available in the spampd code repository).
spampd is available as a package for a significant number of Linux distributions, including Debian and derivatives (Ubuntu, etc). This is typically the easiest/best way to install and configure spampd since it should already take into account any system specifics for setting up and running as a daemon, etc. Note however that packages might not offer the latest version of spampd. A good reference for available packages and their versions can be found at <https://repology.org/project/spampd/versions>.
spampd is also used in the turnkey Mail-in-a-Box <https://mailinabox.email/> project, which includes Postfix as the main MTA and Dovecot as the local delivery agent with LMTP protocol. Even if you don't need the turnkey solution, it may be informative to peruse the MIAB setup <https://github.com/mail-in-a-box/mailinabox/tree/master/setup> / configuration <https://github.com/mail-in-a-box/mailinabox/tree/master/conf> files for reference.
All spampd options have reasonable defaults, especially for a Postfix-centric installation. You may want to specify the "--max-servers" 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 parameters.
To show default values for all options, run "spampd --show defaults".
Since v2.61 spampd injects a "_SPAMPDVERSION_" "template tag" <https://spamassassin.apache.org/doc/Mail_SpamAssassin_Conf.html#TEMPLATE-TAGS> macro at message processing time. This can be used in an "add_header" SA config file directive, for example.
add_header all Filter-Version SpamAssassin _VERSION_ (_SUBVERSION_, Rules: _RULESVERSION_) / SpamPD _SPAMPDVERSION_
Note that spampd replaces spamd from the SpamAssassin distribution in function. You do not need to run spamd 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):
/etc/postfix/master.cf:
smtp inet n - y - - smtpd
-o content_filter=smtp:localhost:10025
-o myhostname=mx.example.com
localhost:10026 inet n - n - 10 smtpd
-o content_filter=
-o myhostname=mx-int.example.com
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 main.cf file. spampd 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 sending.
For the above example you can simply start spampd like this:
spampd --host=localhost:10025 --relayhost=localhost:10026
FILTER_README 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 default spampd is set up for the default Postfix timeout values.
The following guide has some more specific setup instructions: Integrating SpamAssassin into Postfix using spampd <https://wiki.apache.org/spamassassin/IntegratePostfixViaSpampd>
Always consult the changelog.txt file which should be included in the spampd repository/distribution.
If upgrading from a version prior to 2.2, please note that the --add-sc-header option is no longer supported. Use SA's built-in header manipulation features instead (as of SA v2.6).
Upgrading from version 1 simply involves replacing the spampd program 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 change log.
Since v2.60 spampd has a new "Scalable Mode" feature which varies the number of running child servers based on demand. This is disabled by default. The option previosly known as "--children" (or "-c") is now called "--max-servers" (or "-mxs"), but the old style is still accepted. See descriptions of the "max-servers" and "min-servers" options for details.
Also note that v2.60 added the ability to use a "CONFIGURATION FILE" for specifying all options.
spampd [
[ --config | --cfg | --config-file | --cfg-file [<filename>] ][...]
[ --host <host>[:<port>] | --socket <path> --socket-perms <mode> ]
[ --relayhost <host>[:<port>] | --relaysocket <path> ]
[--min-servers | -mns <n>] [--saconfig <file>] [--user | -u <user> ]
[--min-spare | -mnsp <n>] [--satimeout <n> ] [--group | -g <group> ]
[--max-spare | -mxsp <n>] [--dose ] [--pid | -p <file> ]
[--max-servers | -mxs <n>] [--maxsize <n> ] [--[no]detach ]
[--maxrequests | -r <n>] [--local-only | -L ] [--[no]setsid ]
[--childtimeout <n>] [--tagall | -a ] [--log-rules-hit | -rh]
[ --child-name-template | -cnt [<template>] ] [--homedir <path> ]
[ [--set-envelope-headers | -seh] | [--set-envelope-from | -sef] ]
[ --logfile | -o (syslog|stderr|<filename>) ][...]
[ --logsock | -ls <socketpath> ] [ --logident | -li <name> ]
[ --debug | -d [<area,...>|1|0] ] [ --logfacility | -lf <name> ]
[ --show ( all | (defaults, config, version, argv, start, self) ) ][...]
]
spampd --version
spampd [--help | -?] | -?? [txt] | -??? [txt] | [-???? | --man [html|txt]]
Options are case-insensitive. "=" can be used as name/value separator instead of space (--name=value). "-" or "--" prefix can be used for all options. Shortest unique option name can be used. All options must be listed individually (no "bundling"). All boolean options can take an optional argument of 1 or 0, or can be negated by adding a "no-" prefix in front of the name. An option specified on the command line overrides the same option loaded from config file(s).
Please be sure to also read the general information about specifying option arguments in the above "USAGE" section.
To view default values for all options, run "spampd --show defaults".
See "CONFIGURATION FILE" section for more details.
As of v2.60 this option can also handle IPv6 addresses in the form of "--host n:n:n" or, with port, "--host [n:n:n]:port" (the square brackets are optional in both forms but recommended in the latter case).
Note that the port specified this way implicitly overrides the "--port" option.
Important! You should NOT enable spampd to listen on a public interface (IP address) unless you know exactly what you're doing!
As of v2.60 this option can also handle IPv6 addresses in the form of "--relayhost n:n:n" or, with port, "--relayhost [n:n:n]:port" (the square brackets are optional in both forms but recommended in the latter case).
Note that the port specified this way implicitly overrides the "--relayport" option.
Note: If "--min-servers" option is also set, and is less than "--max-servers", then the server runs in "Scalable Mode" and the meaning of this option changes. In scalable mode, the number of actual running servers will fluctuate between "--min-servers" and "--max-servers", based on demand.
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' or 'lmtp').
See also "--min-servers", "--min-spare", and "--max-spare" options.
Note: If this option is set, and it is less than "--max-servers" option, then the server runs in "Scalable Mode". By default this option is undefined, meaning spampd runs only a set number of servers specified in "--max-servers". In scalable mode, the number of actual running servers will fluctuate between "--min-servers" and "--max-servers", based on demand.
See also "--max-servers", "--min-spare", and "--max-spare" options.
Note: This option is only used when running in "Scalable Mode". See "--min-servers" and "--max-servers" options.
Note: This option is only used when running in "Scalable Mode". See "--min-servers" and "--max-servers" options.
This should be less than your origination and destination servers' timeout settings for the DATA command. (For Postfix this is set in "(smtp|lmtp)_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.
The template uses printf() style formatting, but with named parameter placeholders. For example (wrapped for clarity):
%base_name: child #%child_count(%child_status)
[req %req_count/%req_max, time lst/avg/ttl %(req_time_last).4f/%(req_time_avg).4f/%(req_time_ttl).4f,
ham/spm %req_ham/%req_spam, rules v%sa_rls_ver)]'
Would produce something like:
spampd: child #4(D) [req 8/30, time lst/avg/ttl 0.0222/0.0256/0.2045, ham/spm 3/5, rules v1891891]
Parameters are specified like: "Value of %(my_name)s is %(my_float_value).4f", with names in parenthesis followed by a standard printf() style formatting specifier ("s" is default), or simply as "Value of %my_name is %my_value" with the default format being a string (works for numerics also). Keep in mind that any actual "%" characters need to be escaped as "%%". Formatting warnings will be logged as "sprintf" errors (most likely a parameter was misspelled).
The following variables are available:
base_name # Base script name, eg. "spampd"
spampd_ver # SpamPD version, eg. "2.61"
perl_ver # Perl version, eg. "5.28.1"
ns_ver # Net::Server version, eg. "2.009"
ns_typ # Net::Server type, "PreFork" or "PreForkSimple"
ns_typ_acr # Net::Server type acronym, "PF" or "PFS"
sa_ver # SpamAassassin version, eg. "3.4.2"
sa_rls_ver # SpamAassassin rules update version, eg. "1891891" or "(unknown)"
child_count # total number of children launched so far (current child number)
child_status # child status, "C" for connected, or "D" for disconnected
req_count # number of requests child has processed so far
req_max # maximum child requests before exit
req_time_last # [s] time to process the last message
req_time_ttl # [s] total processing time for this child
req_time_avg # [s] average processing time for this child (req_time_ttl / req_count)
req_ham # count of ham messages scored by child
req_spam # count of spam messages scored by child
This option may be specified multiple times. You may also specify multiple destination by separating them with a ":" (colon): "--logfile stderr:/var/log/spampd.log"
Simultaneous logging to "syslog", "stderr", and one "filename" is possible. At this time only one log file can be used at a time (if several are specified then the last one takes precedence).
"Since v2.60:"
The type can be any of the socket types or logging mechanisms as accepted by the subroutine Sys::Syslog::setlogsock(). Depending on the version of Sys::Syslog and the underlying operating system, one of the following values (or their subset) can be used:
native, tcp, udp, inet, unix, stream, pipe, console, eventlog (Win32 only)
The default behavior since spampd v2.60 is to let Sys::Syslog pick the default syslog socket. This is the recommended usage for Sys::Syslog (since v0.15), which chooses thusly:
The default is to try native, tcp, udp, unix, pipe, stream, console. Under systems with the
Win32 API, eventlog will be added as the first mechanism to try if Win32::EventLog is available.
For more information please consult the Sys::Syslog <https://metacpan.org/pod/Sys::Syslog> documentation.
To preserve backwards-compatibility, the default on HP-UX and SunOS (Solaris) systems is "inet".
"Prior to v2.60:"
The default was "unix" except on HP-UX and SunOS (Solaris) systems it is "inet".
NOTE: Even though spampd tries to prevent this leakage by removing the X-Envelope-To header after scanning, SpamAssassin itself might add headers that report recipient(s) listed in X-Envelope-To.
Thanks to Alexander Wirt for this fix.
"New in v2.60:"
Setting the value to 1 (one) is the same as using no parameter (eg. simply -d). The value of 0 (zero) disables debug logging.
The area list is passed on directly to SpamAssassin and controls logging facilities. If no areas are listed (and debug logging is enabled), all debugging information is printed (this equivalent to passing "all" as the area). Diagnostic output can also be enabled for each area individually; area is the area of the code to instrument. For example, to produce diagnostic output on bayes, learn, and dns, use:
-d bayes,learn,dns
You can also disable specific areas with the "no" prefix:
-d all,norules,nobayes
To show only spampd debug messages (none from SpamAssassin), use:
-d spampd
For more information about which areas (aka channels or facilities) are available, please see the documentation at:
SpamAssassin Wiki::DebugChannels <http://wiki.apache.org/spamassassin/DebugChannels>
Mail::SpamAssassin::Logger::add_facilities() <https://spamassassin.apache.org/doc/Mail_SpamAssassin_Logger.html#METHODS>
<thing> may be one or more of:
Multiple "thing"s may be specified by using the --show option multiple times, or separating the items with a comma: "--show config,start,argv".
Note that all thing options besides "defaults" and "config" require the Perl module Data::Dumper installed.
spampd --??? | less -R
Alternatively you can request plain-text format with the optional "txt" value.
"--man" displays the full documentation, optionally in "html" or plain text "txt" formats (default is to use actual "man" format/display). HTML version is saved to a temp file and an attempt is made to open it in the default system browser (it is better if the browser is already opened). If available, the optional Perl module HTML::Display is used to (try to) open a browser.
Net::Server supports some other options which spampd doesn't accept directly. For example there are access control options, child process tuning, and a few more (see below). Such options can be passed through to Net::Server (and subtypes) by specifying them at the end of the spampd command line (or in a configuration file) following two dashes " -- " by themselves (this is a failry typicaly convention for passing options onto another program). As an example, it may look something like this:
spampd --host 10.0.0.1 -port 10025 -- --cidr_allow 10.0.0.0/24
The "--cidr_allow" after the " -- " is passed onto Net::Server. If the " -- " were not there, you would get an error from spampd about an unknown option.
To specify Net::Server options in a configuration file, place them after two dashes ("--") on a line by themselves. See "CONFIGURATION FILE" for an example.
This only makes sense with the few options not directly controlled by/through spampd. As of Net::Server v2.009 the list is:
reverse_lookups, allow, deny, cidr_allow, cidr_deny, chroot, ipv, conf_file, serialize, lock_file, check_for_dead, max_dequeue, check_for_dequeue
If running in "Scalable Mode" then these settings from Net::Server::PreFork can also be very relevant to performance tuning:
check_for_waiting, check_for_spawn, min_child_ttl
Keep in mind that the Net::Server types inherit from each other: "PreFork" inherits from "PreForkSimple" which inherits from "Net::Server" itself. Which means all the options are also inherited.
See the Net::Server(3) <https://https://metacpan.org/pod/Net::Server#DEFAULT-ARGUMENTS-FOR-Net::Server>, Net::Server::PreForkSimple(3) <https://metacpan.org/pod/Net::Server::PreForkSimple#COMMAND-LINE-ARGUMENTS>, and Net::Server::PreFork(3) <https://metacpan.org/pod/Net::Server::PreFork#COMMAND-LINE-ARGUMENTS> documentation for details.
The following options are no longer used but still accepted for backwards compatibility with prevoius spampd versions:
For SA version < 3.0, turns on the SpamAssassin global whitelist feature. See the SA docs. Note that per-user whitelists are not available.
NOTE: DBBasedAddrList is used as the storage mechanism. If you wish to use a different mechanism (such as SQLBasedAddrList), the spampd code will need to be modified in 2 instances (search the source for DBBasedAddrList).
Since v2.60 spampd allows for the use of a configuration file to load server parameters. One or more files can be specified on the command line (see "--config" option for more details on syntax). The format of a configuration file is simple key/value pairs. Comments (starting with # or ;) and blank lines are ignored. The option names are exactly as they appear above in the "OPTIONS" section. They can be listed with or w/out the "-"/"--" prefixes. Key/value separator can be one or more of space, tab, or "=" (equal) sign.
Multiple configuration files can be loaded, with the latter ones being able to override options loaded earlier. Any options specified on the command line will take precedence over options from file(s). Configuration file(s) are reloaded during a HUP-induced restart (see "SIGNALS"), making it possible to adjust settings dynamically on a running server.
You may also provide "passthrough" options directly to Net::Server by putting them after a "--" on a line by itself (this is just like using the lonesome "--" on a command line; see "Other Net::Server Options").
Note that one cannot use the "--config" option to load a file from within another file. A config file can only be specified on the command line.
Use the "spampd --show defaults > spampd.config" command to generate a sample configuration file showing all default values. The example below demonstrates various valid syntax for the file.
# Sample configuration file for SpamPD. # Double dashes --user spampd # Single dash and = separator with spaces -pid = /var/run/spampd/spampd.pid # No dashes required, equals separator no spaces homedir=/var/cache/spampd # No dashes, space separator host 127.0.0.1 # Disabled option (after comment character) #port 10025 # Boolean values can be set/unset a number of ways: tagall 1 local-only 0 set-envelope-from no-log-rules-hit # Passthrough arguments for Net::Server[::PreFork[Simple]] could go here. # Be sure to also uncomment the "--" if using any. # -- # cidr_allow 127.0.0.1/32
"Since v2.60":
SpamAssassin configuration IS reloaded on HUP. Any children currently in the middle of a transaction will finish with the previous SA config and then exit. A new set of children, using the new config, is spawned immediately upon HUP and will serve any new requests.
In a similar manner, spampd will also reload its own settings from any configuration file(s) specified on the original command line with "--config" option (see "OPTIONS" and "CONFIGURATION FILE").
"Since v2.52": Children were restarted but SpamAssassin configuration was not reloaded.
"Prior to v2.52": HUP would try to restart the server with all default settings (usually failing).
spampd --host=192.168.1.10
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 another host.
spampd --relayhost=192.168.1.10
spampd --port=10025 --relayhost=127.0.0.1:10026 --local-only
spampd --socket /var/run/spampd.socket --socket-perms 700
spampd will relay mail to "/var/run/dovecot/lmtp" instead of a TCP port:
spampd --relaysocket /var/run/dovecot/lmtp
Remember that the user spampd runs as needs to have read AND write permissions on the relaysocket!
spampd is written and maintained by Maxim Paperno <MPaperno@WorldDesign.com>. The open source code repository is located at <https://github.com/mpaperno/spampd/>. See <http://www.WorldDesign.com/index.cfm/rd/mta/spampd.htm> for historical info.
spampd v2 uses two Perl modules (MSDW::SMTP::Client and MSDW::SMTP::Server) 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 (SpamPD::Client and SpamPD::Server, respectively).
Also thanks to Bennett Todd for the example smtpproxy script which helped create this version of spampd. See <http://bent.latency.net/smtpprox/> (seems to be down) or <https://github.com/jnorell/smtpprox>.
spampd 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. <https://openshut.net/>.
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.
Kurt Andersen Roland Koeckel Urban Petry Sven Mueller
See also: <https://github.com/mpaperno/spampd/graphs/contributors/>
spampd is Copyright (c) Maxim Paperno; All Rights Reserved.
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.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Use GitHub issue tracking: <https://github.com/mpaperno/spampd/issues>
Mail::SpamAssassin(3) <https://spamassassin.apache.org/doc/Mail_SpamAssassin.html>
Net::Server(3) <https://metacpan.org/pod/Net::Server>
SpamAssassin Site <http://www.spamassassin.org/>
SpamPD Code Repository <https://github.com/mpaperno/spampd>
SpamPD product page <http://www.WorldDesign.com/index.cfm/rd/mta/spampd.htm>
Integrating SpamAssassin into Postfix using spampd <https://wiki.apache.org/spamassassin/IntegratePostfixViaSpampd>
| 2025-02-27 | perl v5.40.1 |