procmail and .forward
The facts are these:
- I have a user account (and therefore mailbox) on a unix box (let's call it Acorn) behind Xcorp's corporate firewall.
- I want all mail received for my account on Acorn to be forwarded to another, external, email address.
I used to achieve this quite simply by creating a ".forward" file in my home directory on Acorn. This contained one line:
\my_username, me@anotherhost.com
which saved a copy of my mail locally and also sent it to my remote email address.
XCorp's network policy meant that Acorn couldn't communicate directly to the outside world; instead, all email was sent out via the company's smtp relay.
This system worked well for a good while -- right up until a couple of weeks ago when XCorp's sys-admins tightened up their relay's policy.
It now refused to relay any messages where the sender's email address (as given in the 'From' header) was not from the xcorp.com domain. This meant that about 80% of the emails I received on Acorn were now being bounced.
I was pretty sure I could use my .forward file to somehow get round this unwelcome hurdle by
- changing every "From:" header on all incoming mail to me@acorn.xcorp.com
- adding the original "From:" header as the "Reply-To:" header (so I could still reply to the real sender)
- redirecting the mail (as before) to me@anotherhost.com
And after a few hours of trial-and-error, that is what I've done. (I record it here for my own reference, though if you find it helpful please feel free to make use of it. However, bear in mind that I am by no means an email expert and may be doing all this in completely the wrong way.)
Step 1: edit .forward file
First I threw away the old .forward file and replaced it with a new one-line file:
"|IFS=' '&&exec /usr/bin/procmail -f-||exit 75 #donald_i"
This pipes all mail delivered to me on acorn (by the MTA, which is postfix) to the procmail program. The other stuff sets the separator character to be a space (' '), which is the default anyway, and handles any errors in firing up procmail by exiting with code 75. (This -- potentially -- will mean something to postfix.)
When procmail is called in this way, it looks in your home directory for a file called .procmailrc. If it doesn't find it, it does precisely nothing (other than delivering your mail). However, you can put all sorts of recipes into your procmailrc to process mail in different ways before -- or instead of -- delivering it.
Step 2: Contructing a procmailrc file
I merely scratched the surface of the program's capabilities (and may have got even that wrong) but this is what I came up with for my .procmailrc.
SENDMAIL = /usr/sbin/sendmail
ORIG_FROM = `formail -zxFrom:`
:0
* !^X-Loop: me@acorn.xcorp.com
| formail \
-i "From: me@acorn.xcorp.com" \
-i "Reply-To: $ORIG_FROM" \
-A "X-Loop: me@acorn.xcorp.com" \
| $SENDMAIL -oi me@anotherhost.com
The first two lines are just bash variables. We need to keep the current value of the "From" header for use later on, and the formail program can get that for us. Then the ":0" is procmail's way of starting a method or procedure. Other flags can be added here, but we don't need them. The the * wildcard indicates we're going to start a regex style match: it says, "for all messages that don't contain an X-Loop header set to me@acorn.xcorp.com, do the following".
The following in this case means run through procmail's helper program, formail. The -i parameter adds a header to the message currently being processed. If the message already has a header with this name, it is renamed to "Old-[Header]". So we change the "From" header to keep the proxy happy and add the original "From" data as a "Reply-To:" header so I can still reply to the person who sent the email. Finally we add the X-Loop header we did the check for earlier (-A adds headers) to guard against mail loops.
Finally the message is piped onward to the MTA for delivery. And this time, the XCorp mail relay will allow it to pass!
Note two things:
- I no longer keep a local copy of the email. This is fine -- it was of doubtful usefulness anyway. And if I wanted it reinstated, it would be easy enough.
- If the original sender had used the Reply-To header in their message, that info would be hidden in the message headers (as "Old-Reply-To:"). For the few emails I get via Acorn, I don't think this will cause me much trouble.
Comments
Post a Comment