autoreply.py
is a Postfix filter to send auto-reply emails when a message sent to a qualifying email address enters the Postfix mail system.
It supports authentication, StartTLS and HTML for the auto-reply.
The proposed Postfix configuration uses check_recipient_access
to instruct Postfix to only pipe emails that are addressed to these qualifying email addresses to autoreply.py
, while the rest continue their normal flow. The script, using settings stored in autoreply.json
, sends the auto-reply and re-injects the original email into Postfix for delivery.
The look up table related to check_recipient_access
is used for any mail received by SMTP but not for emails sent locally, using sendmail.
autoreply.py
could be easily adapted to do other things with the original email like extracting information or storing attachments.
The following sections provide a step-by-step guide on how to set up autoreply.py
and Postfix to send auto-replies.
One of our clients had a complex email infrastructure and they wanted a script that would trigger auto-replies when emails sent to some specific addresses entered one of their MTAs. Normally, these auto-replies would have been configured at an MDA/mailbox level.
The MTA in question was Postfix and it relayed all the emails to another SMTP server which they couldn't/wanted to configure differently.
After some consideration, it was deemed viable to use an after-queue content filter in Postfix to achieve this.
As the email addresses that would need to auto-reply would change over time, as well as the subjects and wording of the auto-reply emails, we decided to use a JSON file to store that information which could be changed without having to edit the script.
This section is somehow optional but please note that, as per Postfix's FILTER documentation, filter scripts should be run using a separate account, as these are handling potentially malicious emails. To quote their documentation, do not use "nobody", and most certainly do not use "root" or "postfix".
- Add autoreply user with home directory /opt/autoreply and nologin.
sudo useradd -d /opt/autoreply -s /usr/sbin/nologin autoreply
- Create autoreply's home directory.
sudo mkdir /opt/autoreply
- Change autoreply's home directory ownership.
sudo chown autoreply:autoreply /opt/autoreply
- Restrict access to autoreply's home directory.
sudo chmod 700 /opt/autoreply
- Change to autoreply user.
sudo su - autoreply -s /bin/bash
- Download
autoreply.py
.
wget https://github.com/innovara/autoreply/raw/master/autoreply.py
- Change permissions.
chmod 700 autoreply.py
- Run ./autoreply.py -j to generate ~/autoreply.json.
./autoreply.py -j
- Edit autoreply.json.
nano autoreply.json
{
"logging": false,
"SMTP": "localhost",
"port": 25,
"starttls": false,
"smtpauth": false,
"username": "user",
"password": "pass",
"autoreply": [
{
"email": "foo@bar",
"from": "Foo Bar <foo@bar>",
"reply-to": "foo@bar",
"subject": "Subject here",
"body": "Email body here",
"html": false,
"_comment": "If you set html to true, set body to the full path of your html file"
}
]
}
Explanation:
- logging: true or false to enable/disable logging to ~/autoreply.log.
- SMTP: server that will send the auto-reply emails.
- port: SMTP port of the server.
- starttls: true to enable STARTTLS.
- smtpauth: true if authentication is required.
- username: SMTP user.
- password: SMTP user's password.
- email: email address that would trigger an auto-reply.
- from: email address that you want to show the auto-reply coming from.
- reply-to: the reply-to email address the auto-reply receivers will see. Useful when using noreply@...
- If you want to add more email addresses, the JSON file would look something like this.
{
"logging": false,
"SMTP": "localhost",
"port": 25,
"starttls": false,
"smtpauth": false,
"username": "user",
"password": "pass",
"autoreply": [
{
"email": "foo@bar",
"from": "Foo Bar <foo@bar>",
"reply-to": "foo@bar",
"subject": "Subject here",
"body": "/path/to/email.html",
"html": true,
"_comment": "If you set html to true, set body to the full path of your html file"
},
{
"email": "foo2@bar",
"from": "Foo Bar <foo@bar>",
"reply-to": "foo2@bar",
"subject": "Subject here",
"body": "Email body here",
"html": false,
"_comment": "If you set html to true, set body to the full path of your html file"
}
]
}
- If you want to create an email file for testing, use
./autoreply.py -t
and edittest.txt
to changeFrom
,To
andReply-to
accordingly.
./autoreply.py -t
nano test.txt
- Run a test from the command line.
./autoreply.py from@bar to@bar < test.txt
At this point, the recipient of the test email should have received the test email from the sender, and the sender an auto-reply message from the recipient.
- Exit autoreply shell
exit
Now, you have to edit the configuration of the Postfix server to pipe emails to the script.
You could pipe all the emails to autoreply.py
, but the script would unnecessarily handle a number of emails that would not trigger an auto-reply.
To avoid emails out of the scope of autoreply.py
being piped to it, we use check_recipient_access
under smtpd_recipient_restrictions
in main.cf
.
Bear in mind that, if there are multiple recipients, Postfix will pipe the email as long as at least one of them is in the lookup table.
- Create a Postfix lookup table input file.
sudo nano /etc/postfix/autoreply
- Add one line per recipient:
foo@bar FILTER autoreply:dummy
- Create its corresponding Postfix lookup table.
sudo postmap /etc/postfix/autoreply
- Back up
main.cf
.
sudo cp /etc/postfix/main.{cf,cf.bak}
- Edit
main.cf
.
sudo nano /etc/postfix/main.cf
- Add the new lookup table as the first item in
smtpd_recipient_restrictions
.
smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/autoreply
- Back up
master.cf
.
sudo cp /etc/postfix/master.{cf,cf.bak}
- Edit
master.cf
.
sudo nano /etc/postfix/master.cf
- Add the autoreply pipe at the end of the file. Edit user and script path if you are not following the instructions regarding system configuration.
# autoreply pipe
autoreply unix - n n - - pipe
flags= user=autoreply null_sender=
argv=/opt/autoreply/autoreply.py ${sender} ${recipient}
- Restart Postfix.
sudo systemctl restart postfix
You are ready to go. If everything went well, when Postfix receives emails that are addressed to your target auto-reply recipients, it will pass them to autoreply.py
and the script will send the auto-reply email according to your configuration.