How to configure postfix to pipe all incoming email to a script?

Solution 1:

Ok, I just got this working -- though hairier than I thought it would be. I dropped the maildir_command part, and went with transport_maps. The key is to do 5 things:

  1. Set up a db file to handle aliases (and add a catch-all alias)
  2. Set up a db file to map the 'transport' for the domain in question to a special handler.
  3. Compile the db files into berkeley db format that postfix wants.
  4. Set up the handler in /etc/postfix/master.cf to pipe mail to the script.
  5. Set /etc/postfix/main.cf to use the transport db for transport_maps, and the alias db for virtual_alias-maps.

(1) Create /etc/postfix/virtual_aliases to add a catch-all alias -- localuser needs to be an existing local user:

@mydomain.tld   [email protected]

(2) Create /etc/postfix/transport to add a transport mapping. "mytransportname" can be whatever you want; it's used below in master.cf:

mydomain.tld    mytransportname:

(3) Next, both transport and virtual_aliases need to be compiled into berkeley db files:

$ sudo postmap /etc/postfix/virtual_aliases
$ sudo postmap /etc/postfix/transport

(4) Add the transport to /etc/postfix/master.cf:

mytransportname   unix  -       n       n       -       -       pipe
  flags=FR user=localuser argv=/path/to/my/script.py
  ${nexthop} ${user}

(5) In /etc/postfix/main.cf:

  ...
  transport_maps = hash:/etc/postfix/transport
  virtual_alias_maps = hash:/etc/postfix/virtual_aliases

And... good to go! Sheesh.

Solution 2:

The only time I've used something like this was for a specific user's mailbox. All that was required was to alias that user's name to a pipe and a process in aliases:

pong: "| /usr/local/bin/gotit.pl"

This sent traffic destined for "[email protected]" to a perl script I wrote to process it.

gotit.pl (as an example, don't pick on me for crappy programming skillz =). It's job was to process an email I'd sent to our Exchange server (where it was auto-replied via some VB code) to verify that Exchange was processing email in a timely fashion. If not, the mail server would send out an alert email to our pagers and write a lock file so we didn't get constantly spammed.

#! /usr/bin/perl -w
use vars qw ( $mung $sent $tvalue $remainder $delta $fout );
$mung = time;
while (<STDIN>) {
    ($sent, $tvalue, $remainder ) = split /: /, $_, 3;
    $tvalue =~ s/(\D+)//g;
    chomp($tvalue);
    $delta = $mung-$tvalue;
    if ( $sent =~ "Sent" ) {
        $fout = "/var/spool/mailcheck/$tvalue";
        next unless ( -e $fout );
        open (TMP, "> $fout") or die "Couldn't open output file: $!\n";
        print TMP "Received in: $delta seconds.\n";
                close TMP;
        last;
    }
}