1199 lines
54 KiB
HTML
1199 lines
54 KiB
HTML
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
"https://www.w3.org/TR/html4/loose.dtd">
|
|
|
|
<head>
|
|
|
|
<title>Postfix Postscreen Howto (Postfix 2.8 - 3.5)</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 Postscreen Howto (Postfix 2.8 - 3.5)</h1>
|
|
|
|
<hr>
|
|
|
|
<h2> <a name="intro">Introduction</a> </h2>
|
|
|
|
<p> This document describes features that are available in Postfix
|
|
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_white_black"> Permanent allow/denylist test </a>
|
|
|
|
<li> <a href="#temp_white"> Temporary allowlist test </a>
|
|
|
|
<li> <a href="#white_veto"> MX Policy test </a>
|
|
|
|
</ul>
|
|
|
|
<h3> <a name="perm_white_black"> 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>
|
|
|
|
<pre>
|
|
<b>WHITELISTED</b> <i>[address]:port</i>
|
|
</pre>
|
|
|
|
<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>
|
|
|
|
<pre>
|
|
<b>BLACKLISTED</b> <i>[address]:port</i>
|
|
</pre>
|
|
|
|
<p> The <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_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_white"> 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_white_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="white_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_whitelist_interfaces">postscreen_whitelist_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>
|
|
|
|
<pre>
|
|
<b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b>
|
|
<b>WHITELIST VETO</b> <i>[address]:port</i>
|
|
</pre>
|
|
|
|
<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_blacklist_action">postscreen_blacklist_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_whitelist_threshold">postscreen_dnsbl_whitelist_threshold</a> feature (Postfix 2.11 and
|
|
later). This is especially effective for sites such as Google that
|
|
never retry immediately 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 <CR><LF>. Lines ending in a
|
|
"bare" <LF>, 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_white_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> = ${stress?<i>something</i>}${stress:<i>something</i>}" or
|
|
"<i>parametername</i> = ${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_white_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>
|
|
|
|
</body>
|
|
|
|
</html>
|