mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 06:05:37 +00:00
postfix-2.8-20100923
This commit is contained in:
committed by
Viktor Dukhovni
parent
36a1c7272a
commit
038275e32e
@@ -16033,3 +16033,9 @@ Apologies for any names omitted.
|
||||
|
||||
Bugfix: cut-and-paste error. Postscreen used pregreet_ttl
|
||||
instead of dnsbnl_ttl. File: postscreen/postscreen_early.c.
|
||||
|
||||
20100920
|
||||
|
||||
Cleanup: minor cleanups and invisible fixes. Files:
|
||||
postscreen/postscreen_misc.c, postscreen/postscreen.h,
|
||||
postscreen/postscreen_tests.c.
|
||||
|
@@ -5,13 +5,13 @@ PPoossttffiixx PPoossttssccrreeeenn HHoowwttoo
|
||||
IInnttrroodduuccttiioonn
|
||||
|
||||
The Postfix postscreen(8) server performs triage on multiple inbound SMTP
|
||||
connections in parallel. While a single postscreen(8) process keeps spambots
|
||||
connections in parallel. While a single postscreen(8) process keeps zombies
|
||||
away from Postfix SMTP server processes, more Postfix SMTP server processes
|
||||
remain available for legitimate clients.
|
||||
|
||||
By doing these checks in a single postscreen(8) process, Postfix can avoid
|
||||
wasting one SMTP server process per connection. A side benefit of postscreen
|
||||
(8)'s DNSBL lookups is that DNS records are already cached before the Postfix
|
||||
wasting one SMTP server process per zombie. A side benefit of postscreen(8)'s
|
||||
DNSBL lookups is that DNS records will already be cached before the Postfix
|
||||
SMTP server looks them up later.
|
||||
|
||||
Topics in this document:
|
||||
@@ -29,26 +29,36 @@ Topics in this document:
|
||||
|
||||
TThhee bbaassiicc iiddeeaa bbeehhiinndd ppoossttssccrreeeenn((88))
|
||||
|
||||
Spambots have a limited amount of time to send out spam before they become
|
||||
blacklisted. For this reason, spambots make compromises in their SMTP protocol
|
||||
implementation to speed up spam deliveries. For example, they speak before
|
||||
their turn, or they ignore responses from SMTP servers.
|
||||
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 postscreen(8)
|
||||
that keeps the zombies away, Postfix would be spending most of its resources
|
||||
not receiving email.
|
||||
|
||||
Many spambots avoid spamming the same site repeatedly, in an attempt to fly
|
||||
under the radar. Thus, postscreen(8) must make a long-term decision after a
|
||||
single measurement. For example, allow a good client to skip the "pregreet"
|
||||
test for 24 hours.
|
||||
The main challenge for postscreen(8) is to make an is-it-a-zombie decision
|
||||
based on a single measurement. This is necessary because many zombies avoid
|
||||
spamming the same site repeatedly, in an attempt to fly under the radar. Once
|
||||
postscreen(8) decides that a client is not-a-zombie, it whitelists the client
|
||||
temporarily to avoid further delays for legitimate mail.
|
||||
|
||||
To recognize spambots, postscreen(8) measures properties of the client IP
|
||||
address and of the client SMTP protocol implementation (the protocol
|
||||
compromises that were made to speed up delivery). These properties don't change
|
||||
with delivery attempts, and are therefore suitable for making a long-term
|
||||
decision after a single measurement.
|
||||
Zombies have challenges too: they have only a limited amount of time to deliver
|
||||
spam before their IP address becomes blacklisted. 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.
|
||||
|
||||
postscreen(8) does not inspect message content. The reason is that content can
|
||||
change with each delivery attempt, especially with legitimate clients. Message
|
||||
content is not good for making a long-term decision after a single measurement,
|
||||
and that is the problem that postscreen(8) is focused on.
|
||||
postscreen(8) uses a variety of measurements to recognize zombies. First,
|
||||
postscreen(8) determines if the remote SMTP client IP address is blacklisted.
|
||||
Second, postscreen(8) looks for protocol compromises that are made to speed up
|
||||
delivery. The results of such measurements don't change with each delivery
|
||||
attempt, and are therefore good for making an is-it-a-zombie decision based on
|
||||
a single measurement.
|
||||
|
||||
postscreen(8) does not inspect message content. Message content can vary widely
|
||||
with each delivery attempt, especially with clients that (also) send legitimate
|
||||
email. Content is therefore not good for making an is-it-a-zombie decision
|
||||
based on a single measurement, and that is the problem that postscreen(8) is
|
||||
focused on.
|
||||
|
||||
GGeenneerraall ooppeerraattiioonn
|
||||
|
||||
@@ -67,7 +77,7 @@ from clients that fail one or more tests, after logging the helo, sender and
|
||||
recipient information.
|
||||
|
||||
Note: postscreen(8) is not an SMTP proxy; this is intentional. The purpose is
|
||||
to keep spambots away from Postfix, with minimal overhead for legitimate
|
||||
to keep zombies away from Postfix, with minimal overhead for legitimate
|
||||
clients.
|
||||
|
||||
QQuuiicckk tteessttss bbeeffoorree eevveerryytthhiinngg eellssee
|
||||
@@ -139,14 +149,14 @@ postscreen_greet_wait delay).
|
||||
PPrreeggrreeeett tteesstt
|
||||
|
||||
The SMTP protocol is a classic example of a protocol where the server speaks
|
||||
before the client. postscreen(8) detects spambots that are in a hurry and that
|
||||
before the client. postscreen(8) detects zombies that are in a hurry and that
|
||||
speak before their turn. This test is enabled by default.
|
||||
|
||||
The postscreen_greet_banner parameter specifies the text portion of a "220-
|
||||
text..." teaser banner (default: $smtpd_banner). Note that this becomes the
|
||||
first part of a multi-line server greeting. The postscreen(8) daemon sends this
|
||||
before the postscreen_greet_wait timer is started. The purpose of the teaser
|
||||
banner is to confuse spambots so that they speak before their turn. It has no
|
||||
banner is to confuse zombies so that they speak before their turn. It has no
|
||||
effect on SMTP clients that correctly implement the protocol.
|
||||
|
||||
To avoid problems with poorly-implemented SMTP engines in network appliances or
|
||||
@@ -189,7 +199,7 @@ When the postscreen_greet_wait time has elapsed, and the combined DNSBL score
|
||||
is equal to or greater than the postscreen_dnsbl_threshold parameter value,
|
||||
postscreen(8) logs this as:
|
||||
|
||||
DDNNSSBBLL rraannkk count ffoorr address
|
||||
DDNNSSBBLL rraannkk count ffoorr address
|
||||
|
||||
Translation: the SMTP client at address has a combined DNSBL score of count.
|
||||
|
||||
@@ -259,7 +269,7 @@ command and one response at a time. Unlike the Postfix SMTP server, postscreen
|
||||
are not allowed to send multiple commands. postscreen(8)'s deep protocol test
|
||||
for this is disabled by default.
|
||||
|
||||
With "postscreen_pipelining_enable = yes", postscreen(8) detects spambots that
|
||||
With "postscreen_pipelining_enable = yes", postscreen(8) detects zombies that
|
||||
send multiple commands, instead of sending one command and waiting for the
|
||||
server to reply.
|
||||
|
||||
@@ -285,7 +295,7 @@ Postfix SMTP server's smtpd_forbidden_commands feature, postscreen(8) has an
|
||||
equivalent postscreen_forbidden_commands feature to block these clients.
|
||||
postscreen(8)'s deep protocol test for this is disabled by default.
|
||||
|
||||
With "postscreen_non_smtp_command_enable = yes", postscreen(8) detects spambots
|
||||
With "postscreen_non_smtp_command_enable = yes", postscreen(8) detects zombies
|
||||
that send commands specified with the postscreen_forbidden_commands 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
|
||||
@@ -501,7 +511,7 @@ more of:
|
||||
* "postscreen_greet_action = enforce", 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 spambots that haven't yet been
|
||||
server. It is backup protection for zombies that haven't yet been
|
||||
blacklisted.
|
||||
|
||||
* You can also enable "deep protocol tests", but these are more intrusive
|
||||
|
@@ -2,15 +2,17 @@ Wish list:
|
||||
|
||||
Remove this file from the stable release.
|
||||
|
||||
how to prevent postscreen's cache sweeper from deleting
|
||||
records that have failed ignored tests?
|
||||
|
||||
Update history in manpage/readme for SQLite driver.
|
||||
|
||||
header_checks(5): document synopsis and feature subsets.
|
||||
|
||||
Consistency: in postconf.proto make <dt>..</dt> tags bold.
|
||||
|
||||
postscreen(8): listen on multiple IP addresses and enforce
|
||||
that the client contacts the primary MX address first (i.e.
|
||||
punish hosts that contact the secondary before the primary).
|
||||
The downside with any approach that relies on temporary
|
||||
punishment is that it does not scale to configurations
|
||||
with multiple equal-preference MX hosts. Such hosts would
|
||||
have to share the postscreen cache, causing an unacceptable
|
||||
performance bottleneck and a single point of failure.
|
||||
|
||||
According to a paper by Ted Unangst at BSDCON09, kqueue
|
||||
reports state changes, i.e. kqueue indicates when the socket
|
||||
becomes readable. Specifically, he writes when kqueue reports
|
||||
@@ -24,12 +26,6 @@ Wish list:
|
||||
repeats these tests with OpenBSD and NetBSD (and MacOS X
|
||||
once they fix their kqueue implementation).
|
||||
|
||||
postscreen(8): need some option to wait for DNSBL lookup
|
||||
(etc.) completion. For example, postscreen_greet_wait would
|
||||
become a lower bound, while postscreen_dnsbl_wait would
|
||||
become an upper bound (or should all features use a shared
|
||||
postscreen_max_wait upper bound?).
|
||||
|
||||
Would it help if there were different cleanup_service
|
||||
parameter names for different message paths? smtpd(8) uses
|
||||
the same cleanup_service value for receiving remote mail
|
||||
|
@@ -19,15 +19,14 @@
|
||||
|
||||
<p> The Postfix <a href="postscreen.8.html">postscreen(8)</a> server performs triage on multiple
|
||||
inbound SMTP connections in parallel. While a single <a href="postscreen.8.html">postscreen(8)</a>
|
||||
process keeps spambots away from Postfix SMTP server processes,
|
||||
process keeps zombies away from Postfix SMTP server processes,
|
||||
more Postfix SMTP server processes remain available for legitimate
|
||||
clients. </p>
|
||||
|
||||
<p> By doing these checks in a single <a href="postscreen.8.html">postscreen(8)</a> process, Postfix
|
||||
can avoid wasting one SMTP server process per connection. A side
|
||||
benefit of <a href="postscreen.8.html">postscreen(8)</a>'s DNSBL lookups is that DNS records are
|
||||
already cached before the Postfix SMTP server looks them up later.
|
||||
</p>
|
||||
can avoid wasting one SMTP server process per zombie. A side benefit
|
||||
of <a href="postscreen.8.html">postscreen(8)</a>'s DNSBL lookups is that DNS records will already be
|
||||
cached before the Postfix SMTP server looks them up later. </p>
|
||||
|
||||
<p> Topics in this document: </p>
|
||||
|
||||
@@ -57,30 +56,39 @@ already cached before the Postfix SMTP server looks them up later.
|
||||
|
||||
<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2>
|
||||
|
||||
<p> Spambots have a limited amount of time to send out spam before
|
||||
they become blacklisted. For this reason, spambots make compromises
|
||||
in their SMTP protocol implementation to speed up spam deliveries.
|
||||
For example, they speak before their turn, or they ignore responses
|
||||
from SMTP servers. </p>
|
||||
<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> Many spambots avoid spamming the same site repeatedly, in an
|
||||
attempt to fly under the radar. Thus, <a href="postscreen.8.html">postscreen(8)</a> must make a
|
||||
long-term decision after a single measurement. For example, allow
|
||||
a good client to skip the "<a href="#pregreet">pregreet</a>" test
|
||||
for 24 hours. </p>
|
||||
<p> The main challenge for <a href="postscreen.8.html">postscreen(8)</a> is to make an is-it-a-zombie
|
||||
decision based on a single measurement. This is necessary because
|
||||
many zombies avoid spamming the same site repeatedly, in an attempt
|
||||
to fly under the radar. Once <a href="postscreen.8.html">postscreen(8)</a> decides that a client
|
||||
is not-a-zombie, it whitelists the client temporarily to avoid
|
||||
further delays for legitimate mail. </p>
|
||||
|
||||
<p> To recognize spambots, <a href="postscreen.8.html">postscreen(8)</a> measures properties of the
|
||||
client IP address and of the client SMTP protocol implementation
|
||||
(the protocol compromises that were made to speed up delivery).
|
||||
These properties don't change with delivery attempts, and are
|
||||
therefore suitable for making a long-term decision after a single
|
||||
measurement. </p>
|
||||
<p> Zombies have challenges too: they have only a limited amount
|
||||
of time to deliver spam before their IP address becomes blacklisted.
|
||||
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> does not inspect message content. The reason is
|
||||
that content can change with each delivery attempt, especially with
|
||||
legitimate clients. Message content is not good for making a long-term
|
||||
decision after a single measurement, and that is the problem that
|
||||
<a href="postscreen.8.html">postscreen(8)</a> is focused on. </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 blacklisted. Second, <a href="postscreen.8.html">postscreen(8)</a> looks for protocol
|
||||
compromises that are made to speed up delivery. The results of
|
||||
such measurements don't change with each delivery attempt, and are
|
||||
therefore good for making an is-it-a-zombie decision based on a
|
||||
single measurement. </p>
|
||||
|
||||
<p> <a href="postscreen.8.html">postscreen(8)</a> does not inspect message content. Message content
|
||||
can vary widely with each delivery attempt, especially with clients
|
||||
that (also) send legitimate email. Content is therefore not good
|
||||
for making an is-it-a-zombie decision based on a single measurement,
|
||||
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>
|
||||
|
||||
@@ -100,7 +108,7 @@ 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 spambots away from Postfix, with minimal
|
||||
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>
|
||||
@@ -196,7 +204,7 @@ for the short <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_w
|
||||
<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 spambots
|
||||
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>
|
||||
|
||||
@@ -205,7 +213,7 @@ portion of a "220-<i>text</i>..." teaser banner (default: $<a href="postconf.5.h
|
||||
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
|
||||
spambots so that they speak before their turn. It has no effect on
|
||||
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
|
||||
@@ -262,7 +270,9 @@ hide "password" information in DNSBL domain names.
|
||||
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>
|
||||
|
||||
<b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i>
|
||||
<pre>
|
||||
<b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i>
|
||||
</pre>
|
||||
|
||||
<p> Translation: the SMTP client at <i>address</i> has a combined
|
||||
DNSBL score of <i>count</i>. </p>
|
||||
@@ -359,7 +369,7 @@ to send multiple commands. postscreen(8)'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
|
||||
spambots that send multiple commands, instead of sending one command
|
||||
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
|
||||
@@ -392,7 +402,7 @@ feature to block these clients. postscreen(8)'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 spambots that send commands specified with the
|
||||
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
|
||||
@@ -695,7 +705,7 @@ Postfix SMTP servers dramatically. </p>
|
||||
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
|
||||
spambots that haven't yet been blacklisted. </p>
|
||||
zombies that haven't yet been blacklisted. </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
|
||||
|
@@ -19,15 +19,14 @@
|
||||
|
||||
<p> The Postfix postscreen(8) server performs triage on multiple
|
||||
inbound SMTP connections in parallel. While a single postscreen(8)
|
||||
process keeps spambots away from Postfix SMTP server processes,
|
||||
process keeps zombies away from Postfix SMTP server processes,
|
||||
more Postfix SMTP server processes remain available for legitimate
|
||||
clients. </p>
|
||||
|
||||
<p> By doing these checks in a single postscreen(8) process, Postfix
|
||||
can avoid wasting one SMTP server process per connection. A side
|
||||
benefit of postscreen(8)'s DNSBL lookups is that DNS records are
|
||||
already cached before the Postfix SMTP server looks them up later.
|
||||
</p>
|
||||
can avoid wasting one SMTP server process per zombie. A side benefit
|
||||
of postscreen(8)'s DNSBL lookups is that DNS records will already be
|
||||
cached before the Postfix SMTP server looks them up later. </p>
|
||||
|
||||
<p> Topics in this document: </p>
|
||||
|
||||
@@ -57,30 +56,39 @@ already cached before the Postfix SMTP server looks them up later.
|
||||
|
||||
<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2>
|
||||
|
||||
<p> Spambots have a limited amount of time to send out spam before
|
||||
they become blacklisted. For this reason, spambots make compromises
|
||||
in their SMTP protocol implementation to speed up spam deliveries.
|
||||
For example, they speak before their turn, or they ignore responses
|
||||
from SMTP servers. </p>
|
||||
<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 postscreen(8) that keeps the zombies away, Postfix would be
|
||||
spending most of its resources not receiving email. </p>
|
||||
|
||||
<p> Many spambots avoid spamming the same site repeatedly, in an
|
||||
attempt to fly under the radar. Thus, postscreen(8) must make a
|
||||
long-term decision after a single measurement. For example, allow
|
||||
a good client to skip the "<a href="#pregreet">pregreet</a>" test
|
||||
for 24 hours. </p>
|
||||
<p> The main challenge for postscreen(8) is to make an is-it-a-zombie
|
||||
decision based on a single measurement. This is necessary because
|
||||
many zombies avoid spamming the same site repeatedly, in an attempt
|
||||
to fly under the radar. Once postscreen(8) decides that a client
|
||||
is not-a-zombie, it whitelists the client temporarily to avoid
|
||||
further delays for legitimate mail. </p>
|
||||
|
||||
<p> To recognize spambots, postscreen(8) measures properties of the
|
||||
client IP address and of the client SMTP protocol implementation
|
||||
(the protocol compromises that were made to speed up delivery).
|
||||
These properties don't change with delivery attempts, and are
|
||||
therefore suitable for making a long-term decision after a single
|
||||
measurement. </p>
|
||||
<p> Zombies have challenges too: they have only a limited amount
|
||||
of time to deliver spam before their IP address becomes blacklisted.
|
||||
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> postscreen(8) does not inspect message content. The reason is
|
||||
that content can change with each delivery attempt, especially with
|
||||
legitimate clients. Message content is not good for making a long-term
|
||||
decision after a single measurement, and that is the problem that
|
||||
postscreen(8) is focused on. </p>
|
||||
<p> postscreen(8) uses a variety of measurements to recognize
|
||||
zombies. First, postscreen(8) determines if the remote SMTP client
|
||||
IP address is blacklisted. Second, postscreen(8) looks for protocol
|
||||
compromises that are made to speed up delivery. The results of
|
||||
such measurements don't change with each delivery attempt, and are
|
||||
therefore good for making an is-it-a-zombie decision based on a
|
||||
single measurement. </p>
|
||||
|
||||
<p> postscreen(8) does not inspect message content. Message content
|
||||
can vary widely with each delivery attempt, especially with clients
|
||||
that (also) send legitimate email. Content is therefore not good
|
||||
for making an is-it-a-zombie decision based on a single measurement,
|
||||
and that is the problem that postscreen(8) is focused on. </p>
|
||||
|
||||
<h2> <a name="general"> General operation </a> </h2>
|
||||
|
||||
@@ -100,7 +108,7 @@ to reject mail from clients that fail one or more tests, after
|
||||
logging the helo, sender and recipient information. </p>
|
||||
|
||||
<p> Note: postscreen(8) is not an SMTP proxy; this is intentional.
|
||||
The purpose is to keep spambots away from Postfix, with minimal
|
||||
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>
|
||||
@@ -196,7 +204,7 @@ for the short postscreen_greet_wait delay). </p>
|
||||
<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. postscreen(8) detects spambots
|
||||
server speaks before the client. postscreen(8) detects zombies
|
||||
that are in a hurry and that speak before their turn. This test is
|
||||
enabled by default. </p>
|
||||
|
||||
@@ -205,7 +213,7 @@ portion of a "220-<i>text</i>..." teaser banner (default: $smtpd_banner).
|
||||
Note that this becomes the first part of a multi-line server greeting.
|
||||
The postscreen(8) daemon sends this before the postscreen_greet_wait
|
||||
timer is started. The purpose of the teaser banner is to confuse
|
||||
spambots so that they speak before their turn. It has no effect on
|
||||
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
|
||||
@@ -262,7 +270,9 @@ hide "password" information in DNSBL domain names.
|
||||
DNSBL score is equal to or greater than the postscreen_dnsbl_threshold
|
||||
parameter value, postscreen(8) logs this as: </p>
|
||||
|
||||
<b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i>
|
||||
<pre>
|
||||
<b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i>
|
||||
</pre>
|
||||
|
||||
<p> Translation: the SMTP client at <i>address</i> has a combined
|
||||
DNSBL score of <i>count</i>. </p>
|
||||
@@ -359,7 +369,7 @@ to send multiple commands. postscreen(8)'s <a href="#after_220">deep
|
||||
protocol test</a> for this is disabled by default. </p>
|
||||
|
||||
<p> With "postscreen_pipelining_enable = yes", postscreen(8) detects
|
||||
spambots that send multiple commands, instead of sending one command
|
||||
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 postscreen(8) has
|
||||
@@ -392,7 +402,7 @@ feature to block these clients. postscreen(8)'s <a href="#after_220">deep
|
||||
protocol test</a> for this is disabled by default. </p>
|
||||
|
||||
<p> With "postscreen_non_smtp_command_enable = yes", postscreen(8)
|
||||
detects spambots that send commands specified with the
|
||||
detects zombies that send commands specified with the
|
||||
postscreen_forbidden_commands 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
|
||||
@@ -695,7 +705,7 @@ Postfix SMTP servers dramatically. </p>
|
||||
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
|
||||
spambots that haven't yet been blacklisted. </p>
|
||||
zombies that haven't yet been blacklisted. </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
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20100918"
|
||||
#define MAIL_RELEASE_DATE "20100923"
|
||||
#define MAIL_VERSION_NUMBER "2.8"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@@ -560,7 +560,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
|
||||
/* Not: PS_PASS_SESSION_STATE. Repeat this test the next time. */
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: unknown pregreet action value %d",
|
||||
msg_panic("%s: unknown blacklist action value %d",
|
||||
myname, ps_blist_action);
|
||||
}
|
||||
}
|
||||
@@ -580,7 +580,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
|
||||
if (msg_verbose)
|
||||
msg_info("%s: cached + recent flags: %s",
|
||||
myname, ps_print_state_flags(state->flags, myname));
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_TODO) == 0) {
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_TODO_FAIL) == 0) {
|
||||
msg_info("PASS OLD %s", state->smtp_client_addr);
|
||||
ps_conclude(state);
|
||||
return;
|
||||
|
@@ -186,6 +186,12 @@ typedef struct {
|
||||
#define PS_STATE_FLAG_ANY_TODO \
|
||||
(PS_STATE_FLAG_EARLY_TODO | PS_STATE_FLAG_SMTPD_TODO)
|
||||
|
||||
#define PS_STATE_FLAG_ANY_TODO_FAIL \
|
||||
(PS_STATE_FLAG_ANY_TODO | PS_STATE_FLAG_ANY_FAIL)
|
||||
|
||||
#define PS_STATE_FLAG_ANY_UPDATE \
|
||||
(PS_STATE_FLAG_ANY_PASS)
|
||||
|
||||
/*
|
||||
* See log_adhoc.c for discussion.
|
||||
*/
|
||||
@@ -383,6 +389,7 @@ extern void ps_dnsbl_request(const char *, void (*) (int, char *), char *);
|
||||
(dst)->pregr_stamp = PS_TIME_STAMP_INVALID; \
|
||||
(dst)->dnsbl_stamp = PS_TIME_STAMP_INVALID; \
|
||||
(dst)->pipel_stamp = PS_TIME_STAMP_INVALID; \
|
||||
(dst)->barlf_stamp = PS_TIME_STAMP_INVALID; \
|
||||
} while (0)
|
||||
#define PS_BEGIN_TESTS(state, name) do { \
|
||||
(state)->test_name = (name); \
|
||||
@@ -411,7 +418,7 @@ extern void ps_smtpd_init(void);
|
||||
/*
|
||||
* postscreen_misc.c
|
||||
*/
|
||||
extern char *ps_format_delta_time(VSTRING *, struct timeval, int *);
|
||||
extern char *ps_format_delta_time(VSTRING *, struct timeval, DELTA_TIME *);
|
||||
extern void ps_conclude(PS_STATE *);
|
||||
extern void ps_hangup_event(PS_STATE *);
|
||||
|
||||
|
@@ -58,7 +58,7 @@ static void ps_early_event(int event, char *context)
|
||||
char read_buf[PS_READ_BUF_SIZE];
|
||||
int read_count;
|
||||
int dnsbl_score;
|
||||
int elapsed;
|
||||
DELTA_TIME elapsed;
|
||||
const char *dnsbl_name;
|
||||
|
||||
if (msg_verbose > 1)
|
||||
@@ -206,13 +206,13 @@ static void ps_early_event(int event, char *context)
|
||||
* EVENT_TIME, instead of calling ps_early_event recursively.
|
||||
*/
|
||||
state->flags |= PS_STATE_FLAG_PREGR_DONE;
|
||||
if (elapsed >= PS_EFF_GREET_WAIT
|
||||
if (elapsed.dt_sec >= PS_EFF_GREET_WAIT
|
||||
|| ((state->flags & PS_STATE_FLAG_EARLY_DONE)
|
||||
== PS_STATE_FLAGS_TODO_TO_DONE(state->flags & PS_STATE_FLAG_EARLY_TODO)))
|
||||
ps_early_event(EVENT_TIME, context);
|
||||
else
|
||||
event_request_timer(ps_early_event, context,
|
||||
PS_EFF_GREET_WAIT - elapsed);
|
||||
PS_EFF_GREET_WAIT - elapsed.dt_sec);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@
|
||||
/* char *ps_format_delta_time(buf, tv, delta)
|
||||
/* VSTRING *buf;
|
||||
/* struct timeval tv;
|
||||
/* int *delta;
|
||||
/* DELTA_TIME *delta;
|
||||
/*
|
||||
/* void ps_conclude(state)
|
||||
/* PS_STATE *state;
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
/* ps_format_delta_time - pretty-formatted delta time */
|
||||
|
||||
char *ps_format_delta_time(VSTRING *buf, struct timeval tv, int *delta)
|
||||
char *ps_format_delta_time(VSTRING *buf, struct timeval tv, DELTA_TIME *delta)
|
||||
{
|
||||
DELTA_TIME pdelay;
|
||||
struct timeval now;
|
||||
@@ -75,7 +75,7 @@ char *ps_format_delta_time(VSTRING *buf, struct timeval tv, int *delta)
|
||||
PS_CALC_DELTA(pdelay, now, tv);
|
||||
VSTRING_RESET(buf);
|
||||
format_tv(buf, pdelay.dt_sec, pdelay.dt_usec, SIG_DIGS, var_delay_max_res);
|
||||
*delta = pdelay.dt_sec;
|
||||
*delta = pdelay;
|
||||
return (STR(buf));
|
||||
}
|
||||
|
||||
@@ -95,26 +95,26 @@ void ps_conclude(PS_STATE *state)
|
||||
* blacklisting. There may still be unfinished tests; those tests will
|
||||
* need to be completed when the client returns in a later session.
|
||||
*/
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_PASS) != 0
|
||||
&& (state->flags & PS_STATE_FLAG_ANY_FAIL) == 0) {
|
||||
if (state->flags & PS_STATE_FLAG_ANY_FAIL)
|
||||
state->flags &= ~PS_STATE_FLAG_ANY_PASS;
|
||||
|
||||
/*
|
||||
* Log our final blessing when all unfinished tests were completed.
|
||||
*/
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_PASS) ==
|
||||
PS_STATE_FLAGS_TODO_TO_PASS(state->flags & PS_STATE_FLAG_ANY_TODO))
|
||||
msg_info("PASS %s %s", (state->flags & PS_STATE_FLAG_NEW) == 0 ?
|
||||
"OLD" : "NEW", state->smtp_client_addr);
|
||||
/*
|
||||
* Log our final blessing when all unfinished tests were completed.
|
||||
*/
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_PASS) ==
|
||||
PS_STATE_FLAGS_TODO_TO_PASS(state->flags & PS_STATE_FLAG_ANY_TODO))
|
||||
msg_info("PASS %s %s", (state->flags & PS_STATE_FLAG_NEW) == 0 ?
|
||||
"OLD" : "NEW", state->smtp_client_addr);
|
||||
|
||||
/*
|
||||
* Update the postscreen cache. This still supports a scenario where
|
||||
* a client gets whitelisted in the course of multiple sessions, as
|
||||
* long as that client does not "fail" any test.
|
||||
*/
|
||||
if (ps_cache_map != 0) {
|
||||
ps_print_tests(ps_temp, state);
|
||||
ps_cache_update(ps_cache_map, state->smtp_client_addr, STR(ps_temp));
|
||||
}
|
||||
/*
|
||||
* Update the postscreen cache. This still supports a scenario where a
|
||||
* client gets whitelisted in the course of multiple sessions, as long as
|
||||
* that client does not "fail" any test.
|
||||
*/
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_UPDATE) != 0
|
||||
&& ps_cache_map != 0) {
|
||||
ps_print_tests(ps_temp, state);
|
||||
ps_cache_update(ps_cache_map, state->smtp_client_addr, STR(ps_temp));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -123,7 +123,7 @@ void ps_conclude(PS_STATE *state)
|
||||
if ((state->flags & PS_STATE_FLAG_NOFORWARD) == 0) {
|
||||
ps_send_socket(state);
|
||||
} else {
|
||||
if ((state->flags & PS_STATE_FLAG_HANGUP) == 0)
|
||||
if ((state->flags & PS_STATE_FLAG_HANGUP) == 0)
|
||||
(void) ps_send_reply(vstream_fileno(state->smtp_client_stream),
|
||||
state->smtp_client_addr, state->smtp_client_port,
|
||||
state->final_reply);
|
||||
@@ -136,7 +136,7 @@ void ps_conclude(PS_STATE *state)
|
||||
|
||||
void ps_hangup_event(PS_STATE *state)
|
||||
{
|
||||
int elapsed;
|
||||
DELTA_TIME elapsed;
|
||||
|
||||
/*
|
||||
* Sessions can break at any time, even after the client passes all tests
|
||||
|
@@ -191,11 +191,17 @@ void ps_parse_tests(PS_STATE *state,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((state->pregr_stamp = pregr_stamp) == PS_TIME_STAMP_NEW
|
||||
|| (state->dnsbl_stamp = dnsbl_stamp) == PS_TIME_STAMP_NEW
|
||||
|| (state->pipel_stamp = pipel_stamp) == PS_TIME_STAMP_NEW
|
||||
|| (state->nsmtp_stamp = nsmtp_stamp) == PS_TIME_STAMP_NEW
|
||||
|| (state->barlf_stamp = barlf_stamp) == PS_TIME_STAMP_NEW)
|
||||
state->pregr_stamp = pregr_stamp;
|
||||
state->dnsbl_stamp = dnsbl_stamp;
|
||||
state->pipel_stamp = pipel_stamp;
|
||||
state->nsmtp_stamp = nsmtp_stamp;
|
||||
state->barlf_stamp = barlf_stamp;
|
||||
|
||||
if (pregr_stamp == PS_TIME_STAMP_NEW
|
||||
|| dnsbl_stamp == PS_TIME_STAMP_NEW
|
||||
|| pipel_stamp == PS_TIME_STAMP_NEW
|
||||
|| nsmtp_stamp == PS_TIME_STAMP_NEW
|
||||
|| barlf_stamp == PS_TIME_STAMP_NEW)
|
||||
state->flags |= PS_STATE_FLAG_NEW;
|
||||
|
||||
/*
|
||||
@@ -258,8 +264,8 @@ char *ps_print_tests(VSTRING *buf, PS_STATE *state)
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_PASS) == 0)
|
||||
msg_panic("%s: attempt to save a no-pass record", myname);
|
||||
if ((state->flags & PS_STATE_FLAG_ANY_UPDATE) == 0)
|
||||
msg_panic("%s: attempt to save a no-update record", myname);
|
||||
|
||||
/*
|
||||
* Give disabled tests a dummy time stamp so that we don't log a client
|
||||
|
Reference in New Issue
Block a user