Motivation: I’m changing my ticketing system so that messages with a friendlier subject line. Instead of ‘Subject: [SNAFU #1] summary’, I’ll change it to use ‘Subject: [HELPDESK #1] summary’.
Another colleague suggested we use procmail
. As unixgeeks.org says:
Is procmail right for me?
Procmail is a serious unix hack. On the other hand, it does a pretty good job.
(http://unixgeeks.org/security/newbie/unix/procmail/procmail.html)
I think we can do better than a serious Unix hack. I think Postfix can handle this.
How to do it?
First, I created a test environment: two Debian 9 virtual machines:
- foo.osric.net
- bar.osric.net
I’m not going to add DNS entries, though, so I’ll be relying on their IP addresses on my internal network:
- 192.168.0.18
- 192.168.0.19
I installed postfix
and mutt
on each:
# apt-get install postfix mutt
As an initial test, I tried to send a message from one machine to the other:
# sendmail root@192.168.0.18 < test.eml
But this resulted in an error from the mailer-daemon:
<root@192.168.0.18>: bad address syntax
The solution? Enclose the IP address in square brackets:
# sendmail root@[192.168.0.18] < test.eml
(Thanks to Is there a way to send an email to an IP address directly?, which I believe is the first time I have ever seen anything useful on the Quora web site.)
The two test systems can send messages to each other. Great!
Now, to change the subject line. A ServerFault post, postfix header_checks to rename email subject, looked like exactly what I was looking for (and a similar scenario motivated that question).
Following the answer there, I added the following to /etc/postfix/main.cf
:
header_checks = pcre:/etc/postfix/header_checks.pcre
And I created /etc/postfix/header_checks.pcre
, containing the following:
/^Subject: \[SNAFU #(\d+)\](.*)$/ REPLACE Subject: [HELPDESK #$1]$2
Don’t forget to reload Postfix, required by just about any Postfix change:
# postfix reload
I sent a test message from bar
to foo
, and an error message arrived in root’s mailbox on foo
:
Subject: Postfix SMTP server: errors from bar.osric.net[192.168.0.19]
I checked the logs at /var/log/mail.log
and found the following:
Jul 8 16:47:29 foo postfix/cleanup[10927]: error: unsupported dictionary type: pcre
I reproduced this problem using postmap
:
# postmap -q 'Subject: [SNAFU #1]' pcre:/etc/postfix/header_checks.pcre
postmap: fatal: unsupported dictionary type: pcre
I changed the filename (not strictly necessary, but good for my sanity) and tried regexp
instead:
# postmap -q 'Subject: [SNAFU #1]' regexp:/etc/postfix/header_checks.regexp
This produced no output, no error message, and a return code of 1. Why didn’t it match?
It turned out I needed to modify the regular expression, since \d
is a Perl-ism:
/^Subject: \[SNAFU #([0-9]+)\](.*)$/ REPLACE Subject: [HELPDESK #$1]$2
(Using [[:digit:]]
instead of [0-9]
would also work.)
I ran a couple successful tests using postmap
:
# postmap -q 'Subject: [SNAFU #1]' regexp:/etc/postfix/header_checks.regexp
REPLACE Subject: [HELPDESK #1]
~# postmap -q 'Subject: [SNAFU #1] more text' regexp:/etc/postfix/header_checks.regexp
REPLACE Subject: [HELPDESK #1] more text
Now to test an actual e-mail message.
First, I updated /etc/postfix/main.cf
to point to the updated filename with the corresponding dictionary type:
header_checks = regexp:/etc/postfix/header_checks.regexp
Don’t forget:
# postfix reload
I tested it from bar.osric.net
(192.168.0.19), using the following file, test.eml
:
Subject: [SNAFU #1] test message
This is a test.
# sendmail root@[192.168.0.18] < test.eml
It appeared in root’s inbox on foo.osric.net
(192.168.0.18) with the updated subject as expected:
Date: Sun, 8 Jul 2018 17:03:56 -0500 (CDT)
From: root <root@bar.osric.net>
Subject: [HELPDESK #1] test message
This is a test.
I sent another message with a different subject line just to confirm it was unchanged by the header_check
.
Other useful resources:
- Postfix documentation: header_checks
- Postfix documentation: postmap
- Postfix documenation: regexp table
I should note that the regular expression used here would not match subject lines that contain reply (Re:) or forwarded (Fwd:) indicators, e.g.:
With a little extra work on the regular expression, that should be solvable.
On Debian (or Ubuntu), you can solve the “unsupported dictionary type” error by installing
postfix-pcre
:You can list all currently-installed lookup table types with: