Postfix address rewriter

By steve, 20 April, 2016

The following code allows e-mail to be sent to realtouser+rewriteuser+rewritedomain@smtp-rewrite.realdomain, and it will change the from address to rewritefrom@rewritedomain and send the mail to realtouser@realdomain

If requires the follwing postfix config in /etc/postfix/master.cf:

 filter    unix  -       n       n       -       10      pipe    flags=Rq user=nobody null_sender=    argv=/path/to/script -f ${sender} -- ${recipient}
 smtp      inet  ...other stuff here, do not change...   smtpd        -o content_filter=filter:dummy

And the following in /etc/postfix/main.cf:

relay_domains = smtp-rewrite.realdomain
relay_recipient_maps = hash:/etc/postfix/smtp-rewrite-recipient-map

And the following in /etc/postfix/smtp-rewrite-recipient-map

@smtp-rewrite.realdomain   OK

And then run:
postmap /etc/postfix/smtp-rewrite-recipient-map

You will also need to add a DNS record for smtp-rewrite.realdomain pointing to the IP address of the mail server (either MX or A record)

Script below:

#!/usr/bin/perl

use strict;

my @sendmailargs=("/usr/sbin/sendmail","-G","-i");
my $frompos=-1;
my $lastarg=-1;
my $endargs=0;

my $origtoaddress="";
my $toaddress="";
my $origfromaddress="";
my $fromaddress="";

foreach my $arg(@ARGV) {
        if($arg eq "-f") {
                # Record the position of the from address
                $frompos=scalar(@sendmailargs)+1;
        } elsif ($arg eq "--") {
                # -- signals the end of arguments, everything else is an e-mail address
                $endargs=1;
                $lastarg=scalar(@sendmailargs)+1;
        } elsif (!$endargs) {
                # If we have not hit a definite end of the args set lastarg
                # variable based on whetehr this is an argument or not
                if ($arg =~ /^-/) {
                        $lastarg=-1;
                } else {
                        $lastarg=scalar(@sendmailargs);
                }
        }
        push @sendmailargs,$arg;
}

if($lastarg > 0 && $frompos > 0) {
        for(my $i=$lastarg; $i) {
        if($headers) {
                if($_ =~ /^$/g) {
                        $headers=0;
                } elsif ($fromaddress && $_ =~ /^(From|Sender:Reply-To): /) {
                        $_ =~ s/()\S+\@\S+(>?)/$1$fromaddress$2/g;
                } elsif ($fromaddress && $_ =~ /^(To|CC): /) {
                        $_ =~ s/$origtoaddress/$toaddress/g;
                }
        }

        print FD  $_;
}

close(FD);
exit($?);

Comments