Setting up procmail to ignore auto-responders and bounces

I'm using procmail to receive email messages and then forward them on to a script for handling. Sometimes this will even mean generating an email (for example, forwarding the message to another user, or answering a query).

Needless to say, I have zero interest in loading up my server with emails from autoresponders or vacation responses, so I'm wondering if there is an easy way to filter out these messages. I am piping these to a script anyway, so I can always roll my own filter in the script, but I'd rather not reinvent the wheel.

I already know I should trash messages with Precedence: junk or Precedence: bulk. Can I just filter them like you would any other header in procmail?


Reading the docs would be a good start. There's a mini-howto here which covers the basics. Automatically generated messages should be picked up by the FROM_DAEMON and FROM_MAILER rules. Also use X-Loop (described in doc referenced above) to avoid looping messages.

Finally, you can suppress repeat replies to the same address as demonstrated here (for the pruposes of a vacation auto-responder). So even if the remote system does not play nicely and populate the from address properly and strips out the X-Loop header, you can break the cycle.

Procmail can be used to create very sophisticated systems - it's a programming language in its own right. You might also want to have a look at:

  • The Procmail Companion
  • Infinite Ink's Procmail guide

Update

Since www.clarconnect.com has dropped off the internet, I fetched the content from the way back machine:

Overview

I know not everybody approves of e-mailed vacation auto-replies, but the fact is that some of our clients/users insist on it. So here is a way you can set up a system where the users can administer their own vacation auto-reply messages.

Features of this procmail vacation auto-reply recipe:

  • User-managed auto-reply - user can enable/disable the auto-reply and user can set a different reply message every time.
  • An auto-reply is only sent once to an email address every time the auto-reply is enabled. Consequently auto-reply loops are avoided and if one person (or mailing list) sends multiple emails to the address while the auto-reply is enabled, the sender is not bothered by multiple auto-reply responses.
  • Recipe attempts to avoid responding to mailing lists and spam. Install and Configure Procmail

Before you proceed any further you will need to have procmail enabled on your system. For instructions, go to the following howto: Filtering E-mail With Procmail

Take special note of the section titled "Enable Procmail in Postfix".

Configuring Vacation Auto-Reply

To enable vacation auto-reply for your users you will need to create a .procmailrc file in the /home/"username" folder for every user requiring this service. The file will need to contain the code below.

# Uncomment the lines below if you need log output for testing.
#
#LOGFILE=/tmp/procmailvacation.log
#VERBOSE=on

# vim: ft=procmail

# User-managed vacation recipe for procmail
# Written by Jason Thaxter
#  (http://www.google.com/search?q=jason+thaxter)

#   * Include this file in the procmail file.
#   * Set $VACATION_PASSWORD. (for security, this is mandatory)
#   * Define $VACATION_SENDER in your procmail recipe: it will be "from" this
#     address.
#   * E-mail a message with $VACATION_PASSWORD and $VACATION_ON in the subject
#     line. The body of the message becomes the vacation message. $VACATION_ON
#     can be set prior to the INCLUDERC, but it defaults to "vacation on".
#   * To turn it off, e-mail a message with $VACATION_PASSWORD and $VACATION_OFF
#     in the subject line. Likewise, $VACATION_OFF defaults to "vacation off".

# Note that you probably want this to execute *after* any mailing list or spam
# delivery recipes. You can set $VACATION_SKIP to disable vacation processing
# if it's inconvenient to skip this recipe.

# -----------------------------------------------------------------------------
# Configurable variables: These variables allow you to use this vacation recipe
# as an include and customize it from your main procmail file.
#
# lockfile:
VACATION_LOCK=$HOME/${VACATION_LOCK:-".vacation$LOCKEXT"}
# cache file:
VACATION_CACHE=$HOME/${VACATION_CACHE:-".vacation_cache"}
# cache size:
VACATION_CACHE_SZ=${VACATION_CACHE_SZ:-8192}
# message file
VACATION_MSG=$HOME/${VACATION_MSG:-".vacation_mesg"}
# what to use as the xloop header
HOSTNAME=${HOSTNAME:-`hostname`}
VACATION_XLOOP=${VACATION_XLOOP:-"$LOGNAME@$HOSTNAME"}
# base token for default $VACATION_ON and $VACATION_OFF
# so you could set this and not those individually
VACATION_COOKIE=${VACATION_COOKIE:-"vacation"}
VACATION_ON=${VACATION_ON:-"$VACATION_COOKIE on"}
VACATION_OFF=${VACATION_OFF:-"$VACATION_COOKIE off"}

#
#Change these variables
#
VACATION_PASSWORD=yourpassword
VACATION_DOMAIN_NAME=domainname.com

VACATION_SENDER=$LOGNAME@$VACATION_DOMAIN_NAME
VACATION_SENDMAILFROM=${VACATION_SENDMAILFROM:-"-f$VACATION_SENDER"}
VACATION_SENDMAILFLAGS="-oi -t $VACATION_SENDMAILFROM"
# -----------------------------------------------------------------------------

SENDMAIL_CMD="$SENDMAIL $VACATION_SENDMAILFLAGS"
SHELL=/bin/sh

# check if we should send vacation message, add user to cache
:0 Whc: $VACATION_LOCK
# if i haven't been instructed to skip processing
* ? test -z $VACATION_SKIP
# if i have a vacation message file
* ? test -f $VACATION_MSG
# and the message is not from a daemon or mailer
* !^FROM_DAEMON
* !^FROM_MAILER
# not declared spam by spamassassin
* !^X-Spam-Flag: YES
# not discernably in a mailing list
* !^List-
* !^(Mailing-List|Approved-By|BestServHost|Resent-(Message-ID|Sender)):
* !^X-[^:]*-List:
* !^X-(Sent-To|(Listprocessor|Mailman)-Version):
# and not x-loop
* !^X-Loop: $VACATION_XLOOP
# add it to the cache
| formail -rD $VACATION_CACHE_SZ $VACATION_CACHE

:0 ehc
# if the name was not in the cache
# if we can find who we're sending it to
# and who we are sending this "From"
* ? test -n ${VACATION_MSG_SEND_TO}
* ? test -n ${VACATION_SENDER}
*$ !^From:.*$VACATION_SENDER
| (formail -r \
   -I"Precedence: junk" \
   -A"From: $VACATION_SENDER" \
   -A"X-Loop: $VACATION_XLOOP"; \
   cat  $VACATION_MSG ) | \
   $SENDMAIL_CMD

# Add/remove vacation message
:0
# First make sure that the sender has 
# the correct username
* ^TO_\/[-\.a-z_]+@
*$ ^From:.*$\MATCH
# the correct email domain
*$ ^From:.*$\VACATION_DOMAIN_NAME
# only do this if we have a password set
* ? test -n $VACATION_PASSWORD
# and it's in the subject line
* $^Subject:.*${VACATION_PASSWORD}
{

    # VACATION ON
    # if subject line matches magic cookie for ON:
    :0
    * $^Subject:.*${VACATION_ON}
    {
       # pipe the body into the vacation message file
       :0c:$VACATION_LOCK
       | formail -I "" > $VACATION_MSG

       # add message to the body
       :0f
       | cat - ; \
       echo; \
       echo '---------- VACATION -----------------'; \
       echo 'The above text was installed as your vacation message'
    }

    # VACATION OFF
    # if subject line matches magic cookie for OFF:
    # delete the vacation file and notify
    :0f
    * $^Subject:.*${VACATION_OFF}
      | cat -;  \
      echo '---------- VACATION -----------------'; \
      echo 'Removing message and cache: '; \
      rm -vf $VACATION_MSG; \
      rm -vf $VACATION_CACHE; \
      echo ; \
      echo "Removed vacation message."

 }

Once you have created the file, make sure that you change the following lines:

  • $VACATION_PASSWORD - this is to prevent others from enabling/disabling your vacation auto-reply.
  • $VACATION_DOMAIN_NAME - this is the domain name used for your emails (e.g. [email protected]).

Now you will want to make sure that the .procmailrc file has the following security permissions:

User and Group should be set to the username of the email user you're setting it up for.

File Permissions should be set to rwx------ for the user only (i.e. 0700).

** Warning! **

Note that if you set the permissions for .procmailrc to the wrong user or set the permissions so that user,group and others can read/write/execute .procmailrc, then procmail will ignore your .procmailrc file.

Once these settings are configured the auto-reply should work. If you experience problems with the auto-reply, you can uncomment the following two lines and check the content of /tmp/procmailvacation.log.

#LOGFILE=/tmp/procmailvacation.log
#VERBOSE=on

Using Vacation Auto-Reply

Now that the recipe is installed users can turn on the vacation auto-reply by sending themselves an email with the following subject:

  • password vacation on - where password is the password configured in the script.

The body of this email will become the auto-reply email message. The user will receive the email the user just sent to themselves with the following text appended to the end:

---------- VACATION -----------------

The above text was installed as your vacation message

To turn off the vacation auto-reply the users send themselves an email with the subject

  • password vacation off - where password is the password configured in the script.

The user will receive the email the user just sent to themselves with the following text appended to the end:

---------- VACATION -----------------

Removing message and cache: 
removed `/home/[username]/.vacation_mesg'
removed `/home/[username]/.vacation_cache'

Removed vacation message.

Well, if the subject contains a standard response, then you can filter everything with "Out Of Office" (or similar) to /dev/null.

:0
* 'Out Of Office'
/dev/null