diff options
Diffstat (limited to 'proto/SMTPD_PROXY_README.html')
-rw-r--r-- | proto/SMTPD_PROXY_README.html | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/proto/SMTPD_PROXY_README.html b/proto/SMTPD_PROXY_README.html new file mode 100644 index 0000000..83ce3eb --- /dev/null +++ b/proto/SMTPD_PROXY_README.html @@ -0,0 +1,438 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Before-Queue Content Filter </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<link rel='stylesheet' type='text/css' href='postfix-doc.css'> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Before-Queue Content Filter </h1> + +<hr> + +<h2>WARNING </h2> + +<p> The before-queue content filtering feature described in this +document limits the amount of mail that a site can handle. See the +"<a href="#pros_cons">Pros and Cons</a>" section below for details. +</p> + +<h2>The Postfix before-queue content filter feature</h2> + +<p> As of version 2.1, the Postfix SMTP server can forward all +incoming mail to a content filtering proxy server that inspects all +mail BEFORE it is stored in the Postfix mail queue. It is roughly +equivalent in capabilities to the approach described in MILTER_README, +except that the latter uses a dedicated protocol instead of SMTP. + +<p> The before-queue content filter is meant to be used as follows: </p> + +<blockquote> + +<table> + +<tr> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Internet </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server</a> + </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <b>Before</b> <b>queue</b> <b>filter</b> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server</a> + </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="cleanup.8.html">Postfix cleanup + server</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Postfix queue </td> + + <td align="center" valign="middle" width="5%"> <tt> -< </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtp.8.html">smtp</a><br> <a + href="local.8.html">local</a><br> <a + href="virtual.8.html">virtual</a> </td> + +</tr> + +</table> + +</blockquote> + +<p> The before-queue content filter is not to be confused with the +approach described in the FILTER_README document, where mail is +filtered AFTER it is stored in the Postfix mail queue. </p> + +<p> This document describes the following topics: </p> + +<ul> + +<li><a href="#principles">Principles of operation</a> + +<li><a href="#pros_cons">Pros and cons of before-queue content filtering</a> + +<li><a href="#config">Configuring the Postfix SMTP pass-through +proxy feature</a> + +<li><a href="#parameters">Configuration parameters</a> + +<li><a href="#protocol">How Postfix talks to the before-queue content +filter</a> + +</ul> + +<h2><a name="principles">Principles of operation</a></h2> + +<p> As shown in the diagram above, the before-queue filter sits +between two Postfix SMTP server processes. </p> + +<ul> + +<li> <p> The before-filter Postfix SMTP server accepts connections from the +Internet and does the usual relay access control, SASL authentication, +TLS negotiation, +RBL lookups, rejecting non-existent sender or recipient addresses, +etc. </p> + +<li> <p> The before-queue filter receives unfiltered mail content from +Postfix and does one of the following: </p> + +<ol> + + <li> <p> Re-inject the mail back into Postfix via SMTP, perhaps + after changing its content and/or destination. </p> + + <li> <p> Discard or quarantine the mail. </p> + + <li> <p> Reject the mail by sending a suitable SMTP status code + back to Postfix. Postfix passes the status back to the remote + SMTP client. This way, Postfix does not have to send a bounce + message. </p> + +</ol> + +<li> <p>The after-filter Postfix SMTP server receives mail from the +content filter. From then on Postfix processes the mail as usual. </p> + +</ul> + +<p> The before-queue content filter described here works just like +the after-queue content filter described in the FILTER_README +document. In many cases you can use the same software, within the +limitations as discussed in the "<a href="#pros_cons">Pros and +Cons</a>" section below. </p> + +<h2><a name="pros_cons">Pros and cons of before-queue content +filtering</a></h2> + +<ul> + +<li> <p> Pro: Postfix can reject mail before the incoming SMTP mail +transfer completes, so that Postfix does not have to send rejected +mail back to the sender (which is usually forged anyway). Mail +that is not accepted remains the responsibility of the remote SMTP +client. </p> + +<li> <p> Con: The smtpd(8) service before the smtpd_proxy_filter +cannot support features that involve header or body access, or that +involve queue file manipulation (i.e., anything that involves +processing by the cleanup(8) service). </p> + +<ul> + +<li> <p> No support for HOLD actions in Postfix smtpd access(5) +restrictions. </p> + +<li> <p> No support for smtpd_milters features that involve message +header or body content. </p> + +<li> <p> No support for receive_override_options. + +</ul> + +<p> Instead, specify those features with the smtpd(8) service behind +the smtpd_proxy_filter. In some cases, it may be possible to combine +a before-filter PREPEND action that emits a unique pattern (for +example containing the MTA domain name), with an after-filter +header_checks action that does what you want, and with an +smtp_header_checks IGNORE action that deletes the prepended header +from transit mail. </p> + +<li> <p> Con: The remote SMTP client expects an SMTP reply within +a deadline. As the system load increases, fewer and fewer CPU +cycles remain available to answer within the deadline, and eventually +you either have to stop accepting mail or you have to stop filtering +mail. It is for this reason that the before-queue content filter +limits the amount of mail that a site can handle. </p> + +<li> <p> Con: Content filtering software can use lots of memory +resources. You have to reduce the number of simultaneous content +filter processes so that a burst of mail will not drive your system +into the ground. </p> + +<ul> + +<li> <p> With Postfix versions 2.7 and later, SMTP clients will +experience an increase in the delay between the time the client +sends "end-of-message" and the time the Postfix SMTP server replies +(here, the number of before-filter SMTP server processes can be +larger than the number of filter processes). </p> + +<li> <p> With Postfix versions before 2.7, SMTP clients will +experience an increase in the delay before they can receive service +(here, the number of before-filter SMTP server processes is always +equal to the number of filter processes). </p> + +</ul> + +</ul> + +<h2><a name="config">Configuring the Postfix SMTP pass-through +proxy feature</a></h2> + +<p> In the following example, the before-filter Postfix SMTP server +gives mail to a content filter that listens on localhost port 10025. +The after-filter Postfix SMTP server receives mail from the content +filter via localhost port 10026. From then on mail is processed as +usual. </p> + +<p> The content filter itself is not described here. You can use +any filter that is SMTP enabled. For non-SMTP capable content +filtering software, Bennett Todd's SMTP proxy implements a nice +Perl-based framework. See: +https://web.archive.org/web/20151022025756/http://bent.latency.net/smtpprox/ +or https://github.com/jnorell/smtpprox/ </p> + +<blockquote> + +<table border="0"> + +<tr> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Internet </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server on + port 25</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> filter on localhost port 10025 </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server on + localhost port 10026</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="cleanup.8.html">Postfix cleanup + server</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Postfix incoming queue </td> + +</tr> + +</table> + +</blockquote> + +<p> This is configured by editing the master.cf file: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + # ============================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ============================================================= + # + # Before-filter SMTP server. Receive mail from the network and + # pass it to the content filter on localhost port 10025. + # + smtp inet n - n - 20 smtpd + -o smtpd_proxy_filter=127.0.0.1:10025 + -o smtpd_client_connection_count_limit=10 + # Postfix 2.7 and later performance feature. + # -o smtpd_proxy_options=speed_adjust + # + # After-filter SMTP server. Receive mail from the content filter + # on localhost port 10026. + # + 127.0.0.1:10026 inet n - n - - smtpd + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + # Postfix 2.10 and later: specify empty smtpd_relay_restrictions. + -o smtpd_relay_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions= + -o mynetworks=127.0.0.0/8 + -o receive_override_options=no_unknown_recipient_checks +</pre> +</blockquote> + +<p> Note: do not specify spaces around the "=" or "," characters. </p> + +<p> The before-filter SMTP server entry is a modified version of the +default Postfix SMTP server entry that is normally configured at +the top of the master.cf file: </p> + +<ul> + + <li> <p> The number of SMTP sessions is reduced from the default + 100 to only 20. This prevents a burst of mail from running your + system into the ground with too many content filter processes. </p> + + <li> <p> The "-o smtpd_client_connection_count_limit=10" prevents + one SMTP client from using up all 20 SMTP server processes. + This limit is not necessary if you receive all mail from a + trusted relay host. </p> + + <p> Note: this setting is available in Postfix version 2.2 and + later. Earlier Postfix versions will ignore it. </p> + + <li> <p> The "-o smtpd_proxy_filter=127.0.0.1:10025" tells the + before-filter SMTP server that it should give incoming mail to + the content filter that listens on localhost TCP port 10025. + + <li> <p> The "-o smtpd_proxy_options=speed_adjust" tells the + before-filter SMTP server that it should receive an entire email + message before it connects to a content filter. This reduces + the number of simultaneous filter processes. </p> + + <p> NOTE 1: When this option is turned on, a content filter must + not <i>selectively</i> reject recipients of a multi-recipient + message. Rejecting all recipients is OK, as is accepting all + recipients. </p> + + <p> NOTE 2: This feature increases the minimum amount of free + queue space by $message_size_limit. The extra space is needed + to save the message to a temporary file. </p> + + <li> <p> Postfix ≥ 2.3 supports both TCP and UNIX-domain filters. + The above filter could be specified as "inet:127.0.0.1:10025". + To specify a UNIX-domain filter, specify "unix:<i>pathname</i>". + A relative pathname is interpreted relative to the Postfix queue + directory. </p> + +</ul> + +<p> The after-filter SMTP server is a new master.cf entry: </p> + +<ul> + + <li> <p> The "127.0.0.1:10026" makes the after-filter SMTP + server listen + on the localhost address only, without exposing it to the + network. NEVER expose the after-filter SMTP server to the + Internet :-) </p> + + <li> <p> The "-o smtpd_authorized_xforward_hosts=127.0.0.0/8" + allows the after-filter SMTP server to receive remote SMTP + client information from the before-filter SMTP server, so that + the after-filter Postfix daemons log the remote SMTP client + information instead of logging localhost[127.0.0.1]. </p> + + <li> <p> The other after-filter SMTP server settings avoid + duplication of work that is already done in the "before filter" + SMTP server. </p> + +</ul> + +<p> By default, the filter has 100 seconds to do its work. If it +takes longer then Postfix gives up and reports an error to the +remote SMTP client. You can increase this time limit (see the <a href="#parameters">"Configuration +parameters"</a> section below) but doing so is pointless because you +can't control when the remote SMTP client times out. </p> + +<h2><a name="parameters">Configuration parameters</a></h2> + +<p> Parameters that control proxying: </p> + +<ul> + +<li> <p> smtpd_proxy_filter (syntax: host:port): The host and TCP +port of the before-queue content filter. When no host or host: +is specified here, localhost is assumed. </p> + +<li> <p> smtpd_proxy_timeout (default: 100s): Timeout for connecting +to the before-queue content filter and for sending and receiving +commands and data. All proxy errors are logged to the maillog +file. For privacy reasons, all the remote SMTP client sees is "451 +Error: queue file write error". It would not be right to disclose +internal details to strangers. </p> + +<li> <p> smtpd_proxy_ehlo (default: $myhostname): The hostname to +use when sending an EHLO command to the before-queue content filter. +</p> + +</ul> + +<h2><a name="protocol">How Postfix talks to the before-queue content +filter</a></h2> + +<p> The before-filter Postfix SMTP server connects to the content +filter, delivers one message, and disconnects. While sending mail +into the content filter, Postfix speaks ESMTP but uses no command +pipelining. Postfix generates its own EHLO, XFORWARD (for logging +the remote client IP address instead of localhost[127.0.0.1]), DATA +and QUIT commands, and forwards unmodified copies of all the MAIL +FROM and RCPT TO commands that the before-filter Postfix SMTP server +didn't reject itself. +Postfix sends no other SMTP commands. </p> + +<p> The content filter should accept the same MAIL FROM and RCPT +TO command syntax as the before-filter Postfix SMTP server, and +should forward the commands without modification to the after-filter +SMTP server. If the content filter or after-filter SMTP server +does not support all the ESMTP features that the before-filter +Postfix SMTP server supports, then the missing features must be +turned off in the before-filter Postfix SMTP server with the +smtpd_discard_ehlo_keywords parameter. </p> + +<p> When the filter rejects content, it should send a negative SMTP +response back to the before-filter Postfix SMTP server, and it +should abort the connection with the after-filter Postfix SMTP +server without completing the SMTP conversation with the after-filter +Postfix SMTP server. </p> + +</body> + +</html> |