HOWTO: Email Forwarding with Procmail using formail

Introduction
This was something I needed to do for Aerva and I spent quite awhile on it; a lot longer than I expected. I searched the web a million times looking for solutions and trying to get everything working properly. I decided to create this HOWTO in hopes that someone in the same situation won't have as much trouble.

Problem / Scenario
Reports from several computers are emailed to a single email address. Depending on which computer the report was sent from, I need to forward a copy of that email to a specific email address (the admin for that computer). The server receiving the email uses QMail as an MTA. I added the following line to the .qmail file for the email account (usually located in /var/qmail/mailnames/*domain*/*email-acct*/) to pass all incoming email along to procmail using the specified procmail config file:

| /usr/bin/procmail -m /var/qmail/mailnames/*domain*/*email-acct*/.procmailrc

I figured it would be easy to create the procmail config file using a few rules to catch and filter the subject of the email, and then forward a copy to the specified email address. Well it worked; partially.

All of my email accounts forward their email to a single email account making it easier for me to keep everything organized. So when procmail forwarded the email to my first email account, it should then have been forwarded to my main email account. However, the server for the main email account rejected the email with Error 500: Administrative Prohibition. It was something in the headers of the email that the server didn't like. I couldn't take the chance that one of the admin's might have the same setup as me and never receive the emails.

So I had two choices: either rewrite the headers of the email before forwarding it, or capture the contents of the email and rebuild a new email to send out. I used the latter solution.

Solution

This is the .procmailrc file used as mentioned above:

[code]
SHELL=/bin/sh # <------- THIS LINE IS VERY IMPORTANT!!! # I spent days trying to solve errors that were caused by this line missing! VERBOSE=yes # OPTIONAL, USED FOR DEBUGGING LOGABSTRACT=all # OPTIONAL, USED FOR DEBUGGING COMSAT=no MAILDIR="/var/qmail/mailnames/*domain*/*email-acct*/Maildir/" LOGFILE="/var/qmail/mailnames/*domain*/*email-acct*/procmail.log" #OPTIONAL, USED FOR DEBUGGING # Email addresses to forward reports to (EMAIL ADDRESSES SEPARATED BY COMMAS, NO WHITESPACE) SERVER23="[email protected],[email protected]" # For each new server group you want to catch emails for, copy the code between the recipe lines, # and then modify the what is needed according to the comments # # ------ begin recipe ---------------------- :0 # Change anything after the Subject:.* to match the emails you want to catch * ^Subject:.*Server23 # Used to prevent endless looping of emails * ! ^X-Loop: somewhere.com { :0 * ^Subject:[ ]*/[^ ].* { SUBJECT=$MATCH } :0c:formail.lock | expand | sed -e 's/[ ]*$//g' | sed -e 's/^/ /' > return.tmp

:0:formail.lock
# Change To: field to contain variable with email addresses
| ( /usr/bin/formail -I"Received:" -A"X-Loop: somewhere.com" -I"To: $SERVER23"
-I"From: [email protected]" -I"Subject: $SUBJECT" ; cat return.tmp ;
rm -f return.tmp ) | /usr/sbin/sendmail -t

}

# ----- end recipe ------------------------

# DO NOT REMOVE THE FOLLOWING THREE LINES,
# OTHERWISE EMAILS WILL NOT BE SENT TO THEIR ORIGINAL DESTINATION
:0
*
$MAILDIR

[/code]

As you can see, this procmail config captures the email's Subject and Body content, stores the Subject in a variable and the Body in return.tmp, then uses those two pieces to reconstruct an email using formail (man formail for options and usage), then sends the email to the addresses specified in the $SERVER23 variable. Once all that is done, the original email is placed in the maildir for that email account (specified in the $MAILDIR variable).

In my case, the MTA on the server is QMail, so it's using the maildir format and /usr/sbin/sendmail is actually a wrapper that comes with QMail. QMail actually uses qmail-inject in place of sendmail. Check the manual pages for qmail-inject if you're interested in using it directly.

Summary
In my case, this solution worked perfectly. The email successfully forwarded from my first email account to my main account without any problems. Even if you're not using QMail, this solution should still work.

Write a Comment

Comment

  1. HI..I want to get only mail from gmail, from a specific sender. I want to extrct the attached files in pdf to insert some parts of it into a mysql base..Can you help? TKs