SPAMD(8p)
πΈ SPAMD(8p) πΈ
okay bestie, buckle up, because this is spamd(8p) straight outta the User Contributed Perl Documentation section and it is iconic. it's the daemon-ified glow-up of spamassassin, and we're gonna go through the whole thing together, no skips, no skimming, fr fr. π
β¨ NAME β¨
spamd β daemonized version of spamassassin
π SYNOPSIS π
spamd [options]
Options:
-l, --allow-tell Allow learning/reporting
-c, --create-prefs Create user preferences files
-C path, --configpath=path Path for default config files
--siteconfigpath=path Path for site configs
--cf='config line' Additional line of configuration
--pre='config line' Additional line of ".pre" (prepended to configuration)
-d, --daemonize Daemonize
-h, --help Print usage message
-i [ip_or_name[:port]], --listen=[ip_or_name[:port]] Listen on IP addr and port
-p port, --port=port Listen on specified port, may be overridden by -i
-4, --ipv4-only, --ipv4 Use IPv4 where applicable, disables IPv6
-6 Use IPv6 where applicable, disables IPv4
-A host,..., --allowed-ips=..,.. Restrict to IP addresses which can connect
-m num, --max-children=num Allow maximum num children
--min-children=num Allow minimum num children
--min-spare=num Lower limit for number of spare children
--max-spare=num Upper limit for number of spare children
--max-conn-per-child=num Maximum connections accepted by child
before it is respawned
--round-robin Use traditional prefork algorithm
--timeout-tcp=secs Connection timeout for client headers
--timeout-child=secs Connection timeout for message checks
-q, --sql-config Enable SQL config (needs -x)
-Q, --setuid-with-sql Enable SQL config (needs -x,
enables use of -H)
--ldap-config Enable LDAP config (needs -x)
--setuid-with-ldap Enable LDAP config (needs -x,
enables use of -H)
--virtual-config-dir=dir Enable pattern based Virtual configs
(needs -x)
-r pidfile, --pidfile Write the process id to pidfile
-s facility, --syslog=facility Specify the syslog facility
--syslog-socket=type How to connect to syslogd
--log-timestamp-fmt=fmt strftime(3) format for timestamps, may be
empty to disable timestamps, or 'default'
-u username, --username=username Run as username
-g groupname, --groupname=groupname Run as groupname
-v, --vpopmail Enable vpopmail config
-x, --nouser-config Disable user config files
-U username, --default-user=username Fall back to this username if spamc user
is not found (default: nobody)
-D, --debug[=areas] Print debugging messages (for areas)
-L, --local Use local tests only (no DNS)
-P, --paranoid Die upon user errors
-H [dir], --helper-home-dir[=dir] Specify a different HOME directory
--ssl Enable SSL on TCP connections
--ssl-verify Request a client certificate and verify it
--ssl-ca-file cafile Certificate Authority certificate file
--ssl-ca-path capath Certificate Authority directory
--ssl-port port Override --port setting for SSL connections
--server-key keyfile Specify an SSL keyfile
--server-cert certfile Specify an SSL certificate
--socketpath=path Listen on a given UNIX domain socket
--socketowner=name Set UNIX domain socket file's owner
--socketgroup=name Set UNIX domain socket file's group
--socketmode=mode Set UNIX domain socket file's mode
--timing Enable timing and logging
-V, --version Print version and exit
now, the tea on --listen (aka -i): you can drop this flag more than once, and the syntax goes like this: [ ssl: ] [ host-name-or-IP-address ] [ : port ], OR you can hand it an absolute path (filename) of a Unix socket instead. if the port isn't there, it defaults to --port, or to 783. and --ssl? yeah that just implies a prefix of 'ssl:', slay. π¦
an IPv6 address should be wrapped in square brackets, like [::1]:783. an IPv4 address may be wrapped in square brackets but literally doesn't have to be, no pressure bestie. an asterisk '*' where a hostname would go means an unspecified address β '0.0.0.0' or '::' β so it binds to all interfaces. an empty option value also implies '*'. and the default? that's '--listen localhost', which only binds to a loopback interface. cozy. π
π DESCRIPTION π
so the whole point of this program, bestie, is to give you a daemonized version of the spamassassin executable. the goal is improving throughput performance for automated mail checking. it's giving main character energy for your mail pipeline. β¨
this is meant to be used alongside "spamc", which is a fast, low-overhead C client program. they're a duo, iykyk. π
if you want more deets, go read the README file in the "spamd" directory of the SpamAssassin distribution. it's all there.
note, and this one matters: even though "spamd" will check per-user config files for every single message, any changes to the system-wide config files require either restarting spamd or forcing it to reload itself via SIGHUP for the changes to actually take effect. no cap.
and another one, listen up: if"spamd"receives a SIGHUP, it internally reloads itself, which means it will change its pid and might not restart at all if its environment changed (ie. if it can't change back into its own directory). so if you plan to use SIGHUP, you should always start"spamd"with the-rswitch to know its current pid. π don't say i didn't warn you.
π OPTIONS π
okay so before we get into the individual flags: long-form options can be shortened as long as they stay unambiguous. (i.e. --dae can be used instead of --daemonize.) also, boolean options (like --user-config) can be negated by adding no (--nouser-config), however, this is usually unnecessary. cute, right?
-l,--allow-tellβ allow learning and forgetting (to a local Bayes database), plus reporting and revoking (to a remote database), by spamd. the client issues aTELLcommand to say what type of message is being processed and whether local (learn/forget) or remote (report/revoke) databases should be updated. π
heads up though: spamd always trusts the username passed in, so clients could maliciously learn messages for other users. (this is not usually a concern with an SQL Bayes store, because users will typically have read-write access directly to the database, and can also use"sa-learn"with the-uoption to achieve the same result.) π
-c,--create-prefsβ create user preferences files if they don't exist (default: don't). simple as.-C path,--configpath=pathβ use the specified path for locating the distributed configuration files. ignore the default directories (usually"/usr/share/spamassassin"or similar). your path, your rules. π--siteconfigpath=pathβ use the specified path for locating site-specific configuration files. ignore the default directories (usually"/etc/spamassassin"or similar). β¨--cf='config line'β add additional lines of configuration directly from the command-line, parsed after the configuration files are read. multiple--cfarguments can be used, and each one will be considered a separate line of configuration. stack 'em. π«Ά--pre='config line'β add additional lines of.preconfiguration directly from the command-line, parsed before the configuration files are read. multiple--prearguments can be used, and each will be considered a separate line of configuration. yes it's the same vibe as--cfbut it goes in early. π-d,--daemonizeβ detach from the starting process and run in the background (daemonize). go be free, bestie. π¦-h,--helpβ print a brief help message, then exit without further action. short and sweet.-V,--versionβ print version information, then exit without further action. π-i [ipaddress[:<port>]],--listen[=ipaddress[:<port>]]β additional alias names for this option are--listen-ipand--ip-address. tells spamd to listen on the specified IP address, defaults to a loopback interface, i.e."--listen localhost". if no value is specified after the switch, or if an asterisk'*'stands in place of an <ipaddress>, spamd will listen on all interfaces β equivalent to address'0.0.0.0'for IPv4 and'::'for IPv6. you can also use a valid hostname, which will make spamd listen on all addresses that the name resolves to. this option may be specified multiple times. see also-4and-6for restricting address family to IPv4 or IPv6. if a port is specified, it overrides for this socket the global--port(and--ssl-port) setting. an IPv6 address should be enclosed in square brackets, e.g.[::1]:783. for compatibility, square brackets on an IPv6 address may be omitted if a port number specification is also omitted. π
important vibe check: listening on non-loopback addresses does not automatically permit connections from those addresses. the-A/--allowed-ipsoption controls which source addresses may connect, and defaults to localhost only (127.0.0.1and::1). π₯
-p port,--port=portβ optionally specifies the port number for the server to listen on (default:783). if the--sslswitch is used without--ssl-port, this port accepts SSL connections instead of unencrypted connections. if--ssl-portis also set (which itself implies--ssl), then unencrypted connections are accepted on--portand encrypted connections are accepted on--ssl-portsimultaneously. use-i/--listenwith an"ssl:"prefix for finer control over which addresses and ports carry SSL vs plain-TCP traffic. π-q,--sql-configβ turn on SQL lookups even when per-user config files have been disabled with-x. this is useful for spamd hosts which don't have user's home directories but do want to load user preferences from an SQL database. if yourspamcclient does not support sending the"User:"header, like"exiscan", then the SQL username used will always be nobody. this inhibits thesetuid()behavior, so the"-u"option is required. if you want thesetuid()behaviour, use"-Q"or"--setuid-with-sql"instead. πΈ--ldap-configβ turn on LDAP lookups. this is completely analog to"--sql-config", only it's using an LDAP server. like"--sql-config", this disables the setuid behavior, and requires"-u". if you want it, use"--setuid-with-ldap"instead. π§-Q,--setuid-with-sqlβ turn on SQL lookups even when per-user config files have been disabled with-x, and also setuid to the user. this is useful for spamd hosts which want to load user preferences from an SQL database but also wish to support the use of-H(Helper home directories.) π--setuid-with-ldapβ okay so this one turns LDAP lookups ON even when you've killed per-user config files with-x, and it also setuids to the user. It's literally the exact same energy as--setuid-with-sql, justβ¦ LDAP flavored instead of SQL flavored π--virtual-config-dir=patternβ this is where you tell spamd to look for per-user preferences for virtual users, the ones the-xswitch is about. The pattern is a base pattern for the directory name. And bestie, you get escapes β¨:%uβ swapped out for the full name of the current user, exactly asspamcsent it.%lβ swapped out for the local part of the current username. Like, if the username is an email address, this is everything before the@.%dβ swapped out for the domain of the current username. So if the username is an email address, this is everything after the@.%xβ swapped out for the full name of the current user asspamcsent it, BUT if that resulting config directory doesn't exist, it gets replaced with the domain part instead, so you get a domain-wide default π«Ά%%β swapped out for one single percent sign (%).
So like, for example, if "/vhome/users/%u/spamassassin" is what you specified, and spamc sends a virtual username of "jm@example.com", the directory used will be "/vhome/users/jm@example.com/spamassassin". Slay.
The characters allowed in the virtual username for this path are restricted to:
A-Z a-z 0-9 - + _ . , @ =
Anything else gets replaced with underscores ("_"). Rude but fair.
This path has to be a writable directory. It will be created if it doesn't already exist. If a file called user_prefs lives in this directory (note: NOT in a ".spamassassin" subdirectory!!), it gets loaded as the user's preferences. And the Bayes databases for that user get stored in this directory too.
Heads up: this requires -x to be used, and it cannot be combined with SQL- or LDAP-based configuration.
The pattern must expand to an absolute directory when spamd is running daemonized (-d).
Currently, using this without -u is not supported. And that inhibits setuid. π
-r pidfile,--pidfile=pidfileβ writes the process ID of the spamd parent into the file you name with pidfile. The file gets unlinked when the parent exits. Note that when you're running with the-uoption, that file has to be writable by that user.-v,--vpopmailβ turns on vpopmail config. If you specify this with-uset to the vpopmail user, spamd can look up / createuser_prefsin the vpopmail user's own maildir. Super handy for vpopmail virtual users who don't have an entry in the system/etc/passwdfile π
Currently, using this without -u is not supported. And yeah, this inhibits setuid too.
-s facility,--syslog=facilityβ picks the syslog facility to use (default:mail). If you say"stderr", output goes to stderr instead. (Which is so useful if you're running"spamd"under the"daemontools"package btw.) With a facility of"file", all output goes tospamd.log. And facility is interpreted as a file name to log to if it contains any characters other thana-zand0-9."null"disables logging completely (it's used internally).
Examples, no cap:
spamd -s mail # use syslog, facility mail (default)
spamd -s ./mail # log to file ./mail
spamd -s stderr 2>/dev/null # log to stderr, throw messages away
spamd -s null # the same as above
spamd -s file # log to file ./spamd.log
spamd -s /var/log/spamd.log # log to file /var/log/spamd.log
If logging to a file is enabled and that log file gets rotated, the spamd server must be restarted with a SIGHUP. (If the log file is just truncated, you don't need to, but it's still recommended.)
Note that logging to a file does not use locking, so you cannot intermix logging from spamd and other processes into the same file. If you want to mix logging like this, use syslog instead. π
And if you use syslog logging, it is essential to send a SIGHUP to the spamd daemon when you restart the syslogd daemon. (This is because of a shortcoming in Perl's syslog handling, where losing the connection to syslogd is treated as a fatal error. Not dramatic at all.)
--syslog-socket=typeβ tells spamd how it should send messages to syslogd. type can be any of the socket types or logging mechanisms that the subroutineSys::Syslog::setlogsock()accepts. Depending on your version ofSys::Syslogand on the underlying OS, one of these values (or some subset of them) can be used:"native","eventlog","tcp","udp","inet","unix","stream","pipe", or"console". The value"eventlog"is specific to the Win32 events logger and requires the perl moduleWin32::EventLogto be installed. Want more info? Go read theSys::Syslogdocumentation π
A historical setting, --syslog-socket=none, is mapped to --syslog=stderr.
The default for Windows platforms is "none"; otherwise the default is to try "unix" first, then fall back to "inet" if perl detects errors in its "unix" support.
Some platforms, or some versions of perl, ship with old or straight-up dysfunctional versions of the Sys::Syslog module that don't support some socket types, so you may need to set this option explicitly. If you're getting error messages about __PATH_LOG or similar from spamd, try changing this setting π
The socket type "file" is used internally and should not be specified. Use the -s switch instead, bestie.
--log-timestamp-fmt=formatβ this one hands you a POSIXstrftime(3)format for the timestamps included in each logged message. Each logger (stderr, file, syslog) has its own default timestamp format, and that default kicks in whenever--log-timestamp-fmtisn't given, or when it's given with--log-timestamp-fmt=default. You can turn timestamps off entirely by specifying an empty string, like--log-timestamp-fmt=''or just--log-timestamp-fmt=. Typical use cases:--log-timestamp-fmt='%a %b %e %H:%M:%S %Y'(gives you localized weekday and month names in thectime(3)style), or'%a, %e %b %Y %H:%M:%S %z (%Z)'for an RFC 2822 format, or maybe'%Y-%m-%d %H:%M:%S%z'for an ISO 8601 (EN 28601) format, or just'%Y%m%dT%H%M%S'. Pick your fighter β¨-u username,--username=usernameβ run as the named user. If this option isn't set, the default behaviour is tosetuid()to the user running"spamc", if"spamd"is running as root.
Note:"--username=root"is not a valid option. If you specify it,"spamd"will exit with a fatal error on startup. No root era for you π
-g groupname,--groupname=groupnameβ run as the named group if--usernameis being used. If you don't set this while using--username, then the primary group of the user you gave to--usernameis used.-x,--nouser-config,--user-configβ turns off (or on) reading of per-user configuration files (user_prefs) from the user's home directory. The default behaviour is to read per-user configuration from the user's home directory (--user-config).
This option does not disable or otherwise influence the SQL, LDAP or Virtual Config Dir settings. Those are their own whole thing π¦
-U username,--default-user=usernameβ fall back to this username if the username provided by spamc isn't found. Default isnobody, which might not exist or might not have a usable home directory, so use this setting to define a suitable user if you need one.-A host,...,--allowed-ips=host,...β a comma-separated list of authorized hosts or networks allowed to connect to this spamd instance. Each element of the list is either a single IP address, or a range of IP addresses in address/masklength CIDR notation, or ranges of IPv4 addresses by specifying 3 or fewer octets with a trailing dot. Hostnames are not supported, only IPv4 or IPv6 addresses. This option can be specified multiple times, or it can take a list of addresses separated by commas. IPv6 addresses may be (but need not be) enclosed in square brackets for consistency with the--listenoption. Examples:
-A 10.11.12.13 -- only allow connections from 10.11.12.13.
-A 10.11.12.13,10.11.12.14 -- only allow connections from
10.11.12.13 and 10.11.12.14.
-A 10.200.300.0/24 -- allow connections from any machine in the
range "10.200.300.*".
-A 10. -- allow connections from any machine in the range
"10.*.*.*".
-A [2001:db8::]/32,192.0.2.0/24,::1,127.0.0.0/8 -- only accept
connections from specified test networks and from localhost.
In the absence of the -A option, connections are only accepted from IP address 127.0.0.1 or ::1, i.e. from localhost on a loopback interface. And the allowed-IP list is global across all listening sockets β there is no per-socket access control. One list to rule them all π
-D [area,...],--debug [area,...]β produce debugging output. If no areas are listed, all debugging information gets printed. Diagnostic output can also be enabled for each area individually; area is the area of the code to instrument. So like, to produce diagnostic output on bayes, learn, and dns, you'd use:
spamassassin -D bayes,learn,dns
Higher priority informational messages that are suitable for logging in normal circumstances are available with an area of "info".
Wanna know more about which areas (also known as channels) are available? The documentation lives at:
https://wiki.apache.org/spamassassin/DebugChannels
-4,--ipv4only,--ipv4-only,--ipv4β use IPv4 where applicable, don't use IPv6. This option affects a set of listen sockets (see the--listenoption) and disables IPv6 for DNS tests.-6β use IPv6 where applicable, don't use IPv4. This option affects a set of listen sockets (see the--listenoption) and disables IPv4 for DNS tests. Installing a moduleIO::Socket::IPis recommended if spamd is expected to receive requests over IPv6. Foreshadowing β¨-L,--localβ perform only local tests on all mail. In other words, skip DNS and other network tests. Works the same as the-Lflag tospamassassin(1).-P,--paranoidβ die on user errors (for the user passed from spamc) instead of falling back to user--default-userand using the default configuration. Maximum drama, on purpose π-m number,--max-children=numberβ bestie, this is how many childrenspamdis allowed to spawn. It spawns that many, then vibes in the background sleeping until a child passes away, at which point it goes and spawns a brand new one. π
Incoming connections can still happen even if every single child is busy β they just get queued up waiting for a free child, like a line at the boba shop. The minimum value is 1, the default value is 5.
Heads up tho: there's an OS-specific maximum of connections that can be queued. Wanna find yours? Run perl -MSocket -e'print SOMAXCONN' and it'll spill the tea. π
Also β and this part matters β if you run too many servers for the amount of free RAM you've got, you're lowkey in danger of hurting performance by causing a high swap load, as server processes get swapped in and out continually. Not the vibe.
--min-children=numberβ the minimum number of children that will be kept running, no matter what. The minimum value is1, the default value is1. If you have lots of free RAM, you may want to increase this. β¨--min-spare=numberβ the lower limit for the number of spare children allowed to run. A spare (aka idle) child is one that is not handling a scan request, just chilling. If there are too few spare children available, a new server will be started every second or so β it's giving "hiring spree". The default value is1.--max-spare=numberβ the upper limit for the number of spare children allowed to run. If there are too many spare children, one will be killed every second or so until the number of idle children is in the desired range. The default value is2. π--max-conn-per-child=numberβ the max number of connections each child should process before dying and letting the masterspamdprocess spawn a new child. The minimum value is1, the default value is200.--round-robinβ okay so by default,spamdtries to keep a small number of "hot" child processes as busy as possible while keeping any others as idle as possible, using something similar to the Apache httpd server scaling algorithm. The master process coordinates the children's activities to pull this off. This switch disables that scaling algorithm, and instead you get the behaviour seen in the3.0.xversions, where all processes receive an equal load and no scaling takes place. β¨ throwback era β¨--timeout-tcp=numberβ how many seconds to wait for headers from a client (spamc) before closing the connection. The minimum value is1, the default value is30, and a value of0will disable socket timeouts completely.--timeout-child=numberβ how many seconds to wait for aspamdchild to process or check a message. The minimum value is1, the default value is300, and a value of0will disable child timeouts completely.-H directory,--helper-home-dir=directoryβ specify that external programs such as Razor, DCC, and Pyzor should have aHOMEenvironment variable set to a specific directory. The default is to use theHOMEenvironment variable setting from the shell runningspamd. And if you specify no argument at all?spamdwill use thespamccaller's home directory instead. π--sslβ accept only SSL connections on the associated port. TheIO::Socket::SSLperl module must be installed. π
The details, bestie, because they matter: when used without -i / --listen and without --ssl-port, the single default listener (--port) is converted to SSL. When used together with --ssl-port (which also implies --ssl), two default listeners are created: a plain-TCP listener on --port and an SSL listener on --ssl-port. When -i / --listen options are present, --ssl has no effect on individual sockets β use the ssl: prefix on -i arguments instead (e.g. -i ssl:*:784 -i *:783).
--ssl-verifyβ implies--ssl. Request a client certificate and verify the certificate. Requires--ssl-ca-fileor--ssl-ca-path.
Ngl, verification is limited to confirming the certificate is signed by the specified CA. Hostname (CN) matching and CRL checking are not performed, because spamd has no options to configure either. That's just how it is. π«Ά
--ssl-ca-file=cafileβ implies--ssl-verify. Use the specified Certificate Authority certificate to verify the client certificate. The client certificate must be signed by this certificate.--ssl-ca-path=capathβ implies--ssl-verify. Use the Certificate Authority certificate files in the specified directory to verify the client certificate. The client certificate must be signed by one of these Certificate Authorities. The directory must be hashed in the usual manner (seec_rehash(1)).--ssl-port=portβ specifies the port number for SSL connections, implies--ssl. When-i/--listenoptions are given without explicitssl:prefixes, each address is expanded into a plain-TCP listener on--portand an SSL listener on--ssl-port, matching the no--ibehaviour.--server-key keyfileβ specify the SSL key file to use for SSL connections. Defaults to/etc/spamassassin/certs/server-key.pem.--server-cert certfileβ specify the SSL certificate file to use for SSL connections. Defaults to/etc/spamassassin/certs/server-cert.pem.--socketpath pathnameβ listen on a UNIX domain socket at path pathname, in addition to sockets specified with a--listenoption. This option is provided for compatibility with older versions ofspamd. Starting with version3.4.0the--listenoption can also take a UNIX domain socket as its value (an absolute path name). Unlike--socketpath, the--listenoption may be specified multiple times ifspamdneeds to listen on multiple UNIX or INET or INET6 sockets.
β οΈ Warning: the Perl support on BSD platforms for UNIX domain sockets seems to have a bug regarding paths of over 100 bytes or so (SpamAssassin bug 4380). If you see a 'could not find newly-created UNIX socket' error message, and the path appears truncated, this may be the cause. Try using a shorter path to the socket. π
By default, use of --socketpath without --listen will inhibit SSL connections and unencrypted TCP connections. To add other sockets, specify them with --listen, e.g. '--listen=:' or '--listen=*:'.
--socketowner nameβ set UNIX domain socket to be owned by the user named name. Note that this requires thatspamdbe started asroot, and if-uis used, that user should have write permissions to unlink the file later, for when thespamdserver is killed.--socketgroup nameβ set UNIX domain socket to be owned by the group named name. See--socketownerfor notes on ownership and permissions.--socketmode modeβ set UNIX domain socket to use the octal mode mode. Note that if-uis used, that user should have write permissions to unlink the file later, for when thespamdserver is killed.--timingβ enable timing measurements and output the information for logging. This is the same information as provided by theTIMINGtag. β±οΈ
π SEE ALSO
spamc(1) spamassassin(1) Mail::SpamAssassin::Conf(3) Mail::SpamAssassin(3)
π PREREQUISITES
Mail::SpamAssassin
π AUTHORS
The SpamAssassin(tm) Project (https://spamassassin.apache.org/)
π LICENSE
SpamAssassin is distributed under the Apache License, Version 2.0, as described in the file LICENSE included with the distribution.
okay bestie that's the whole page, we ate and left absolutely no crumbs π
this was SPAMD(8p) from perl v5.40.1, dated 2026-07-23, and likeβ¦ go forth and filter that spam, main character. π¦β¨
π¦ where this page comes from
- ubuntu stonking: spamd 4.0.2+svn1935691-1build1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms