the djb way

services, services!


fetchmail


Protocol: system daemon
Standard Port: N/A

fetchmail is a mail retrieval utility written by Eric S. Raymond. It is extremely flexible and configurable for a variety of retrieval and forwarding applications.

Here we will consider the use of fetchmail in a particular scenario. Imagine you are running an email server for your site that picks up messages for your domain from a remote maildrop. Maybe your Internet connection is intermittent or unreliable, and so your ISP hosts an alternate MX for your domain. You want to use fetchmail to periodically collect mail from the maildrop, delivering it to users on your local network via your locally-running SMTP mail transport agent (which, of course, is qmail.)

Although fetchmail has its own daemon mode, using it with a daemontools setup will provide some advantages. These include:

For security reasons, you will probably want to run fetchmail under daemontools' setuidgid as an unpriveleged, non-root user. Create a user account named "fetchmail", member group "nofiles", with disabled password, /homeless home directory, and /nonexistent login shell.

Then proceed to make the local service directories. Here we also create a pid directory where fetchmail will be told to write its lockfile:

# mkdir -p /var/svc.d/fetchmail/{log,pid}
# chown fetchmail /var/svc.d/fetchmail/pid

Put this daemontools run script in /var/svc.d/fetchmail/run:


#!/bin/sh
# fetchmail/run
INTERVAL=551
exec 2>&1
echo "*** Starting fetchmail service..."
exec env FETCHMAILHOME="./pid" \
    setuidgid fetchmail fetchmail -v \
    -f ./fetchmail.conf \
    --nodetach \
    --daemon ${INTERVAL}

### that's all, folks!

Of course, make the script executable as usual. The $FETCHMAILHOME environmental variable is set, telling fetchmail where to write its fetchmail.pid lock file. Then fetchmail is invoked with the -v flag for the verbose option, and told to read its configuration file from /var/svc.d/fetchmail/fetchmail.conf. The --nodetach option tells fetchmail to run in the foreground, as daemontools requires. The interval between polls is parameterized with the variable $INTERVAL, used as an argument to the --daemon flag. The example sets up fetchmail to poll the remote server every 9 minutes, 11 seconds. (The --nodetach option keeps fetchmail in the foreground, even when running with the --daemon option.)

Most everything else about running fetchmail is defined in its configuration file, fetchmail.conf. This configuration will be very specific to your site. As an example, it may look something like this:


# fetchmail/fetchmail.conf
#
poll maildrop.myisp.com proto apop port 110 nodns
  timeout 71
  localdomains example.org
  qvirtual "example-"
  envelope Delivered-To
  user example with pass woolybooly
  smtpaddress example.org
  to * here
  fetchall forcecr

### that's all, folks!

This example polls a maildrop, the imaginary maildrop.myisp.com. The ISP has a POP3 server setup on port 110, and recognizes APOP authentication.

We use the timeout keyword to tell fetchmail to give up on this round if a connection cannot be established after a certain time. Our domain is example.org, so fetchmail should consider it local. The maildrop happens to use qmail conventions, so we tell fetchmail to strip the example- prefix from the incoming messages, and look for the recipient information in Delivered-To lines. And so on...

This configuration file needs to be readable by the "fetchmail" user account. Also note the file has the password for the maildrop POP account in cleartext. So make sure the file is owned by "fetchmail" and protected with permissions 0600:

# chown fetchmail:nofiles fetchmail.conf
# chmod 600 fetchmail.conf

Probably you will spend some time testing your configuration with manual runs of fetchmail from the command line. Once your configuration is the way you like it, then setup the usual logging service in /var/svc.d/fetchmail/log/run:


#!/bin/sh
# fetchmail/log/run
exec setuidgid multilog multilog t /var/multilog/fetchmail

### that's all, folks!

Prepare the log directory as usual in /var/multilog:

# mkdir -p /var/multilog/fetchmail
# chown multilog:nofiles /var/multilog/fetchmail

The service is ready. Link it into /service to start it up:

# ln -s /var/svc.d/fetchmail /service/fetchmail

Now fetchmail will startup with every system boot, no need to make system-specific alterations to boot scripts. If fetchmail barfs, daemontools will restart it automatically. And you will find complete tai-stamped logging in the familiar /var/multilog directory.

When running as a non-root user in daemon mode, you can force fetchmail to wake-up and do a poll by giving it the SIGUSR1 signal. Unfortunately, the standard daemontools package does not support USR1/USR2 signals. But if you followed the installation instructions, and applied the daemontools-0.76.sigq12.patch patch, this capability will be available:

# svc -1 /service/fetchmail

(The option here is the number "one".) This will prompt the fetchmail service to wake-up and do an immediate poll of the remote server.

If you haven't applied the patch, not a huge deal. The svc -t /service/fetchmail command will force fetchmail to terminate and restart, simulating the desired effect.

The difference is noticeable when you are polling an SSL-enabled server, though. With a USR1 signal, fetchmail will repoll with certificate information cached from its first connection. This saves quite a bit of dialogue time, compared to a restart.


Copyright © 2003, 2004 Wayne Marshall.
All rights reserved.

Last edit 2004.04.06, wcm.