Skip to content

Instantly share code, notes, and snippets.

@nguyenkims
Last active July 15, 2019 08:09
Show Gist options
  • Save nguyenkims/018b2deec1e5c70240373f0a549cc39a to your computer and use it in GitHub Desktop.
Save nguyenkims/018b2deec1e5c70240373f0a549cc39a to your computer and use it in GitHub Desktop.
Example on how to create an external Postfix script in python
#!/usr/bin/env python3
"""
An example on how to create a external Postfix script in python. By the end of this small tutorial,
"postmap -q 200 tcp:127.0.0.1:10444" should return "success".
This is not much 😅 but serves as an example on how to create Python script for Postfix.
I haven't found any snippet on this topic and ended up creating a toy script.
This is based on http://dozzie.jarowit.net/blog-archive/2013/11/13/postfix-sender-rewriting-scheme/
# Steps:
1) Add this to the end of /etc/postfix/master.cf
===
## Test Python external script
127.0.0.1:10444 inet n n n - 8 spawn
user=ubuntu
argv=/tmp/postfix.py
===
The command says is each time postfix receives a query at 127.0.0.1:10444, it will "spawn" the
script /tmp/postfix.py, running as "ubuntu" user. I need "ubuntu" as the script needs to be able to write to
"/tmp/postfix.log" and it seems "nobody" user cannot do that I think :).
"Spawn" is not efficient and not adapted for production.
2) Create in /tmp/postfix.py this script
3) Now "postmap -q 200 tcp:127.0.0.1:10444" should return "success"
4) (Future) If you decide to implement SRS using Python following this pattern, you can enable this by adding
===
sender_canonical_classes = envelope_sender
sender_canonical_maps = tcp:localhost:10444
====
into /etc/postfix/main.cf
"""
import logging
import sys
# as the script is launched by postfix master,
# we write the log to a file in order to know what's going on
logging.basicConfig(
level=logging.DEBUG,
filename="/tmp/postfix.log",
filemode="a",
format="%(asctime)s - %(name)s - %(levelname)s - %(process)d - %(module)s:%(lineno)d - %(funcName)s - %(message)s",
)
line = sys.stdin.readline()
if line:
logging.debug("line %s.", line)
# remove the trailing \n if any
line = line.rstrip()
logging.debug("line:%s %s", line, len(line))
# postfix sends something like "get {data}" and expects to receive the the response
# following the protocol on http://www.postfix.org/tcp_table.5.html
data = line.replace("get ", "")
logging.debug("email is %s %s %s.", data, len(data), type(data))
if data == "500":
logging.debug("handle 500")
print("500 500error")
elif data == "400":
logging.debug("handle 400")
print("400 400error")
elif data == "200":
logging.debug("handle 200")
print("200 success")
else:
logging.error("Cannot handle %s", data)
logging.debug("End")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment