Rewrite email (RFC822) From address to match MAIL FROM (RFC821) envelope address postfix
I've spent some time looking into this and I can't find a pure postfix way. The one suggestion of using header_checks
doesn't seem to work because you can't (AFAIK) match one header against another.
What is possible is to write your own program / script to perform the check for you and use this as a content_filter.
Step 1
Here's a simplified version of the one I use written in python. This reads an email from the stdin taking MAIL from
and RECPT to
addresses as arguments. It checks the From:
header against the MAIL from
and replaces it if they don't match. I save this as /usr/share/mail_filter/filter.py
:
#! /usr/bin/python3
import sys
import subprocess
import email.parser
import email.policy
parser = email.parser.BytesParser(policy=email.policy.default)
message = parser.parse(sys.stdin.buffer)
envelope_from = sys.argv[1]
envelope_to = sys.argv[2]
# This if statement checks envelope from against message from
if message['From'].addresses[0].addr_spec != envelope_from:
print(f"Replacing sender {message['from']} with {envelope_from}", file=sys.stderr)
message.replace_header('From', envelope_from)
# sendmail -G -i -f sender@sender_domain.tld recipient@recipient_domain.tld
sendmail = subprocess.Popen(["/usr/sbin/sendmail", "-Gif", envelope_from, envelope_to], stdin=subprocess.PIPE)
with sendmail.stdin:
sendmail.stdin.write(message.as_bytes())
# If sendmail returns an error, cascade it back to postfix
sys.exit(sendmail.wait())
Step 2
Updated /etc/postfix/master.cf
:
# added the -o content_filter...
smtp inet n - y - - smtpd
-o content_filter=filter:dummy
# Added this entire service
filter unix - n n - 10 pipe
flags=Rq user=filter null_sender=
argv=/usr/share/mail_filter/filter.py ${sender} ${recipient}
Note this references the script location from step 1 and the user defined in step 3
Step 3
I added an OS user filter
in a group with access to use sendmail
.
useradd --system --gid postdrop filter
Caveats
As per the instructions simple filters (passing forward using sendmail
) can only be applied to SMTP clients and cannot filter messages sent via sendmail. If this is a problem for you then you would need to write an advanced content filter.