postprox - minimal Postfix SMTP proxy
postprox HOST:PORT [-c CMD] [-d DIR]
[-t SEC] [-rv] [-l [IP:]PORT]
postprox reads SMTP commands on standard input and passes them on to the specified mail server unchanged, except for the DATA portion. Output from the specified mail server is passed back to standard output. The DATA portion from the input mail server (stdin) is spooled to a temporary file so that COMMAND can be run on it; if COMMAND exits with a non-zero exit status, its standard error is passed as an SMTP error to the input SMTP server (on stdout) and the connection to the output SMTP server is aborted with a QUIT.
postprox is intended to be used in a postfix(1) configuration as a before-queue or after-queue content filter.
See the EXAMPLE CONFIGURATION section for an example of how to use postprox as a before-queue content filter.
The postprox options are listed below.
When COMMAND is run, the environment variable EMAIL will be set to the filename of the email to be processed, and the environment variable OUTFILE will be set to the filename of an existing empty file which the filter can optionally put a modified version of the message into.
See the ENVIRONMENT VARIABLES section below for more details.
The exit status of COMMAND determines whether the email will be passed through or rejected. An exit status of 0 means to pass the email through, 1 means to reject it - the last line of COMMAND's standard error output will be used as the error text, and unless it starts with a 3-digit number and a space, it will be prefixed with 554 (SMTP hard error). An exit code of 2 or more means the filter failed to run correctly.
If the contents of OUTFILE are left alone by COMMAND then an exit status of 0 means to pass the email through as it was received. If OUTFILE contains anything at all, then an exit status of 0 will cause the contents of OUTFILE to be passed through instead of the original email.
This configuration is based on steps outlined in the file SMTPD_PROXY_README included with postfix(1). It can be read online here:
First, set up a user to run the filter as, such as filter.
Next, create a script or program which can be run on an email (the filename of the email to examine will be in the environment variable EMAIL), and which will exit with status 0 if the email is to be accepted, 1 if it is to be rejected, or anything else if there was a problem with an aspect of the filter itself. The filter script can also output an SMTP error on standard error if you would like customised error responses.
For instance, a script to scan all incoming email with clamdscan(1) would look like this:
Now you need to reconfigure postfix(1). Add the following to /etc/postfix/main.cf:
Now add the following to the bottom of /etc/postfix/master.cf:
# After-filter SMTP server. Receive mail from the content filter
# on localhost port 10026.
127.0.0.1:10026 inet n - n - - smtpd
Finally, do postfix reload and watch the mail logs to ensure that it's working. Send a few test emails to satisfy yourself that the system is still processing mail correctly.
Remember to replace COMMAND in the above example with the full path to your filtering script. The script must be executable by the filter user.
The number just before spawn in the first line of the addition to master.cf is the maximum number of proxy processes to spawn. Adjust this according to the needs of your system.
See the documentation for master(5) for further details of the format of /etc/postfix/master.cf.
The following environment variables are available to any filter command:
Note that only the EMAIL and OUTFILE variables can be trusted, as these are generated by postprox. Everything else is supplied by a potentially hostile remote host, so should be used with care. If your script uses the shell at all, make sure you always fully quote these variables.
Also note that everything but EMAIL and OUTFILE will be truncated to a maximum of 99 characters.
Project home page:
If you find any bugs, please contact the author, either by email or by using the contact form on the web site.
postfix(1), postconf(5), master(5)
This is free software, distributed under the ARTISTIC license.