Last active
July 15, 2019 08:09
-
-
Save nguyenkims/018b2deec1e5c70240373f0a549cc39a to your computer and use it in GitHub Desktop.
Example on how to create an external Postfix script in python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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