summaryrefslogtreecommitdiffstats
path: root/html/POSTSCREEN_README.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--html/POSTSCREEN_README.html1214
1 files changed, 1214 insertions, 0 deletions
diff --git a/html/POSTSCREEN_README.html b/html/POSTSCREEN_README.html
new file mode 100644
index 0000000..e6f1321
--- /dev/null
+++ b/html/POSTSCREEN_README.html
@@ -0,0 +1,1214 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<head>
+
+<title>Postfix Postscreen Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Postscreen Howto</h1>
+
+<hr>
+
+<h2> <a name="intro">Introduction</a> </h2>
+
+<p> This document describes features that are available in Postfix
+3.6 and later. See <a href="POSTSCREEN_3_5_README.html">
+POSTSCREEN_3_5_README.html</a> for Postfix versions 2.8 - 3.5. </p>
+
+<p> The Postfix <a href="postscreen.8.html">postscreen(8)</a> daemon provides additional protection
+against mail server overload. One <a href="postscreen.8.html">postscreen(8)</a> process handles
+multiple inbound SMTP connections, and decides which clients may
+talk to a Postfix SMTP server process. By keeping spambots away,
+<a href="postscreen.8.html">postscreen(8)</a> leaves more SMTP server processes available for
+legitimate clients, and delays the onset of <a
+href="STRESS_README.html">server overload</a> conditions. </p>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> should not be used on SMTP ports that receive
+mail from end-user clients (MUAs). In a typical deployment,
+<a href="postscreen.8.html">postscreen(8)</a> handles the MX service on TCP port 25, while MUA
+clients submit mail via the submission service on TCP port 587 which
+requires client authentication. Alternatively, a site could set up
+a dedicated, non-postscreen, "port 25" server that provides submission
+service and client authentication, but no MX service. </p>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> maintains a temporary allowlist for clients that
+pass its tests; by allowing allowlisted clients to skip tests,
+<a href="postscreen.8.html">postscreen(8)</a> minimizes its impact on legitimate email traffic.
+</p>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> is part of a multi-layer defense. <p>
+
+<ul>
+
+<li> <p> As the first layer, <a href="postscreen.8.html">postscreen(8)</a> blocks connections from
+zombies and other spambots that are responsible for about 90% of
+all spam. It is implemented as a single process to make this defense
+as inexpensive as possible. </p>
+
+<li> <p> The second layer implements more complex SMTP-level access
+checks with <a href="SMTPD_ACCESS_README.html">Postfix SMTP servers</a>,
+<a href="SMTPD_POLICY_README.html">policy daemons</a>, and
+<a href="MILTER_README.html">Milter applications</a>. </p>
+
+<li> <p> The third layer performs light-weight content inspection
+with the Postfix built-in <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a>. This can
+block unacceptable attachments such as executable programs, and
+worms or viruses with easy-to-recognize signatures. </p>
+
+<li> <p> The fourth layer provides heavy-weight content inspection
+with external content filters. Typical examples are <a
+href="http://www.ijs.si/software/amavisd/">Amavisd-new</a>, <a
+href="http://spamassassin.apache.org/">SpamAssassin</a>, and <a
+href="MILTER_README.html">Milter applications</a>. </p>
+
+</ul>
+
+<p> Each layer reduces the spam volume. The general strategy is to
+use the less expensive defenses first, and to use the more expensive
+defenses only for the spam that remains. </p>
+
+<p> Topics in this document: </p>
+
+<ul>
+
+<li> <a href="#intro">Introduction</a>
+
+<li> <a href="#basic">The basic idea behind postscreen(8)</a>
+
+<li> <a href="#general"> General operation </a>
+
+<li> <a href="#quick">Quick tests before everything else</a>
+
+<li> <a href="#before_220"> Tests before the 220 SMTP server greeting </a>
+
+<li> <a href="#after_220">Tests after the 220 SMTP server greeting</a>
+
+<li> <a href="#other_error">Other errors</a>
+
+<li> <a href="#victory">When all tests succeed</a>
+
+<li> <a href="#config"> Configuring the postscreen(8) service</a>
+
+<li> <a href="#historical"> Historical notes and credits </a>
+
+</ul>
+
+<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2>
+
+<p> Most email is spam, and most spam is sent out by zombies (malware
+on compromised end-user computers). Wietse expects that the zombie
+problem will get worse before things improve, if ever. Without a
+tool like <a href="postscreen.8.html">postscreen(8)</a> that keeps the zombies away, Postfix would be
+spending most of its resources not receiving email. </p>
+
+<p> The main challenge for <a href="postscreen.8.html">postscreen(8)</a> is to make an is-a-zombie
+decision based on a single measurement. This is necessary because
+many zombies try to fly under the radar and avoid spamming the same
+site repeatedly. Once <a href="postscreen.8.html">postscreen(8)</a> decides that a client is
+not-a-zombie, it allowlists the client temporarily to avoid further
+delays for legitimate mail. </p>
+
+<p> Zombies have challenges too: they have only a limited amount
+of time to deliver spam before their IP address becomes denylisted.
+To speed up spam deliveries, zombies make compromises in their SMTP
+protocol implementation. For example, they speak before their turn,
+or they ignore responses from SMTP servers and continue sending
+mail even when the server tells them to go away. </p>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> uses a variety of measurements to recognize
+zombies. First, <a href="postscreen.8.html">postscreen(8)</a> determines if the remote SMTP client
+IP address is denylisted. Second, <a href="postscreen.8.html">postscreen(8)</a> looks for protocol
+compromises that are made to speed up delivery. These are good
+indicators for making is-a-zombie decisions based on single
+measurements. </p>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> does not inspect message content. Message content
+can vary from one delivery to the next, especially with clients
+that (also) send legitimate email. Content is not a good indicator
+for making is-a-zombie decisions based on single measurements,
+and that is the problem that <a href="postscreen.8.html">postscreen(8)</a> is focused on. </p>
+
+<h2> <a name="general"> General operation </a> </h2>
+
+<p> For each connection from an SMTP client, <a href="postscreen.8.html">postscreen(8)</a> performs
+a number of tests
+in the order as described below. Some tests introduce a delay of
+a few seconds. <a href="postscreen.8.html">postscreen(8)</a> maintains a temporary allowlist for
+clients that pass its tests; by allowing allowlisted clients to
+skip tests, <a href="postscreen.8.html">postscreen(8)</a> minimizes its impact on legitimate email
+traffic. </p>
+
+<p> By default, <a href="postscreen.8.html">postscreen(8)</a> hands off all connections to a Postfix
+SMTP server process after logging its findings. This mode is useful
+for non-destructive testing. </p>
+
+<p> In a typical production setting, <a href="postscreen.8.html">postscreen(8)</a> is configured
+to reject mail from clients that fail one or more tests, after
+logging the helo, sender and recipient information. </p>
+
+<p> Note: <a href="postscreen.8.html">postscreen(8)</a> is not an SMTP proxy; this is intentional.
+The purpose is to keep zombies away from Postfix, with minimal
+overhead for legitimate clients. </p>
+
+<h2> <a name="quick">Quick tests before everything else</a> </h2>
+
+<p> Before engaging in SMTP-level tests. <a href="postscreen.8.html">postscreen(8)</a> queries a
+number of local deny and allowlists. These tests speed up the
+handling of known clients. </p>
+
+<ul>
+
+<li> <a href="#perm_allow_deny"> Permanent allow/denylist test </a>
+
+<li> <a href="#temp_allow"> Temporary allowlist test </a>
+
+<li> <a href="#allow_veto"> MX Policy test </a>
+
+</ul>
+
+<h3> <a name="perm_allow_deny"> Permanent allow/denylist test </a> </h3>
+
+<p> The <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> parameter (default: <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>)
+specifies a permanent access list for SMTP client IP addresses. Typically
+one would specify something that allowlists local networks, followed
+by a CIDR table for selective allow- and denylisting. </p>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
+ <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
+ # Rules are evaluated in the order as specified.
+ # Denylist 192.168.* except 192.168.0.1.
+ 192.168.0.1 permit
+ 192.168.0.0/16 reject
+</pre>
+
+<p> See the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> manpage documentation for more
+details. </p>
+
+<p> When the SMTP client address matches a "permit" action,
+<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
+</p>
+
+<blockquote>
+<pre>
+<b>ALLOWLISTED</b> <i>[address]:port</i>
+</pre>
+</blockquote>
+
+<blockquote> <p> Use the <a href="postconf.5.html#respectful_logging">respectful_logging</a> configuration parameter to
+select a deprecated form of this logging. </p> </blockquote>
+
+<p> The allowlist action is not configurable: immediately hand off the
+connection to a Postfix SMTP server process. </p>
+
+<p> When the SMTP client address matches a "reject" action,
+<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
+</p>
+
+<blockquote>
+<pre>
+<b>DENYLISTED</b> <i>[address]:port</i>
+</pre>
+</blockquote>
+
+<blockquote> <p> Use the <a href="postconf.5.html#respectful_logging">respectful_logging</a> configuration parameter to
+select a deprecated form of this logging. </p> </blockquote>
+
+<p> The <a href="postconf.5.html#postscreen_denylist_action">postscreen_denylist_action</a> parameter specifies the action
+that is taken next. See "<a href="#fail_before_220">When tests
+fail before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="temp_allow"> Temporary allowlist test </a> </h3>
+
+<p> The <a href="postscreen.8.html">postscreen(8)</a> daemon maintains a <i>temporary</i>
+allowlist for SMTP client IP addresses that have passed all
+the tests described below. The <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> parameter
+specifies the location of the temporary allowlist. The
+temporary allowlist is not used for SMTP client addresses
+that appear on the <i>permanent</i> access list. </p>
+
+<p> By default the temporary allowlist is not shared with other
+<a href="postscreen.8.html">postscreen(8)</a> daemons. See
+<a href="#temp_allow_sharing"> Sharing
+the temporary allowlist </a> below for alternatives. </p>
+
+<p> When the SMTP client address appears on the temporary
+allowlist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port
+number as: </p>
+
+<pre>
+ <b>PASS OLD</b> <i>[address]:port</i>
+</pre>
+
+<p> The action is not configurable: immediately hand off the
+connection to a Postfix SMTP server process. The client is
+excluded from further tests until its temporary allowlist
+entry expires, as controlled with the postscreen_*_ttl
+parameters. Expired entries are silently renewed if possible. </p>
+
+<h3> <a name="allow_veto"> MX Policy test </a> </h3>
+
+<p> When the remote SMTP client is not on the static access list
+or temporary allowlist, <a href="postscreen.8.html">postscreen(8)</a> can implement a number of
+allowlist tests, before it grants the client a temporary allowlist
+status that allows it to talk to a Postfix SMTP server process. </p>
+
+<p> When <a href="postscreen.8.html">postscreen(8)</a> is configured to monitor all primary and
+backup MX addresses, it can refuse to allowlist clients that connect
+to a backup MX address only (an old spammer trick to take advantage
+of backup MX hosts with weaker anti-spam policies than primary MX
+hosts). </p>
+
+<blockquote> <p> NOTE: The following solution is for small sites.
+Larger sites would have to share the <a href="postscreen.8.html">postscreen(8)</a> cache between
+primary and backup MTAs, which would introduce a common point of
+failure. </p> </blockquote>
+
+<ul>
+
+<li> <p> First, configure the host to listen on both primary and
+backup MX addresses. Use the appropriate <tt>ifconfig</tt> or <tt>ip</tt>
+command for the local operating system, or update the appropriate
+configuration files and "refresh" the network protocol stack. </p>
+
+<p> <p> Second, configure Postfix to listen on the new IP address
+(this step is needed when you have specified <a href="postconf.5.html#inet_interfaces">inet_interfaces</a> in
+<a href="postconf.5.html">main.cf</a>). </p>
+
+<li> <p> Then, configure <a href="postscreen.8.html">postscreen(8)</a> to deny the temporary allowlist
+status on the backup MX address(es). An example for Wietse's
+server is: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_allowlist_interfaces">postscreen_allowlist_interfaces</a> = !168.100.189.8 <a href="DATABASE_README.html#types">static</a>:all
+</pre>
+
+<p> Translation: allow clients to obtain the temporary allowlist
+status on all server IP addresses except 168.100.189.8, which is a
+backup MX address. </p>
+
+</ul>
+
+<p> When a non-allowlisted client connects the backup MX address,
+<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
+</p>
+
+<blockquote> <pre>
+<b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b>
+<b>ALLOWLIST VETO</b> <i>[address]:port</i>
+</pre> </blockquote>
+
+<blockquote> <p> Use the <a href="postconf.5.html#respectful_logging">respectful_logging</a> configuration parameter to
+select a deprecated form of this logging. </p> </blockquote>
+
+<p> Translation: the client at <i>[address]:port</i> connected to
+the backup MX address 168.100.189.8 while it was not allowlisted.
+The client will not be granted the temporary allowlist status, even
+if passes all the allowlist tests described below. </p>
+
+<h2> <a name="before_220"> Tests before the 220 SMTP server greeting </a> </h2>
+
+<p> The <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> parameter specifies a short time
+interval before the "220 <i>text</i>..." server greeting, where
+<a href="postscreen.8.html">postscreen(8)</a> can run a number of tests in parallel. </p>
+
+<p> When a good client passes these tests, and no "<a
+href="#after_220">deep protocol tests</a>"
+are configured, <a href="postscreen.8.html">postscreen(8)</a>
+adds the client to the temporary allowlist and hands off the "live"
+connection to a Postfix SMTP server process. The client can then
+continue as if <a href="postscreen.8.html">postscreen(8)</a> never even existed (except of course
+for the short <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> delay). </p>
+
+<ul>
+
+<li> <a href="#pregreet"> Pregreet test </a>
+
+<li> <a href="#dnsbl"> DNS Allow/denylist test </a>
+
+<li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a>
+
+</ul>
+
+<h3> <a name="pregreet"> Pregreet test </a> </h3>
+
+<p> The SMTP protocol is a classic example of a protocol where the
+server speaks before the client. <a href="postscreen.8.html">postscreen(8)</a> detects zombies
+that are in a hurry and that speak before their turn. This test is
+enabled by default. </p>
+
+<p> The <a href="postconf.5.html#postscreen_greet_banner">postscreen_greet_banner</a> parameter specifies the <i>text</i>
+portion of a "220-<i>text</i>..." teaser banner (default: $<a href="postconf.5.html#smtpd_banner">smtpd_banner</a>).
+Note that this becomes the first part of a multi-line server greeting.
+The <a href="postscreen.8.html">postscreen(8)</a> daemon sends this before the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a>
+timer is started. The purpose of the teaser banner is to confuse
+zombies so that they speak before their turn. It has no effect on
+SMTP clients that correctly implement the protocol. </p>
+
+<p> To avoid problems with poorly-implemented SMTP engines in network
+appliances or network testing tools, either exclude them from all
+tests with the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> feature or else specify
+an empty teaser banner: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ # Exclude broken clients by allowlisting. Clients in <a href="postconf.5.html#mynetworks">mynetworks</a>
+ # should always be allowlisted.
+ <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
+ <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
+ 192.168.254.0/24 permit
+</pre>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ # Disable the teaser banner (try allowlisting first if you can).
+ <a href="postconf.5.html#postscreen_greet_banner">postscreen_greet_banner</a> =
+</pre>
+
+<p> When an SMTP client sends a command before the
+<a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> time has elapsed, <a href="postscreen.8.html">postscreen(8)</a> logs this as:
+</p>
+
+<pre>
+ <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
+</pre>
+
+<p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
+bytes before its turn to speak. This happened <i>time</i> seconds
+after the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> timer was started. The <i>text</i>
+is what the client sent (truncated to 100 bytes, and with non-printable
+characters replaced with C-style escapes such as \r for carriage-return
+and \n for newline). </p>
+
+<p> The <a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> parameter specifies the action that
+is taken next. See "<a href="#fail_before_220">When tests fail
+before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="dnsbl"> DNS Allow/denylist test </a> </h3>
+
+<p> The <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter (default: empty) specifies
+a list of DNS blocklist servers with optional filters and weight
+factors (positive weights for denylisting, negative for allowlisting).
+These servers will be queried in parallel with the reverse client
+IP address. This test is disabled by default. </p>
+
+<blockquote>
+<p>
+CAUTION: when postscreen rejects mail, its SMTP reply contains the
+DNSBL domain name. Use the <a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> feature to
+hide "password" information in DNSBL domain names.
+</p>
+</blockquote>
+
+<p> When the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> time has elapsed, and the combined
+DNSBL score is equal to or greater than the <a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold</a>
+parameter value, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
+
+<pre>
+ <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> has a combined
+DNSBL score of <i>count</i>. </p>
+
+<p> The <a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> parameter specifies the action that
+is taken when the combined DNSBL score is equal to or greater than
+the threshold. See "<a href="#fail_before_220">When tests fail
+before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="fail_before_220">When tests fail before the 220 SMTP server greeting</a> </h3>
+
+<p> When the client address matches the permanent denylist, or
+when the client fails the pregreet or DNSBL tests, the action is
+specified with <a href="postconf.5.html#postscreen_denylist_action">postscreen_denylist_action</a>, <a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a>,
+or <a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a>, respectively. </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Repeat this test the next time the client connects. This option
+is useful for testing and collecting statistics without blocking
+mail. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<h2> <a name="after_220">Tests after the 220 SMTP server greeting</a> </h2>
+
+<p> In this phase of the protocol, <a href="postscreen.8.html">postscreen(8)</a> implements a
+number of "deep protocol" tests. These tests use an SMTP protocol
+engine that is built into the <a href="postscreen.8.html">postscreen(8)</a> server. </p>
+
+<p> Important note: these protocol tests are disabled by default.
+They are more intrusive than the pregreet and DNSBL tests, and they
+have limitations as discussed next. </p>
+
+<ul>
+
+<li> <p> The main limitation of "after 220 greeting" tests is that
+a new client must disconnect after passing these tests (reason:
+postscreen is not a proxy). Then the client must reconnect from
+the same IP address before it can deliver mail. The following
+measures may help to avoid email delays: </p>
+
+<ul>
+
+<li> <p> Allow "good" clients to skip tests with the
+<a href="postconf.5.html#postscreen_dnsbl_allowlist_threshold">postscreen_dnsbl_allowlist_threshold</a> feature. This is especially effective
+for large providers that usually don't retry from the same IP
+address. </p>
+
+<li> <p> Small sites: Configure <a href="postscreen.8.html">postscreen(8)</a> to listen on multiple
+IP addresses, published in DNS as different IP addresses for the
+same MX hostname or for different MX hostnames. This avoids mail
+delivery delays with clients that reconnect immediately from the
+same IP address. </p>
+
+<li> <p> Large sites: Share the <a href="postscreen.8.html">postscreen(8)</a> cache between different
+Postfix MTAs with a large-enough <a href="memcache_table.5.html">memcache_table(5)</a>. Again, this
+avoids mail delivery delays with clients that reconnect immediately
+from the same IP address. </p>
+
+</ul>
+
+<li> <p> <a href="postscreen.8.html">postscreen(8)</a>'s built-in SMTP engine does not implement the
+AUTH, XCLIENT, and XFORWARD features. If you need to make these
+services available on port 25, then do not enable the tests after
+the 220 server greeting. </p>
+
+<li> <p> End-user clients should connect directly to the submission
+service, so that they never have to deal with <a href="postscreen.8.html">postscreen(8)</a>'s tests.
+</p>
+
+</ul>
+
+<p> The following "after 220 greeting" tests are available: </p>
+
+<ul>
+
+<li> <a href="#pipelining">Command pipelining test</a>
+
+<li> <a href="#non_smtp">Non-SMTP command test</a>
+
+<li> <a href="#barelf">Bare newline test</a>
+
+<li> <a href="#fail_after_220">When tests fail after the 220 SMTP server greeting</a>
+
+</ul>
+
+<h3> <a name="pipelining">Command pipelining test</a> </h3>
+
+<p> By default, SMTP is a half-duplex protocol: the sender and
+receiver send one command and one response at a time. Unlike the
+Postfix SMTP server, <a href="postscreen.8.html">postscreen(8)</a> does not announce support
+for ESMTP command pipelining. Therefore, clients are not allowed
+to send multiple commands. <a href="postscreen.8.html">postscreen(8)</a>'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "<a href="postconf.5.html#postscreen_pipelining_enable">postscreen_pipelining_enable</a> = yes", <a href="postscreen.8.html">postscreen(8)</a> detects
+zombies that send multiple commands, instead of sending one command
+and waiting for the server to reply. </p>
+
+<p> This test is opportunistically enabled when <a href="postscreen.8.html">postscreen(8)</a> has
+to use the built-in SMTP engine anyway. This is to make <a href="postscreen.8.html">postscreen(8)</a>
+logging more informative. </p>
+
+<p> When a client sends multiple commands, <a href="postscreen.8.html">postscreen(8)</a> logs this
+as: </p>
+
+<pre>
+ <b>COMMAND PIPELINING from</b> <i>[address]:port</i> <b>after</b> <i>command</i>: <i>text</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent
+multiple SMTP commands, instead of sending one command and then
+waiting for the server to reply. This happened after the client
+sent <i>command</i>. The <i>text</i> shows part of the input that
+was sent too early; it is not logged with Postfix 2.8. </p>
+
+<p> The <a href="postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action</a> parameter specifies the action
+that is taken next. See "<a href="#fail_after_220">When tests fail
+after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="non_smtp">Non-SMTP command test</a> </h3>
+
+<p> Some spambots send their mail through open proxies. A symptom
+of this is the usage of commands such as CONNECT and other non-SMTP
+commands. Just like the Postfix SMTP server's <a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>
+feature, <a href="postscreen.8.html">postscreen(8)</a> has an equivalent <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a>
+feature to block these clients. <a href="postscreen.8.html">postscreen(8)</a>'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "<a href="postconf.5.html#postscreen_non_smtp_command_enable">postscreen_non_smtp_command_enable</a> = yes", <a href="postscreen.8.html">postscreen(8)</a>
+detects zombies that send commands specified with the
+<a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> parameter. This also detects commands
+with the syntax of a message header label. The latter is a symptom
+that the client is sending message content after ignoring all the
+responses from <a href="postscreen.8.html">postscreen(8)</a> that reject mail. </p>
+
+<p> This test is opportunistically enabled when <a href="postscreen.8.html">postscreen(8)</a> has
+to use the built-in SMTP engine anyway. This is to make <a href="postscreen.8.html">postscreen(8)</a>
+logging more informative. </p>
+
+<p> When a client sends non-SMTP commands, <a href="postscreen.8.html">postscreen(8)</a> logs this
+as: </p>
+
+<pre>
+ <b>NON-SMTP COMMAND from</b> <i>[address]:port</i> <b>after</b> <i>command: text</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a
+command that matches the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a>
+parameter, or that has the syntax of a message header label (text
+followed by optional space and ":").
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> The <a href="postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action</a> parameter specifies
+the action that is taken next. See "<a href="#fail_after_220">When
+tests fail after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="barelf">Bare newline test</a> </h3>
+
+<p> SMTP is a line-oriented protocol: lines have a limited length,
+and are terminated with &lt;CR&gt;&lt;LF&gt;. Lines ending in a
+"bare" &lt;LF&gt;, that is newline not preceded by carriage return,
+are not allowed in SMTP. <a href="postscreen.8.html">postscreen(8)</a>'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "<a href="postconf.5.html#postscreen_bare_newline_enable">postscreen_bare_newline_enable</a> = yes", <a href="postscreen.8.html">postscreen(8)</a>
+detects clients that send lines ending in bare newline characters.
+</p>
+
+<p> This test is opportunistically enabled when <a href="postscreen.8.html">postscreen(8)</a> has
+to use the built-in SMTP engine anyway. This is to make <a href="postscreen.8.html">postscreen(8)</a>
+logging more informative. </p>
+
+<p> When a client sends bare newline characters, <a href="postscreen.8.html">postscreen(8)</a> logs
+this as:
+</p>
+
+<pre>
+ <b>BARE NEWLINE from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
+newline character, that is newline not preceded by carriage
+return.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> The <a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a> parameter specifies the
+action that is taken next. See "<a href="#fail_after_220">When
+tests fail after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="fail_after_220">When tests fail after the 220 SMTP server greeting</a> </h3>
+
+<p> When the client fails the pipelining, non-SMTP command or bare
+newline tests, the action is specified with <a href="postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action</a>,
+<a href="postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action</a> or <a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a>,
+respectively. </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default for bare newline) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Do NOT repeat this test before the result from some other test
+expires.
+
+This option is useful for testing and collecting statistics without
+blocking mail permanently. </dd>
+
+<dt> <b>enforce</b> (default for pipelining) </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver
+mail with a 550 SMTP reply, and log the helo/sender/recipient
+information. Repeat this test the next time the client connects.
+</dd>
+
+<dt> <b>drop</b> (default for non-SMTP commands) </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. This action is
+compatible with the Postfix SMTP server's <a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>
+feature. </dd>
+
+</dl>
+
+<h2> <a name="other_error">Other errors</a> </h2>
+
+<p> When an SMTP client hangs up unexpectedly, <a href="postscreen.8.html">postscreen(8)</a> logs
+this as: </p>
+
+<pre>
+ <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> disconnected
+unexpectedly, <i>time</i> seconds after the start of the
+test named <i>test name</i>. </p>
+
+<p> There is no punishment for hanging up. A client that hangs up
+without sending the QUIT command can still pass all <a href="postscreen.8.html">postscreen(8)</a>
+tests. </p>
+
+<!--
+
+<p> While an unexpired penalty is in effect, an SMTP client is not
+allowed to pass any tests, and <a href="postscreen.8.html">postscreen(8)</a> logs each connection
+with the remaining amount of penalty time as: </p>
+
+<pre>
+ <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
+</pre>
+
+<p> During this time, all attempts by the client to deliver mail
+will be deferred with a 450 SMTP status. </p>
+
+-->
+
+<p> The following errors are reported by the built-in SMTP engine.
+This engine never accepts mail, therefore it has per-session limits
+on the number of commands and on the session length. </p>
+
+<pre>
+ <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-command time limit as specified with the <a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a>
+parameter. The session is terminated immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<pre>
+ <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-session command count limit as specified with the
+<a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> parameter. The session is terminated
+immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<pre>
+ <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-command length limit, as specified with the <a href="postconf.5.html#line_length_limit">line_length_limit</a>
+parameter. The session is terminated immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> When an SMTP client makes too many connections at the same time,
+<a href="postscreen.8.html">postscreen(8)</a> rejects the connection with a 421 status code and logs: </p>
+
+<pre>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
+</pre>
+
+<p> The <a href="postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a> parameter controls this limit. </p>
+
+<p> When an SMTP client connects after <a href="postscreen.8.html">postscreen(8)</a> has reached a
+connection count limit, <a href="postscreen.8.html">postscreen(8)</a> rejects the connection with
+a 421 status code and logs: </p>
+
+<pre>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all screening ports busy</b>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
+</pre>
+
+<p> The <a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> and <a href="postconf.5.html#postscreen_post_queue_limit">postscreen_post_queue_limit</a>
+parameters control these limits. </p>
+
+<h2> <a name="victory">When all tests succeed</a> </h2>
+
+<p> When a new SMTP client passes all tests (i.e. it is not allowlisted
+via some mechanism), <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
+
+<pre>
+ <b>PASS NEW</b> <i>[address]:port</i>
+</pre>
+
+<p> Where <i>[address]:port</i> are the client IP address and port.
+Then, <a href="postscreen.8.html">postscreen(8)</a>
+creates a temporary allowlist entry that excludes the client IP
+address from further tests until the temporary allowlist entry
+expires, as controlled with the postscreen_*_ttl parameters. </p>
+
+<p> When no "<a href="#after_220">deep protocol tests</a>" are
+configured, <a href="postscreen.8.html">postscreen(8)</a> hands off the "live" connection to a Postfix
+SMTP server process. The client can then continue as if <a href="postscreen.8.html">postscreen(8)</a>
+never even existed (except for the short <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> delay).
+</p>
+
+<p> When any "<a href="#after_220">deep protocol tests</a>" are
+configured, <a href="postscreen.8.html">postscreen(8)</a> cannot hand off the "live" connection to
+a Postfix SMTP server process in the middle of the session. Instead,
+<a href="postscreen.8.html">postscreen(8)</a> defers mail delivery attempts with a 4XX status, logs
+the helo/sender/recipient information, and waits for the client to
+disconnect. The next time the client connects it will be allowed
+to talk to a Postfix SMTP server process to deliver its mail.
+<a href="postscreen.8.html">postscreen(8)</a> mitigates the impact of this limitation by giving
+<a href="#after_220">deep protocol tests</a> a long expiration
+time. </p>
+
+<h2> <a name="config"> Configuring the postscreen(8) service</a>
+</h2>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> has been tested on FreeBSD [4-8], Linux 2.[4-6]
+and Solaris 9 systems. </p>
+
+<ul>
+
+<li> <a href="#enable"> Turning on postscreen(8) without blocking
+mail</a>
+
+<li> <a href="#starttls"> postscreen(8) TLS configuration </a>
+
+<li> <a href="#blocking"> Blocking mail with postscreen(8) </a>
+
+<li> <a href="#turnoff"> Turning off postscreen(8) </a>
+
+<li> <a href="#temp_allow_sharing"> Sharing the temporary allowlist
+</a>
+
+</ul>
+
+<h3> <a name="enable"> Turning on postscreen(8) without blocking mail</a> </h3>
+
+<p> To enable the <a href="postscreen.8.html">postscreen(8)</a> service and log client information
+without blocking mail: </p>
+
+<ol>
+
+<li> <p> Make sure that local clients and systems with non-standard
+SMTP implementations are excluded from any <a href="postscreen.8.html">postscreen(8)</a> tests. The
+default is to exclude all clients in <a href="postconf.5.html#mynetworks">mynetworks</a>. To exclude additional
+clients, for example, third-party performance monitoring tools (these
+tend to have broken SMTP implementations): </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ # Exclude broken clients by allowlisting. Clients in <a href="postconf.5.html#mynetworks">mynetworks</a>
+ # should always be allowlisted.
+ <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
+ <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
+ 192.168.254.0/24 permit
+</pre>
+
+<li> <p> Comment out the "<tt>smtp inet ... smtpd</tt>" service
+in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ #smtp inet n - n - - smtpd
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the new "<tt>smtpd pass ... smtpd</tt>" service
+in <a href="master.5.html">master.cf</a>, and duplicate any "<tt>-o parameter=value</tt>" entries
+from the smtpd service that was commented out in the previous step.
+</p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ smtpd pass - - n - - smtpd
+ -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the new "<tt>smtp inet ... postscreen</tt>"
+service in <a href="master.5.html">master.cf</a>. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ smtp inet n - n - 1 postscreen
+</pre>
+
+<li> <p> Uncomment the new "<tt>tlsproxy unix ... tlsproxy</tt>"
+service in <a href="master.5.html">master.cf</a>. This service implements STARTTLS support for
+<a href="postscreen.8.html">postscreen(8)</a>. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ tlsproxy unix - - n - 0 tlsproxy
+</pre>
+
+<li> <p> Uncomment the new "<tt>dnsblog unix ... dnsblog</tt>"
+service in <a href="master.5.html">master.cf</a>. This service does DNSBL lookups for <a href="postscreen.8.html">postscreen(8)</a>
+and logs results. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ dnsblog unix - - n - 0 dnsblog
+</pre>
+
+<li> <p> To enable DNSBL lookups, list some DNS blocklist sites in
+<a href="postconf.5.html">main.cf</a>, separated by whitespace. Different sites can have different
+weights. For example:
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold</a> = 2
+ <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> = zen.spamhaus.org*2
+ bl.spamcop.net*1 b.barracudacentral.org*1
+</pre>
+
+<p> Note: if your DNSBL queries have a "secret" in the domain name,
+you must censor this information from the <a href="postscreen.8.html">postscreen(8)</a> SMTP replies.
+For example: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> = <a href="DATABASE_README.html#types">texthash</a>:/etc/postfix/dnsbl_reply
+</pre>
+
+<pre>
+/etc/postfix/dnsbl_reply:
+ # Secret DNSBL name Name in <a href="postscreen.8.html">postscreen(8)</a> replies
+ secret.zen.dq.spamhaus.net zen.spamhaus.org
+</pre>
+
+<p> The <a href="DATABASE_README.html#types">texthash</a>: format is similar to <a href="DATABASE_README.html#types">hash</a>: except that there is
+no need to run <a href="postmap.1.html">postmap(1)</a> before the file can be used, and that it
+does not detect changes after the file is read. It is new with
+Postfix version 2.8. </p>
+
+<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
+</p>
+
+</ol>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Some <a href="postscreen.8.html">postscreen(8)</a> configuration parameters implement
+stress-dependent behavior. This is supported only when the default
+value is stress-dependent (that is, "postconf -d <i>parametername</i>"
+output shows
+"<i>parametername</i>&nbsp;=&nbsp;${stress?<i>something</i>}${stress:<i>something</i>}" or
+"<i>parametername</i>&nbsp;=&nbsp;${stress?{<i>something</i>}:{<i>something</i>}}").
+Other parameters always evaluate as if the stress value is the empty
+string. </p>
+
+<li> <p> See "<a href="#before_220">Tests before the 220 SMTP server
+greeting</a>" for details about the logging from these
+<a href="postscreen.8.html">postscreen(8)</a> tests. </p>
+
+<li> <p> If you run Postfix 2.6 or earlier you must stop and start
+the master daemon ("<tt>postfix stop; postfix start</tt>"). This
+is needed because the Postfix "pass" master service type did not
+work reliably on all systems. </p>
+
+</ul>
+
+<h3> <a name="starttls"> postscreen(8) TLS configuration </a> </h3>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> TLS support is available for remote SMTP clients
+that aren't allowlisted, including clients that need to renew their
+temporary allowlist status. When a remote SMTP client requests TLS
+service, <a href="postscreen.8.html">postscreen(8)</a> invisibly hands off the connection to a
+<a href="tlsproxy.8.html">tlsproxy(8)</a> process. Then, <a href="tlsproxy.8.html">tlsproxy(8)</a> encrypts and decrypts the
+traffic between <a href="postscreen.8.html">postscreen(8)</a> and the remote SMTP client. One
+<a href="tlsproxy.8.html">tlsproxy(8)</a> process can handle multiple SMTP sessions. The number
+of <a href="tlsproxy.8.html">tlsproxy(8)</a> processes slowly increases with server load, but it
+should always be much smaller than the number of <a href="postscreen.8.html">postscreen(8)</a> TLS
+sessions. </p>
+
+<p> TLS support for <a href="postscreen.8.html">postscreen(8)</a> and <a href="tlsproxy.8.html">tlsproxy(8)</a> uses the same
+parameters as with <a href="smtpd.8.html">smtpd(8)</a>. We recommend that you keep the relevant
+configuration parameters in <a href="postconf.5.html">main.cf</a>. If you must specify "-o
+smtpd_mumble=value" parameter overrides in <a href="master.5.html">master.cf</a> for a
+postscreen-protected <a href="smtpd.8.html">smtpd(8)</a> service, then you should specify those
+same parameter overrides for the <a href="postscreen.8.html">postscreen(8)</a> and <a href="tlsproxy.8.html">tlsproxy(8)</a>
+services. </p>
+
+<h3> <a name="blocking"> Blocking mail with postscreen(8) </a> </h3>
+
+<p> For compatibility with <a href="smtpd.8.html">smtpd(8)</a>, <a href="postscreen.8.html">postscreen(8)</a> implements the
+<a href="postconf.5.html#soft_bounce">soft_bounce</a> safety feature. This causes Postfix to reject mail with
+a "try again" reply code. </p>
+
+<ul>
+
+<li> <p> To turn this on for all of Postfix, specify "<tt><a href="postconf.5.html#soft_bounce">soft_bounce</a>
+= yes</tt>" in <a href="postconf.5.html">main.cf</a>. </p>
+
+<li> <p> To turn this on for <a href="postscreen.8.html">postscreen(8)</a> only, append "<tt>-o
+<a href="postconf.5.html#soft_bounce">soft_bounce</a>=yes</tt>" (note: NO SPACES around '=') to the postscreen
+entry in <a href="master.5.html">master.cf</a>. <p>
+
+</ul>
+
+<p> Execute "<tt>postfix reload</tt>" to make the change effective. </p>
+
+<p> After testing, do not forget to remove the <a href="postconf.5.html#soft_bounce">soft_bounce</a> feature,
+otherwise senders won't receive their non-delivery notification
+until many days later. </p>
+
+<p> To use the <a href="postscreen.8.html">postscreen(8)</a> service to block mail, edit <a href="postconf.5.html">main.cf</a> and
+specify one or more of: </p>
+
+<ul>
+
+<li> <p> "<tt><a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> = enforce</tt>", to reject
+clients that are on DNS blocklists, and to log the helo/sender/recipient
+information. With good DNSBLs this reduces the amount of load on
+Postfix SMTP servers dramatically. </p>
+
+<li> <p> "<tt><a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> = enforce</tt>", to reject
+clients that talk before their turn, and to log the helo/sender/recipient
+information. This stops over half of all known-to-be illegitimate
+connections to Wietse's mail server. It is backup protection for
+zombies that haven't yet been denylisted. </p>
+
+<li> <p> You can also enable "<a href="#after_220">deep protocol
+tests</a>", but these are more intrusive than the pregreet or DNSBL
+tests. </p>
+
+<p> When a good client passes the "<a href="#after_220">deep
+protocol tests</a>",
+<a href="postscreen.8.html">postscreen(8)</a> adds the client to the temporary
+allowlist but it cannot hand off the "live" connection to a Postfix
+SMTP server process in the middle of the session. Instead, <a href="postscreen.8.html">postscreen(8)</a>
+defers mail delivery attempts with a 4XX status, logs the
+helo/sender/recipient information, and waits for the client to
+disconnect. </p>
+
+<p> When the good client comes back in a later session, it is allowed
+to talk directly to a Postfix SMTP server. See "<a href="#after_220">Tests
+after the 220 SMTP server greeting</a>" above for limitations with
+AUTH and other features that clients may need. </p>
+
+<p> An unexpected benefit from "<a href="#after_220">deep protocol
+tests</a>" is that some "good" clients don't return after the 4XX
+reply; these clients were not so good after all. </p>
+
+<p> Unfortunately, some senders will retry requests from different
+IP addresses, and may never get allowlisted. For this reason,
+Wietse stopped using "<a href="#after_220">deep protocol tests</a>"
+on his own internet-facing mail server. </p>
+
+<li> <p> There is also support for permanent denylisting and
+allowlisting; see the description of the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a>
+parameter for details. </p>
+
+</ul>
+
+<h3> <a name="turnoff"> Turning off postscreen(8) </a> </h3>
+
+<p> To turn off <a href="postscreen.8.html">postscreen(8)</a> and handle mail directly with Postfix
+SMTP server processes: </p>
+
+<ol>
+
+<li> <p> Comment out the "<tt>smtp inet ... postscreen</tt>" service
+in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ #smtp inet n - n - 1 postscreen
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Comment out the "<tt>dnsblog unix ... dnsblog</tt>" service
+in <a href="master.5.html">master.cf</a>. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ #dnsblog unix - - n - 0 dnsblog
+</pre>
+
+<li> <p> Comment out the "<tt>smtpd pass ... smtpd</tt>" service
+in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ #smtpd pass - - n - - smtpd
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy</tt>"
+service in <a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>"
+entries that follow. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ #tlsproxy unix - - n - 0 tlsproxy
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the "<tt>smtp inet ... smtpd</tt>" service in
+<a href="master.5.html">master.cf</a>, including any "<tt>-o parameter=value</tt>" entries that
+may follow. </p>
+
+<pre>
+/etc/postfix/<a href="master.5.html">master.cf</a>:
+ smtp inet n - n - - smtpd
+ -o parameter=value ...
+</pre>
+
+<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
+</p>
+
+</ol>
+
+<h3> <a name="temp_allow_sharing"> Sharing the temporary allowlist </a> </h3>
+
+<p> By default, the temporary allowlist is not shared between
+multiple <a href="postscreen.8.html">postscreen(8)</a> daemons. To enable sharing, choose one
+of the following options: </p>
+
+<ul>
+
+<li> <p> A non-persistent <a href="memcache_table.5.html">memcache</a>: temporary allowlist can be shared
+ between <a href="postscreen.8.html">postscreen(8)</a> daemons on the same host or different
+ hosts. Disable cache cleanup (<a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a>
+ = 0) in all <a href="postscreen.8.html">postscreen(8)</a> daemons because <a href="memcache_table.5.html">memcache</a>: has no
+ first-next API (but see example 4 below for <a href="memcache_table.5.html">memcache</a>: with
+ persistent backup). This requires Postfix 2.9 or later. </p>
+
+ <pre>
+ # Example 1: non-persistent <a href="memcache_table.5.html">memcache</a>: allowlist.
+ /etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="memcache_table.5.html">memcache</a>:/etc/postfix/postscreen_cache
+ <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0
+
+ /etc/postfix/postscreen_cache:
+ memcache = inet:127.0.0.1:11211
+ key_format = postscreen:%s
+ </pre>
+
+<li> <p>
+ A persistent <a href="lmdb_table.5.html">lmdb</a>: temporary allowlist can be shared between
+ <a href="postscreen.8.html">postscreen(8)</a> daemons that run under the same <a href="master.8.html">master(8)</a> daemon,
+ or under different <a href="master.8.html">master(8)</a> daemons on the same host. Disable
+ cache cleanup (<a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0) in all
+ <a href="postscreen.8.html">postscreen(8)</a> daemons except one that is responsible for cache
+ cleanup. This requires Postfix 2.11 or later. </p>
+
+ <pre>
+ # Example 2: persistent <a href="lmdb_table.5.html">lmdb</a>: allowlist.
+ /etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="lmdb_table.5.html">lmdb</a>:$<a href="postconf.5.html#data_directory">data_directory</a>/postscreen_cache
+ # See note 1 below.
+ # <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0
+ </pre>
+
+<li> <p> Other kinds of persistent temporary allowlist can be shared
+ only between <a href="postscreen.8.html">postscreen(8)</a> daemons that run under the same
+ <a href="master.8.html">master(8)</a> daemon. In this case, temporary allowlist access must
+ be shared through the <a href="proxymap.8.html">proxymap(8)</a> daemon. This requires Postfix
+ 2.9 or later. </p>
+
+ <pre>
+ # Example 3: proxied <a href="DATABASE_README.html#types">btree</a>: allowlist.
+ /etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> =
+ <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/postscreen_cache
+ # See note 1 below.
+ # <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0
+
+ # Example 4: proxied <a href="DATABASE_README.html#types">btree</a>: allowlist with <a href="memcache_table.5.html">memcache</a>: accelerator.
+ /etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="memcache_table.5.html">memcache</a>:/etc/postfix/postscreen_cache
+ <a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a> =
+ <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/postscreen_cache
+ ... other proxied tables ...
+ # See note 1 below.
+ # <a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> = 0
+
+ /etc/postfix/postscreen_cache:
+ # Note: the $<a href="postconf.5.html#data_directory">data_directory</a> macro is not defined in this context.
+ memcache = inet:127.0.0.1:11211
+ backup = <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/postscreen_cache
+ key_format = postscreen:%s
+ </pre>
+
+ <p> Note 1: disable cache cleanup (<a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a>
+ = 0) in all <a href="postscreen.8.html">postscreen(8)</a> daemons except one that is responsible
+ for cache cleanup. </p>
+
+ <p> Note 2: <a href="postscreen.8.html">postscreen(8)</a> cache sharing via <a href="proxymap.8.html">proxymap(8)</a> requires Postfix
+ 2.9 or later; earlier <a href="proxymap.8.html">proxymap(8)</a> implementations don't support
+ cache cleanup. </p>
+
+</ul>
+
+<h2> <a name="historical"> Historical notes and credits </a> </h2>
+
+<p> Many ideas in <a href="postscreen.8.html">postscreen(8)</a> were explored in earlier work by
+Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic
+Control. </p>
+
+<p> Wietse threw together a crude prototype with pregreet and dnsbl
+support in June 2009, because he needed something new for a Mailserver
+conference presentation in July. Ralf Hildebrandt ran this code on
+several servers to collect real-world statistics. This version used
+the <a href="dnsblog.8.html">dnsblog(8)</a> ad-hoc DNS client program. </p>
+
+<p> Wietse needed new material for a LISA conference presentation
+in November 2010, so he added support for DNSBL weights and filters
+in August, followed by a major code rewrite, deep protocol tests,
+helo/sender/recipient logging, and stress-adaptive behavior in
+September. Ralf Hildebrandt ran this code on several servers to
+collect real-world statistics. This version still used the embarrassing
+<a href="dnsblog.8.html">dnsblog(8)</a> ad-hoc DNS client program. </p>
+
+<p> Wietse added STARTTLS support in December 2010. This makes
+<a href="postscreen.8.html">postscreen(8)</a> usable for sites that require TLS support. The
+implementation introduces the <a href="tlsproxy.8.html">tlsproxy(8)</a> event-driven TLS proxy
+that decrypts/encrypts the sessions for multiple SMTP clients. </p>
+
+<p> The <a href="tlsproxy.8.html">tlsproxy(8)</a> implementation led to the discovery of a "new"
+class of vulnerability (<a
+href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0411"
+>CVE-2011-0411</a>) that affected multiple implementations of SMTP,
+POP, IMAP, NNTP, and FTP over TLS. </p>
+
+<p> <a href="postscreen.8.html">postscreen(8)</a> was officially released as part of the Postfix
+2.8 stable release in January 2011.</p>
+
+<p> Noel Jones helped with the Postfix 3.6 transition towards respectful
+documentation. </p>
+
+</body>
+</html>