SpamAssassin

‚  < ‚  Day Day Up ‚  > ‚  

2.4 Using spamc / spamd

If you are filtering a lot of incoming mail, the processing time required to invoke a new spamassassin script (and starting the Perl interpreter) for each message can become prohibitive. An alternative approach is to run the SpamAssassin daemon, spamd . spamd is started once at system boot and loads the SpamAssassin Perl modules to perform spam-checking. Instead of running the spamassassin script on each message, messages are piped to the spamc program. spamc is a lightweight client, written in C and compiled to an executable that simply takes messages, relays them to spamd , and returns the results.

spamd has several important command-line arguments that control its operation. Once it's properly set up, however, using spamc is simple.

2.4.1 Setting up spamd

By default, spamd is installed in /usr/bin . It is typically started by root from a system boot script but can also be started by root from the shell for testing. The simplest invocation of spamd is:

/usr/bin/spamd --daemonize --pidfile /var/run/spamd.pid

The --daemonize command-line option directs spamd to operate as a daemon in the background. The --pidfile command-line option specifies the file to which spamd will write its process ID number. This option is important because spamd must be signaled with a HUP signal to its process ID whenever the systemwide SpamAssassin configuration is changed (you'll find an example later in this chapter).

When spamd receives a connection, it forks a child process to handle the connection. Typically, the child process reads a request to perform spam-checking from the client (including the account name of the user making the request, the message to check, and other data), performs the requested check, returns the (possibly tagged) message back to the client, and exits.

Several options are used with spamd in many environments. The most common are detailed in the following sections.

2.4.1.1 Connection type

spamd can accept connections from spamc clients either by listening on a TCP port or a Unix domain socket. By default, spamd binds TCP port 783 on the local 127.0.0.1 IP address, which should prevent remote users from connecting to it. You can change how it listens with these command-line options:

--socketpath / path /to/socket

Listen on a Unix domain socket at the specified path instead of a TCP port. Using a Unix domain socket is more efficient than a TCP port and ensures that only local users can access the daemon.

--listen-ip ip-address

Listen on a TCP port on the specified IP address. This can be used to override the default 127.0.0.1 IP address and allow spamd to receive connections from remote machines. This might be useful if you wanted to dedicate a single machine in a LAN to spam-checking in order to manage the processing load or to let many client machines share a well- tuned daemon.

--port port-number

Listen on a TCP port other than the default port (783).

--allowed-ips ip-address,ip-address,...

Specify a comma-separated list of IP addresses from which connections will be accepted. Although this provides a measure of access control for a daemon that accepts remote connections, it should be supplemented with host-based firewall rules for greater security.

--ssl

Require connections from clients to use the SSL/TLS (Secure Sockets Layer/Transport Layer Security) protocol. This provides for encryption of the data between client and server and potentially for authentication of the server to the client, although SpamAssassin's spamc does not attempt to verify the server certificate.

--server-key keyfile

Specifies the file containing the SSL private key for spamd , if SSL connections are to be required.

--server-cert certfile

Specifies the file containing the SSL certificate for spamd , if SSL connections are to be required.

If you want to provide secure remote access to spamd , the SSL support in spamd / spamc is not sufficient, as it provides no mechanism for spamd to authenticate spamc clients. An alternative approach would be to wrap the server and client connections in an SSL tunnel with a program like stunnel that does provide two-way authentication.

2.4.1.2 Running as a non-root user

You must start spamd as root so that it can bind its TCP port or open its socket for connections. By default, spamd continues to run as root . When it receives a connection from spamc , it drops privileges and runs as the user that spamc claims to be running as. This enables it to access private, per-user configuration files.

Many system administrators are uncomfortable running spamd as root . A bug in spamd could provide an attacker with root privileges; a local attacker could also spoof spamc and claim to be a different user (which can be ameliorated with the --auth-ident option discussed later).

To provide additional security, spamd can be instructed to run as a non- root user. After binding its TCP port or Unix socket, spamd gives up root privileges and runs as the specified user. Ideally, you should create a new user (e.g., spamd ) with its own group ( spamd ) and a private home directory ( /home/spamd ). All systemwide configuration files should be made readable by the new user, and the pid file given to the --pidfile command-line option should be in a directory writable by the new user (perhaps its home directory). If spamd is using a Unix domain socket, the socket will automatically have its owner set to the new user, so no changes to this path are necessary, but the directory in which the socket will be created must be writable by the user.

After creating your new user, start spamd like this, as root :

/usr/bin/spamd --daemonize --username spamd --pidfile /home/spamd/spamd.pid

The --username command-line option specifies the name of the user that spamd will run as.

If you want to allow per-user configuration, users' home directories and .spamassassin subdirectories will have to be searchable by the new user (which typically means they must be world-searchable), and files in their .spamassassin directories will have to be readable by the new user. Alternatively, you can turn off per-user configuration with the - -nouser-config command-line option (or store per-user configuration in an SQL database, as discussed in Chapter 3).

You can also run spamd as a non- root user simply by starting it as a non- root user. In this case, the user running spamd must be able to read all of the relevant system configuration files, and you must specify a port number higher than 1024 (or a Unix domain socket in a directory the spamd user can write in).

2.4.1.3 Other security features

Three command-line options provide additional assurances that spamd will operate only when the user running spamc is actually the user that spamc claims to be running for.

--auth-ident

This option causes spamd to perform an ident (RFC 1413) lookup on the connection. If the client's system is running a (trustworthy) ident server, the lookup will return the username of the user running spamc . spamd will confirm that this username matches the username provided by spamc and will refuse to respond if it does not.

--ident-timeout number-of-seconds

Specify the number of seconds to wait for the ident server to respond. If the response doesn't come after this number of seconds, spamd will refuse to perform spam-checking for the connection.

-- paranoid

Specify that spamd should report an error and exit if it finds itself still running as root after it should have changed to a non- root user ID (either the one given by --username or the user running spamc ), or if it cannot look up a given user's name. Without this option, spamd continues running as the nobody user.

One command-line option can protect spamd from being used to commit a denial-of-service attack against its server.

--max-children number

Specifies the maximum number of child processes that spamd will fork. When this maximum is reached, connections will be queued until the number of children drops below the maximum again (or until the operating system can no longer queue connections). If max-children is used, spamd must open pipes to communicate with each child.

In SpamAssassin 3.0, the --max-children option defaults to 5, but in SpamAssassin 2.x, the default number of children is unlimited. I highly recommend explicitly setting --max-children to a reasonable value for your system.

Here's what a typical invocation of spamd might look like for a system that is only performing spam-checking for local users and that runs an ident server:

/usr/bin/spamd --daemonize --username spamd --pidfile /home/spamd/spamd.pid --auth- ident --paranoid --max-children=25

2.4.1.4 Locating configuration files

Like SpamAssassin, spamd looks for rulesets in /usr/share/spamassassin and systemwide configuration files in /etc/mail/spamassassin . If you've installed SpamAssassin in different locations, you can use the --configpath and --siteconfigpath command-line options to help spamd locate these files. These options work just as they do for the spamassassin script and were described earlier.

2.4.2 Testing spamc

Once spamd is running, use spamc instead of the spamassasin script to check a mail message. You can test spamc / spamd much as you would test spamassassin :

$ cd Mail-SpamAssassin-2.63 $ spamc -c < sample-nonspam.txt 0.0/5.0 $ spamc -c < sample-spam.txt 1000.0/5.0

The -c command-line option instructs spamc to produce only the score (and the spam threshold score) that spamd computes for each message. It also causes the spamc process to return an exit code of 1 for messages judged to be spam and 0 for messages judged not to be spam, which can be useful in scripting.

2.4.3 spamc Options

Like the spamassassin script, spamc takes several command-line options that modify its behavior. Here are some of the most useful (see the manpage for spamc for a complete list).

2.4.3.1 Connection type

By default, spamc attempts to connect to spamd at TCP port 783 on localhost. If you run spamd on a different IP address (perhaps on a different machine altogether) or listening on a Unix domain socket, spamc must be told where to connect.

spamc can take advantage of multiple spamd servers at different hosts to increase reliability or balance the processing load. In addition to specifying the proper command-line options to spamc (descriptions follow), you must designate a hostname in DNS with multiple A records, each listing the IP address of a spamd server host.

These command-line options control the spamc connection to spamd .

-d host

Connect to the spamd server on host , instead of localhost . If host is a hostname that resolves to multiple IP addresses, each one will be tried in turn until a successful connection can be made.

-p port

Specify the TCP port number to connect to spamd on. If multiple servers are used, all servers must use the same port number.

-H

When multiple spamd servers are used, try servers in random order instead of the order in which they are returned by the DNS server. This promotes load-balancing across the servers.

-S

Make connections to spamd with SSL. If multiple spamd servers are used, all servers must support SSL connections.

-U /path/to/socket

Specify a Unix domain socket to connect to spamd on, instead of using TCP.

2.4.3.2 Handling problems

By default, if spamc is unable to contact a spamd server, it returns the message unprocessed. This ensures that mail will not be lost due to problems with spamd but means that spam may be accepted without tagging. Two command-line options modify this behavior.

-t number-of-seconds

Specifies the number of seconds that spamc should wait for a reply from spamd before considering the spamd server unreachable. It defaults to 600 seconds (10 minutes), which may be too long to wait on a busy mail server. Setting the number-of-seconds to 0 disables the timeout altogether ‚ spamc will wait as long as it takes (and potentially forever).

-x

This option prevents spamc from returning messages unprocessed when it can't contact a spamd server. Instead, spamc will exit with an error code. Ideally, whatever process is calling spamc will interpret this error code properly, and the message will be queued for later retry . This option requires great care.

spamc 's options are different than those accepted by spamassassin , so it is not generally possible to simply substitute spamc for spamassasin in scripts without reviewing each option. Some of the options to spamassassin are instead given as options to spamd when it is started.

2.4.4 Invoking spamc with procmail

Just as spamc is run manually in place of the spamassassin script, it can also be run in a procmail recipe. Example 2-7 shows a typical /etc/procmailrc recipe for a system using spamd :

Example 2-7. A complete /etc/procmailrc for spamd

DROPPRIVS=yes PATH=/bin:/usr/bin:/usr/local/bin SHELL=/bin/sh # Spamassassin :0fw * <300000 /usr/bin/spamc

2.4.5 Changing SpamAssassin Configuration Files

To increase efficiency, spamd caches the spam-checking rules in memory when it starts up. Therefore, when spamd is in use, the daemon must be signaled whenever you make changes to the SpamAssassin rulesets or systemwide configuration file. Changes in user preferences do not require a signal because user preference files, if they are used, are reread each time they are needed.

spamd reloads configuration files when it receives a HUP signal. To send a process a HUP signal, read the process ID from the pidfile and use the kill command to send the signal:

# kill -HUP `cat /home/spamd/spamd.pid`

If you can't find the pidfile, use the ps command to locate the process ID:

# ps auxw grep spamd (On SysV systems, ps elf ) spamd 30124 0.0 0.6 22200 1596 ? S Nov22 0:02 usr/bin/spamd -- daemonize --username spamd --pidfile /home/spamd/spamd.pid alansz 30521 0.0 0.1 1520 508 pts/1 S 15:44 0:00 grep -E spamd # kill -HUP 30124

After reloading, spamd will have a new process ID.

‚  < ‚  Day Day Up ‚  > ‚  

Категории