mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-29 13:18:12 +00:00
postfix-2.6.0-RC1
This commit is contained in:
parent
d41ba831a2
commit
3aaebc8ac7
@ -15080,3 +15080,14 @@ Apologies for any names omitted.
|
||||
compatibility. Adding such headers to remote mail can break
|
||||
DKIM signatures that cover headers that are not present.
|
||||
File: cleanup/cleanup_message.c.
|
||||
|
||||
20090415
|
||||
|
||||
Workaround: to avoid unnecessary "fatal" delivery agent
|
||||
exits, delivery agents retry getting a shared lock on a
|
||||
queue file. This is necessary since the queue manager's
|
||||
behavior was changed years ago to refill the in-memory
|
||||
recipient list before it was completely empty. File:
|
||||
global/deliver_request.c.
|
||||
|
||||
Documentation: updated STRESS_README.
|
||||
|
@ -12,6 +12,7 @@ GGeenneerraall ccoonnffiigguurraattiioonn
|
||||
* TLS_README: TLS Encryption and authentication
|
||||
* TLS_LEGACY_README: Legacy TLS support
|
||||
* IPV6_README: IP Version 6 Support
|
||||
* MULTI_INSTANCE_README: Multiple-instance management
|
||||
* INSTALL: Installation from source code
|
||||
|
||||
PPrroobblleemm ssoollvviinngg
|
||||
|
@ -88,9 +88,9 @@ Notes:
|
||||
attribute, sends the attribute with an empty value ("name="), or sends a
|
||||
zero value ("name=0") in the case of a numerical attribute.
|
||||
|
||||
* The "recipient" attribute is available only in the "RCPT TO" stage, and in
|
||||
the "DATA" and "END-OF-MESSAGE" stages when Postfix accepted only one
|
||||
recipient for the current message.
|
||||
* The "recipient" attribute is available in the "RCPT TO" stage. It is also
|
||||
available in the "DATA" and "END-OF-MESSAGE" stages if Postfix accepted
|
||||
only one recipient for the current message.
|
||||
|
||||
* The "recipient_count" attribute (Postfix 2.3 and later) is non-zero only in
|
||||
the "DATA" and "END-OF-MESSAGE" stages. It specifies the number of
|
||||
|
@ -4,12 +4,11 @@ PPoossttffiixx SSttrreessss--DDeeppeennddeenntt CCoonn
|
||||
|
||||
OOvveerrvviieeww
|
||||
|
||||
This document describes the symptoms of Postfix SMTP server overload, and how
|
||||
to avoid the condition under normal conditions. When the condition is caused by
|
||||
botnets or other malware, the document suggests configuration settings that
|
||||
help to minimize the impact on legitimate mail. Finally, the document
|
||||
introduces stress-adaptive behavior, introduced with Postfix 2.5, and how it
|
||||
can be used to automatically switch configuration settings under overload.
|
||||
This document describes the symptoms of Postfix SMTP server overload. It
|
||||
presents permanent main.cf changes to avoid overload during normal operation,
|
||||
and temporary main.cf changes to cope with an unexpected burst of mail. This
|
||||
document makes specific suggestions for Postfix 2.5 and later which support
|
||||
stress-adaptive behavior, and for earlier Postfix versions that don't.
|
||||
|
||||
Topics covered in this document:
|
||||
|
||||
@ -17,42 +16,46 @@ Topics covered in this document:
|
||||
* Service more SMTP clients at the same time
|
||||
* Spend less time per SMTP client
|
||||
* Disconnect suspicious SMTP clients
|
||||
* Take desperate measures
|
||||
* Make Postfix behavior stress-adaptive
|
||||
* Temporary measures for older Postfix releases
|
||||
* Automatic stress-adaptive behavior
|
||||
* Detecting support for stress-adaptive behavior
|
||||
* Forcing stress-adaptive behavior on or off
|
||||
* Other measures to off-load zombies
|
||||
* Credits
|
||||
|
||||
SSyymmppttoommss ooff PPoossttffiixx SSMMTTPP sseerrvveerr oovveerrllooaadd
|
||||
|
||||
Under normal conditions, Postfix responds immediately when a remote SMTP client
|
||||
connects. The time needed to deliver mail should be noticeable only with very
|
||||
large messages. Performance degrades more dramatically when the number of
|
||||
remote SMTP clients exceeds the number of Postfix SMTP server processes. When a
|
||||
client connects while all server processes are busy, the client must wait until
|
||||
a server process becomes available.
|
||||
Under normal conditions, the Postfix SMTP server responds immediately when an
|
||||
SMTP client connects to it; the time to deliver mail is noticeable only with
|
||||
large messages. Performance degrades dramatically when the number of SMTP
|
||||
clients exceeds the number of Postfix SMTP server processes. When an SMTP
|
||||
client connects while all Postfix SMTP server processes are busy, the client
|
||||
must wait until a server process becomes available.
|
||||
|
||||
Overload may be caused by a legitimate mail (example: a DNS registrar opens a
|
||||
new zone for registrations), by mistake (mail explosion caused by a forwarding
|
||||
loop) or by illegitimate mail (worm outbreak, botnet, or other malware
|
||||
activity). Symptoms of Postfix SMTP mail server overload are:
|
||||
SMTP server overload may be caused by a surge of legitimate mail (example: a
|
||||
DNS registrar opens a new zone for registrations), by mistake (mail explosion
|
||||
caused by a forwarding loop) or by malice (worm outbreak, botnet, or other
|
||||
illegitimate activity).
|
||||
|
||||
Symptoms of Postfix SMTP server overload are:
|
||||
|
||||
* Remote SMTP clients experience a long delay before Postfix sends the "220
|
||||
hostname.example.com ESMTP Postfix" greeting. If this affects end-user mail
|
||||
clients, enable the "submission" service entry in master.cf (present since
|
||||
Postfix 2.1), and tell users to connect to this instead of the public SMTP
|
||||
service.
|
||||
hostname.example.com ESMTP Postfix" greeting.
|
||||
|
||||
o NOTE: Broken DNS configurations also cause lengthy delays before
|
||||
Postfix sends "220 hostname.example.com ...". In this case the delay
|
||||
happens even when Postfix is not busy.
|
||||
o NOTE: Broken DNS configurations can also cause lengthy delays before
|
||||
Postfix sends "220 hostname.example.com ...". These delays also exist
|
||||
when Postfix is NOT overloaded.
|
||||
|
||||
o NOTE: To avoid "overload" delays for end-user mail clients, enable the
|
||||
"submission" service entry in master.cf (present since Postfix 2.1),
|
||||
and tell users to connect to this instead of the public SMTP service.
|
||||
|
||||
* The Postfix SMTP server logs an increased number of "lost connection after
|
||||
CONNECT" events. This happens because remote SMTP clients disconnect before
|
||||
Postfix answers the connection.
|
||||
|
||||
o NOTE: A portscan for open SMTP ports also results in "lost connection
|
||||
..." logfile messages.
|
||||
o NOTE: A portscan for open SMTP ports can also result in "lost
|
||||
connection ..." logfile messages.
|
||||
|
||||
* Postfix 2.3 and later logs a warning that all server ports are busy:
|
||||
|
||||
@ -63,15 +66,16 @@ activity). Symptoms of Postfix SMTP mail server overload are:
|
||||
condition, increase the process count in master.cf or reduce the
|
||||
service time per client
|
||||
|
||||
Legitimate mail that doesn't get through during an episode of overload is not
|
||||
necessarily lost. It should still arrive once the situation returns to normal,
|
||||
as long as the overload condition is temporary.
|
||||
Legitimate mail that doesn't get through during an episode of Postfix SMTP
|
||||
server overload is not necessarily lost. It should still arrive once the
|
||||
situation returns to normal, as long as the overload condition is temporary.
|
||||
|
||||
SSeerrvviiccee mmoorree SSMMTTPP cclliieennttss aatt tthhee ssaammee ttiimmee
|
||||
|
||||
To service more SMTP clients simultaneously, you need to increase the number of
|
||||
SMTP server processes. This will improve the responsiveness for remote SMTP
|
||||
clients, as long as the server machine has enough hardware and software
|
||||
One measure to avoid the "all server processes busy" condition is to service
|
||||
more SMTP clients simultaneously. For this you need to increase the number of
|
||||
Postfix SMTP server processes. This will improve the responsiveness for remote
|
||||
SMTP clients, as long as the server machine has enough hardware and software
|
||||
resources to run the additional processes, and as long as the file system can
|
||||
keep up with the additional load.
|
||||
|
||||
@ -84,8 +88,9 @@ keep up with the additional load.
|
||||
operating system that supports kernel-based event filters (BSD kqueue(2),
|
||||
Linux epoll(4), or Solaris /dev/poll).
|
||||
|
||||
* You can reduce the Postfix memory footprint by using cdb: lookup tables
|
||||
instead of Berkeley DB's hash: or btree: tables.
|
||||
* More processes use more memory. You can reduce the Postfix memory footprint
|
||||
by using cdb: lookup tables instead of Berkeley DB's hash: or btree:
|
||||
tables.
|
||||
|
||||
1 /etc/postfix/main.cf:
|
||||
2 # Raise the global process limit, 100 since Postfix 2.0.
|
||||
@ -120,9 +125,9 @@ keep up with the additional load.
|
||||
SSppeenndd lleessss ttiimmee ppeerr SSMMTTPP cclliieenntt
|
||||
|
||||
When increasing the number of SMTP server processes is not practical, you can
|
||||
improve Postfix server responsiveness by eliminating unnecessary work. When
|
||||
Postfix spends less time per SMTP session, the same number of SMTP server
|
||||
processes can service more clients in the same amount of time.
|
||||
improve Postfix server responsiveness by eliminating delays. When Postfix
|
||||
spends less time per SMTP session, the same number of SMTP server processes can
|
||||
service more clients in a given amount of time.
|
||||
|
||||
* Eliminate non-functional RBL lookups (blocklists that are no longer in
|
||||
operation). These lookups can degrade performance. Postfix logs a warning
|
||||
@ -137,18 +142,18 @@ processes can service more clients in the same amount of time.
|
||||
BACKSCATTER_README for examples of the latter.
|
||||
|
||||
* Group your header_checks and body_checks patterns to avoid unnecessary
|
||||
pattern matching operations.
|
||||
pattern matching operations:
|
||||
|
||||
1 /etc/postfix/header_checks:
|
||||
2 if /^Subject:/
|
||||
3 /^Subject: virus found in mail from you/ reject
|
||||
4 /^Subject: ..../ ....
|
||||
4 /^Subject: ..other../ reject
|
||||
5 endif
|
||||
6
|
||||
7 if /^Received:/
|
||||
8 /^Received: from (postfix\.org) / reject forged client name in
|
||||
received header: $1
|
||||
9 /^Received: from .../ ....
|
||||
9 /^Received: from ..other../ reject ....
|
||||
10 endif
|
||||
|
||||
DDiissccoonnnneecctt ssuussppiicciioouuss SSMMTTPP cclliieennttss
|
||||
@ -157,14 +162,16 @@ Under conditions of overload you can improve Postfix SMTP server responsiveness
|
||||
by hanging up on suspicious clients, so that other clients get a chance to talk
|
||||
to Postfix.
|
||||
|
||||
* Use "521" reply codes (Postfix 2.6 and later) for botnet-related RBLs or
|
||||
for selected non-RBL restrictions. With Postfix 2.3-2.5 use "421" for a
|
||||
similar result. The Postfix SMTP server will disconnect immediately without
|
||||
* Use "521" SMTP reply codes (Postfix 2.6 and later) or "421" (Postfix 2.3-
|
||||
2.5) to hang up on clients that that match botnet-related RBLs (see next
|
||||
bullet) or that match selected non-RBL restrictions such as SMTP access
|
||||
maps. The Postfix SMTP server will reject mail and disconnect without
|
||||
waiting for the remote SMTP client to send a QUIT command.
|
||||
|
||||
You can set individual reject codes for RBLs, and for individual responses
|
||||
from a specific RBL. We'll use zen.spamhaus.org as an example; by the time
|
||||
you read this document, details may have changed. Right now, their
|
||||
* To hang up connections from blacklisted zombies, you can set specific
|
||||
Postfix SMTP server reject codes for specific RBLs, and for individual
|
||||
responses from specific RBLs. We'll use zen.spamhaus.org as an example; by
|
||||
the time you read this document, details may have changed. Right now, their
|
||||
documents say that a response of 127.0.0.10 or 127.0.0.11 indicates a
|
||||
dynamic client IP address, which means that the machine is probably running
|
||||
a bot of some kind. To give a 521 response instead of the default 554
|
||||
@ -180,37 +187,45 @@ to Postfix.
|
||||
8 rbl_reply_maps = hash:/etc/postfix/rbl_reply_maps
|
||||
9
|
||||
10 /etc/postfix/rbl_reply_maps:
|
||||
11 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable;
|
||||
12 $rbl_class [$rbl_what] blocked using
|
||||
13 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
14
|
||||
15 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable;
|
||||
16 $rbl_class [$rbl_what] blocked using
|
||||
17 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
11 # With Postfix 2.3-2.5 use "421" to hang up connections.
|
||||
12 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable;
|
||||
13 $rbl_class [$rbl_what] blocked using
|
||||
14 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
15
|
||||
16 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable;
|
||||
17 $rbl_class [$rbl_what] blocked using
|
||||
18 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
|
||||
Although the above shows three RBL lookups (lines 4-6), Postfix will still
|
||||
only do a single DNS query, so the performance difference is negligible.
|
||||
Although the above example shows three RBL lookups (lines 4-6), Postfix
|
||||
will only do a single DNS query, so it does not affect the performance.
|
||||
|
||||
With Postfix 2.3-2.5, use 421 (reply code 521 will not cause Postfix to
|
||||
disconnect). The down-side of sending 421 is that it works only for zombies
|
||||
and other malware. If the client is running a real MTA, then it may connect
|
||||
again several times until the mail expires in its queue. When this is a
|
||||
problem, stick with the default 554 reply, and use "smtpd_hard_error_limit
|
||||
= 1" as described below.
|
||||
* With Postfix 2.3-2.5, use reply code 421 (521 will not cause Postfix to
|
||||
disconnect). The down-side of replying with 421 is that it works only for
|
||||
zombies and other malware. If the client is running a real MTA, then it may
|
||||
connect again several times until the mail expires in its queue. When this
|
||||
is a problem, stick with the default 554 reply, and use
|
||||
"smtpd_hard_error_limit = 1" as described below.
|
||||
|
||||
With Postfix 2.5, or with earlier releases that contain the stress-adaptive
|
||||
behavior patch, you can turn on the above under overload by replacing line
|
||||
8 with:
|
||||
* You can automatically turn on the above overload measure with Postfix 2.5
|
||||
and later, or with earlier releases that contain the stress-adaptive
|
||||
behavior source code patch from the mirrors listed at http://
|
||||
www.postfix.org/download.html. Simply replace line above 8 with:
|
||||
|
||||
8 rbl_reply_maps = ${stress?hash:/etc/postfix/rbl_reply_maps}
|
||||
|
||||
More information about automatic stress-adaptive behavior is at the end of
|
||||
this document.
|
||||
More information about automatic stress-adaptive behavior is in section
|
||||
"Automatic stress-adaptive behavior".
|
||||
|
||||
TTaakkee ddeessppeerraattee mmeeaassuurreess
|
||||
TTeemmppoorraarryy mmeeaassuurreess ffoorr oollddeerr PPoossttffiixx rreelleeaasseess
|
||||
|
||||
The following measures will still allow mmoosstt legitimate clients to connect and
|
||||
send mail, but may affect some legitimate clients.
|
||||
See the next section, "Automatic stress-adaptive behavior", if you are running
|
||||
Postfix version 2.5 or later, or if you have applied the source code patch for
|
||||
stress-adaptive behavior from the mirrors listed at http://www.postfix.org/
|
||||
download.html.
|
||||
|
||||
The following measures can be applied temporarily during overload. They still
|
||||
allow mmoosstt legitimate clients to connect and send mail, but may affect some
|
||||
legitimate clients.
|
||||
|
||||
* Reduce smtpd_timeout (default: 300s). Experience on the postfix-users list
|
||||
from a variety of sysadmins shows that reducing the "normal" smtpd_timeout
|
||||
@ -228,55 +243,75 @@ send mail, but may affect some legitimate clients.
|
||||
longer-active user names that didn't bother to unsubscribe. No mail should
|
||||
be lost, as long as this measure is used only temporarily.
|
||||
|
||||
* Disable remote SMTP client hostname lookups, so that all SMTP client
|
||||
hostnames become "unknown" (line 5 below). This feature was introduced with
|
||||
Postfix 2.3. Unfortunately, this measure is more problematic than the other
|
||||
ones proposed sofar. First, this will result in loss of mail when you use
|
||||
hostname-based access rules that reject mail from "unknown" SMTP clients
|
||||
(examples: reject_unknown_client_hostname,
|
||||
reject_unknown_reverse_client_hostname). Second, this may result in loss of
|
||||
mail when you subject "unknown" SMTP clients to additional restrictions
|
||||
such as reject_unverified_sender.
|
||||
* Use an smtpd_junk_command_limit of 1 instead of the default 100. This
|
||||
prevents clients from keeping idle connections open by repeatedly sending
|
||||
NOOP or RSET commands.
|
||||
|
||||
1 /etc/postfix/main.cf:
|
||||
2 smtpd_timeout = 10
|
||||
3 smtpd_hard_error_limit = 1
|
||||
4 # Caution: line 5 may trigger REJECTs by hostname-based access rules
|
||||
4 smtpd_junk_command_limit = 1
|
||||
|
||||
5 smtpd_peername_lookup = no
|
||||
With these measures, no mail should be lost, as long as these measures are used
|
||||
only temporarily. The next section of this document introduces a way to
|
||||
automate this process.
|
||||
|
||||
Except with the last measure, no mail should be lost, as long as these measures
|
||||
are used only temporarily. The next section of this document introduces a way
|
||||
to automate this process.
|
||||
|
||||
MMaakkee PPoossttffiixx bbeehhaavviioorr ssttrreessss--aaddaappttiivvee
|
||||
AAuuttoommaattiicc ssttrreessss--aaddaappttiivvee bbeehhaavviioorr
|
||||
|
||||
Postfix version 2.5 introduces automatic stress-adaptive behavior. This is also
|
||||
available as an add-on patch for Postfix versions 2.4 and 2.3 from the mirrors
|
||||
listed at http://www.postfix.org/download.html.
|
||||
available as a source code patch for Postfix versions 2.4 and 2.3 from the
|
||||
mirrors listed at http://www.postfix.org/download.html.
|
||||
|
||||
It works as follows. When a "public" network service runs into an "all server
|
||||
ports are busy" condition, the master(8) daemon logs a warning, restarts the
|
||||
service (without interrupting existing network sessions), and runs the service
|
||||
with "-o stress=yes" on the command line. Normally, it runs a stress-adaptive
|
||||
service with "-o stress=" on the command line (i.e. with an empty parameter
|
||||
value). Other services never have "-o stress" parameters on the command line,
|
||||
including services that listen on a loopback interface only.
|
||||
It works as follows. When a "public" network service such as the SMTP server
|
||||
runs into an "all server ports are busy" condition, the Postfix master(8)
|
||||
daemon logs a warning, restarts the service (without interrupting existing
|
||||
network sessions), and runs the service with "-o stress=yes" on the server
|
||||
process command line:
|
||||
|
||||
The stress pseudo-parameter value is the key to making main.cf parameter
|
||||
settings stress adaptive:
|
||||
80821 ?? S 0:00.24 smtpd -n smtp -t inet -u -c -o stress=yes
|
||||
|
||||
1 /etc/postfix/main.cf:
|
||||
2 smtpd_timeout = ${stress?10}${stress:300}
|
||||
3 smtpd_hard_error_limit = ${stress?1}${stress:20}
|
||||
Normally, the Postfix master(8) daemon runs such a service with "-o stress=" on
|
||||
the command line (i.e. with an empty parameter value):
|
||||
|
||||
83326 ?? S 0:00.28 smtpd -n smtp -t inet -u -c -o stress=
|
||||
|
||||
Services that have local access only never have "-o stress" parameters on the
|
||||
command line. This includes services internal to Postfix such as the queue
|
||||
manager, and services that listen on a loopback interface only, such as after-
|
||||
filter SMTP services.
|
||||
|
||||
The "stress" parameter value is the key to making main.cf parameter settings
|
||||
stress adaptive. The following settings are the default with Postfix 2.6 and
|
||||
later. With earlier Postfix versions that have stress-adaptive support, append
|
||||
the lines below to the main.cf file and issue a "postfix reload" command:
|
||||
|
||||
1 smtpd_timeout = ${stress?10}${stress:300}s
|
||||
2 smtpd_hard_error_limit = ${stress?1}${stress:20}
|
||||
3 smtpd_junk_command_limit = ${stress?1}${stress:100}
|
||||
|
||||
Translation:
|
||||
|
||||
* Line 2: under conditions of stress, use an smtpd_timeout value of 10
|
||||
seconds instead of the default 300 seconds,
|
||||
* Line 1: under conditions of stress, use an smtpd_timeout value of 10
|
||||
seconds instead of the default 300 seconds. Experience on the postfix-users
|
||||
list from a variety of sysadmins shows that reducing the "normal"
|
||||
smtpd_timeout to 60s is unlikely to affect legitimate clients. However, it
|
||||
is unlikely to become the Postfix default because it's not RFC compliant.
|
||||
Setting smtpd_timeout to 10s (line 2 below) or even 5s under stress will
|
||||
still allow most legitimate clients to connect and send mail, but may delay
|
||||
mail from some clients. No mail should be lost, as long as this measure is
|
||||
used only temporarily.
|
||||
|
||||
* Line 3: under conditions of stress, use an smtpd_hard_error_limit of 1
|
||||
instead of the default 20.
|
||||
* Line 2: under conditions of stress, use an smtpd_hard_error_limit of 1
|
||||
instead of the default 20. This helps by disconnecting clients after a
|
||||
single error, giving other clients a chance to connect. However, this may
|
||||
cause significant delays with legitimate mail, such as a mailing list that
|
||||
contains a few no-longer-active user names that didn't bother to
|
||||
unsubscribe. No mail should be lost, as long as this measure is used only
|
||||
temporarily.
|
||||
|
||||
* Line 3: under conditions of stress, use an smtpd_junk_command_limit of 1
|
||||
instead of the default 100. This prevents clients from keeping idle
|
||||
connections open by repeatedly sending NOOP or RSET commands.
|
||||
|
||||
The syntax of ${name?value} and ${name:value} is explained at the beginning of
|
||||
the postconf(5) manual page.
|
||||
@ -346,6 +381,18 @@ accept remote connections.
|
||||
7 -o stress=
|
||||
8 -o . . .
|
||||
|
||||
OOtthheerr mmeeaassuurreess ttoo ooffff--llooaadd zzoommbbiieess
|
||||
|
||||
OpenBSD spamd implements a daemon that handles all connections from "new"
|
||||
clients. Only well-behaved mail clients are allowed to talk to the mail server.
|
||||
Other clients are tarpitted, and will never get a chance to affect mail server
|
||||
performance.
|
||||
|
||||
At some point in the future, Postfix may come with a simple front-end daemon
|
||||
that does basic greylisting and pipelining detection to keep zombies and other
|
||||
ratware away from Postfix itself. This would use the "pass" service type which
|
||||
has been available in stable Postfix releases since Postfix 2.5.
|
||||
|
||||
CCrreeddiittss
|
||||
|
||||
* Thanks to the postfix-users mailing list members for sharing early
|
||||
|
@ -9,25 +9,18 @@ Wish list:
|
||||
compatibility. The "first" setting is good for performance
|
||||
(stress=yes) when all users are defined in local files.
|
||||
|
||||
Make the double-bounce address time-dependent (with 24-hour
|
||||
grace period). Spammers appear to use this address to avoid
|
||||
DATA command rejects. Avoiding DATA rejects means they can
|
||||
pipeline the entire SMTP session without triggering huge
|
||||
numbers of protocol errors. They can still trigger "improper
|
||||
command pipelining after DATA" alarms, but that requires
|
||||
non-default main.cf settings.
|
||||
|
||||
Cleanup: make DNSBL query format configurable beyond the
|
||||
client's reversed IP address.
|
||||
|
||||
With 'final delivery' in the LMTP client, need an option
|
||||
to also add delivered-to and other pipe(8) features.
|
||||
This requires making mail_copy() more generic.
|
||||
to also add delivered-to and other pipe(8) features. This
|
||||
requires making mail_copy() functionality available in
|
||||
non-mailbox context.
|
||||
|
||||
To work around historical AWK's limit of 10 open files,
|
||||
pipe all output into a shell and have the shell open files.
|
||||
It's too much pain to find out whose AWK is old and where
|
||||
if any they keep the XPG4 compliant version.
|
||||
It's too much pain to find out what systems use ancient AWK
|
||||
and where, if any, they keep the XPG4 compliant version.
|
||||
|
||||
Cleanup: modernize the "add missing From: header" code, to
|
||||
``phrase <addr>'' form. Most likely, quote the entire phrase
|
||||
|
@ -126,10 +126,10 @@ stress=
|
||||
an empty value ("name="), or sends a zero value ("name=0") in
|
||||
the case of a numerical attribute. </p>
|
||||
|
||||
<li> <p> The "recipient" attribute is available only in the
|
||||
"RCPT TO" stage, and in the "DATA" and "END-OF-MESSAGE" stages
|
||||
when Postfix accepted only one recipient for the current message.
|
||||
</p>
|
||||
<li> <p> The "recipient" attribute is available in the "RCPT
|
||||
TO" stage. It is also available in the "DATA" and "END-OF-MESSAGE"
|
||||
stages if Postfix accepted only one recipient for the current
|
||||
message. </p>
|
||||
|
||||
<li> <p> The "recipient_count" attribute (Postfix 2.3 and later)
|
||||
is non-zero only in the "DATA" and "END-OF-MESSAGE" stages. It
|
||||
|
@ -21,13 +21,11 @@ Stress-Dependent Configuration</h1>
|
||||
<h2>Overview </h2>
|
||||
|
||||
<p> This document describes the symptoms of Postfix SMTP server
|
||||
overload, and how to avoid the condition under normal conditions.
|
||||
When the condition is caused by botnets or other malware, the
|
||||
document suggests configuration settings that help to minimize the
|
||||
impact on legitimate mail. Finally, the document introduces
|
||||
stress-adaptive behavior, introduced with Postfix 2.5, and how it
|
||||
can be used to automatically switch configuration settings under
|
||||
overload. </p>
|
||||
overload. It presents permanent <a href="postconf.5.html">main.cf</a> changes to avoid overload
|
||||
during normal operation, and temporary <a href="postconf.5.html">main.cf</a> changes to cope with
|
||||
an unexpected burst of mail. This document makes specific suggestions
|
||||
for Postfix 2.5 and later which support stress-adaptive behavior,
|
||||
and for earlier Postfix versions that don't. </p>
|
||||
|
||||
<p> Topics covered in this document: </p>
|
||||
|
||||
@ -41,47 +39,52 @@ overload. </p>
|
||||
|
||||
<li><a href="#hangup"> Disconnect suspicious SMTP clients </a>
|
||||
|
||||
<li><a href="#desperate"> Take desperate measures </a>
|
||||
<li><a href="#legacy"> Temporary measures for older Postfix releases </a>
|
||||
|
||||
<li><a href="#adapt"> Make Postfix behavior stress-adaptive </a>
|
||||
<li><a href="#adapt"> Automatic stress-adaptive behavior </a>
|
||||
|
||||
<li><a href="#feature"> Detecting support for stress-adaptive behavior </a>
|
||||
|
||||
<li><a href="#forcing"> Forcing stress-adaptive behavior on or off </a>
|
||||
|
||||
<li><a href="#other"> Other measures to off-load zombies </a>
|
||||
|
||||
<li><a href="#credits"> Credits </a>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2><a name="overload"> Symptoms of Postfix SMTP server overload </a></h2>
|
||||
|
||||
<p> Under normal conditions, Postfix responds immediately when a
|
||||
remote SMTP client connects. The time needed to deliver mail should
|
||||
be noticeable only with very large messages. Performance degrades
|
||||
more dramatically when the number of remote SMTP clients exceeds
|
||||
the number of Postfix SMTP server processes. When a client connects
|
||||
while all server processes are busy, the client must wait until a
|
||||
server process becomes available. </p>
|
||||
<p> Under normal conditions, the Postfix SMTP server responds
|
||||
immediately when an SMTP client connects to it; the time to deliver
|
||||
mail is noticeable only with large messages. Performance degrades
|
||||
dramatically when the number of SMTP clients exceeds the number of
|
||||
Postfix SMTP server processes. When an SMTP client connects while
|
||||
all Postfix SMTP server processes are busy, the client must wait
|
||||
until a server process becomes available. </p>
|
||||
|
||||
<p> Overload may be caused by a legitimate mail (example: a DNS
|
||||
registrar opens a new zone for registrations), by mistake (mail
|
||||
explosion caused by a forwarding loop) or by illegitimate mail (worm
|
||||
outbreak, botnet, or other malware activity). Symptoms of Postfix
|
||||
SMTP mail server overload are: </p>
|
||||
<p> SMTP server overload may be caused by a surge of legitimate
|
||||
mail (example: a DNS registrar opens a new zone for registrations),
|
||||
by mistake (mail explosion caused by a forwarding loop) or by malice
|
||||
(worm outbreak, botnet, or other illegitimate activity). </p>
|
||||
|
||||
<p> Symptoms of Postfix SMTP server overload are: </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Remote SMTP clients experience a long delay before Postfix
|
||||
sends the "220 hostname.example.com ESMTP Postfix" greeting. If
|
||||
this affects end-user mail clients, enable the "submission" service
|
||||
entry in <a href="master.5.html">master.cf</a> (present since Postfix 2.1), and tell users to
|
||||
connect to this instead of the public SMTP service. </p>
|
||||
sends the "220 hostname.example.com ESMTP Postfix" greeting. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> NOTE: Broken DNS configurations also cause lengthy delays
|
||||
before Postfix sends "220 hostname.example.com ...". In this case
|
||||
the delay happens even when Postfix is not busy. </p>
|
||||
<li> <p> NOTE: Broken DNS configurations can also cause lengthy
|
||||
delays before Postfix sends "220 hostname.example.com ...". These
|
||||
delays also exist when Postfix is NOT overloaded. </p>
|
||||
|
||||
<li> <p> NOTE: To avoid "overload" delays for end-user mail
|
||||
clients, enable the "submission" service entry in <a href="master.5.html">master.cf</a> (present
|
||||
since Postfix 2.1), and tell users to connect to this instead of
|
||||
the public SMTP service. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -91,8 +94,8 @@ clients disconnect before Postfix answers the connection. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> NOTE: A portscan for open SMTP ports also results in "lost
|
||||
connection ..." logfile messages. </p>
|
||||
<li> <p> NOTE: A portscan for open SMTP ports can also result in
|
||||
"lost connection ..." logfile messages. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -111,14 +114,16 @@ Oct 3 20:39:27 spike postfix/master[28905]: warning: to avoid this
|
||||
</ul>
|
||||
|
||||
<p> Legitimate mail that doesn't get through during an episode of
|
||||
overload is not necessarily lost. It should still arrive once the
|
||||
situation returns to normal, as long as the overload condition is
|
||||
temporary. </p>
|
||||
Postfix SMTP server overload is not necessarily lost. It should
|
||||
still arrive once the situation returns to normal, as long as the
|
||||
overload condition is temporary. </p>
|
||||
|
||||
<h2><a name="concurrency"> Service more SMTP clients at the same time </a> </h2>
|
||||
|
||||
<p> To service more SMTP clients simultaneously, you need to increase
|
||||
the number of SMTP server processes. This will improve the
|
||||
<p> One measure to avoid the "all server processes busy" condition
|
||||
is to service more SMTP clients simultaneously. For this you need
|
||||
to increase the number of Postfix SMTP server processes. This will
|
||||
improve the
|
||||
responsiveness for remote SMTP clients, as long as the server machine
|
||||
has enough hardware and software resources to run the additional
|
||||
processes, and as long as the file system can keep up with the
|
||||
@ -137,7 +142,8 @@ later, and an operating system that supports kernel-based event
|
||||
filters (BSD kqueue(2), Linux epoll(4), or Solaris /dev/poll).
|
||||
</p>
|
||||
|
||||
<li> <p> You can reduce the Postfix memory footprint by using <a href="CDB_README.html">cdb</a>:
|
||||
<li> <p> More processes use more memory. You can reduce the Postfix
|
||||
memory footprint by using <a href="CDB_README.html">cdb</a>:
|
||||
lookup tables instead of Berkeley DB's hash: or btree: tables. </p>
|
||||
|
||||
<pre>
|
||||
@ -181,9 +187,9 @@ Issue a "postfix reload" command to make the change effective. </p>
|
||||
|
||||
<p> When increasing the number of SMTP server processes is not
|
||||
practical, you can improve Postfix server responsiveness by eliminating
|
||||
unnecessary work. When Postfix spends less time per SMTP session, the
|
||||
same number of SMTP server processes can service more clients in the
|
||||
same amount of time. </p>
|
||||
delays. When Postfix spends less time per SMTP session, the same
|
||||
number of SMTP server processes can service more clients in a given
|
||||
amount of time. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
@ -201,18 +207,18 @@ emergency patterns to block the latest worm explosion or backscatter
|
||||
mail. See <a href="BACKSCATTER_README.html">BACKSCATTER_README</a> for examples of the latter.
|
||||
|
||||
<li> <p> Group your <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a> patterns to avoid
|
||||
unnecessary pattern matching operations.
|
||||
unnecessary pattern matching operations:
|
||||
|
||||
<pre>
|
||||
1 /etc/postfix/header_checks:
|
||||
2 if /^Subject:/
|
||||
3 /^Subject: virus found in mail from you/ reject
|
||||
4 /^Subject: ..../ ....
|
||||
4 /^Subject: ..other../ reject
|
||||
5 endif
|
||||
6
|
||||
7 if /^Received:/
|
||||
8 /^Received: from (postfix\.org) / reject forged client name in received header: $1
|
||||
9 /^Received: from .../ ....
|
||||
9 /^Received: from ..other../ reject ....
|
||||
10 endif
|
||||
</pre>
|
||||
|
||||
@ -226,20 +232,22 @@ clients get a chance to talk to Postfix. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Use "521" reply codes (Postfix 2.6 and later) for
|
||||
botnet-related RBLs or for selected non-RBL restrictions. With
|
||||
Postfix 2.3-2.5 use "421" for a similar result. The Postfix SMTP
|
||||
server will disconnect immediately without waiting for the remote
|
||||
SMTP client to send a QUIT command. </p>
|
||||
<li> <p> Use "521" SMTP reply codes (Postfix 2.6 and later) or "421"
|
||||
(Postfix 2.3-2.5) to hang up on clients that that match botnet-related
|
||||
RBLs (see next bullet) or that match selected non-RBL restrictions
|
||||
such as SMTP access maps. The Postfix SMTP server will reject mail
|
||||
and disconnect without waiting for the remote SMTP client to send
|
||||
a QUIT command. </p>
|
||||
|
||||
<p> You can set individual reject codes for RBLs, and for individual
|
||||
responses from a specific RBL. We'll use zen.spamhaus.org as an
|
||||
example; by the time you read this document, details may have
|
||||
changed. Right now, their documents say that a response of 127.0.0.10
|
||||
or 127.0.0.11 indicates a dynamic client IP address, which means
|
||||
that the machine is probably running a bot of some kind. To give
|
||||
a 521 response instead of the default 554 response, use something
|
||||
like: </p>
|
||||
<li> <p> To hang up connections from blacklisted zombies, you can
|
||||
set specific Postfix SMTP server reject codes for specific RBLs,
|
||||
and for individual responses from specific RBLs. We'll use
|
||||
zen.spamhaus.org as an example; by the time you read this document,
|
||||
details may have changed. Right now, their documents say that a
|
||||
response of 127.0.0.10 or 127.0.0.11 indicates a dynamic client IP
|
||||
address, which means that the machine is probably running a bot of
|
||||
some kind. To give a 521 response instead of the default 554
|
||||
response, use something like: </p>
|
||||
|
||||
<pre>
|
||||
1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
@ -252,45 +260,55 @@ like: </p>
|
||||
8 <a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> = hash:/etc/postfix/rbl_reply_maps
|
||||
9
|
||||
10 /etc/postfix/rbl_reply_maps:
|
||||
11 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable;
|
||||
12 $rbl_class [$rbl_what] blocked using
|
||||
13 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
14
|
||||
15 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable;
|
||||
16 $rbl_class [$rbl_what] blocked using
|
||||
17 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
11 # With Postfix 2.3-2.5 use "421" to hang up connections.
|
||||
12 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable;
|
||||
13 $rbl_class [$rbl_what] blocked using
|
||||
14 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
15
|
||||
16 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable;
|
||||
17 $rbl_class [$rbl_what] blocked using
|
||||
18 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
</pre>
|
||||
|
||||
<p> Although the above shows three RBL lookups (lines 4-6), Postfix
|
||||
will still only do a single DNS query, so the performance difference
|
||||
is negligible. </p>
|
||||
<p> Although the above example shows three RBL lookups (lines 4-6),
|
||||
Postfix will only do a single DNS query, so it does not affect the
|
||||
performance. </p>
|
||||
|
||||
<p> With Postfix 2.3-2.5, use 421 (reply code 521 will not cause
|
||||
Postfix to disconnect). The down-side of sending 421 is that
|
||||
it works only for zombies and other malware. If the client is running
|
||||
a real MTA, then it may connect again several times until the mail
|
||||
expires in its queue. When this is a problem, stick with the default
|
||||
554 reply, and use "<a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> = 1" as described below.
|
||||
</p>
|
||||
<li> <p> With Postfix 2.3-2.5, use reply code 421 (521 will not
|
||||
cause Postfix to disconnect). The down-side of replying with 421
|
||||
is that it works only for zombies and other malware. If the client
|
||||
is running a real MTA, then it may connect again several times until
|
||||
the mail expires in its queue. When this is a problem, stick with
|
||||
the default 554 reply, and use "<a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> = 1" as
|
||||
described below. </p>
|
||||
|
||||
<p> With Postfix 2.5, or with earlier releases that contain the
|
||||
stress-adaptive behavior patch, you can turn on the above under
|
||||
overload by replacing line 8 with: </p>
|
||||
<li> <p> You can automatically turn on the above overload measure
|
||||
with Postfix 2.5 and later, or with earlier releases that contain
|
||||
the stress-adaptive behavior source code patch from the mirrors
|
||||
listed at <a href="http://www.postfix.org/download.html">http://www.postfix.org/download.html</a>. Simply replace line
|
||||
above 8 with: </p>
|
||||
|
||||
<pre>
|
||||
8 <a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> = ${stress?hash:/etc/postfix/rbl_reply_maps}
|
||||
</pre>
|
||||
|
||||
<p> More information about automatic stress-adaptive behavior is
|
||||
at the end of this document. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2><a name="desperate"> Take desperate measures </a></h2>
|
||||
<p> More information about automatic stress-adaptive behavior is
|
||||
in section "<a href="#adapt">Automatic stress-adaptive behavior</a>".
|
||||
</p>
|
||||
|
||||
<p> The following measures will still allow <b>most</b> legitimate
|
||||
clients to connect and send mail, but may affect some legitimate
|
||||
clients. </p>
|
||||
<h2><a name="legacy"> Temporary measures for older Postfix releases </a></h2>
|
||||
|
||||
<p> See the next section, "<a href="#adapt">Automatic stress-adaptive
|
||||
behavior</a>", if you are running Postfix version 2.5 or later, or
|
||||
if you have applied the source code patch for stress-adaptive
|
||||
behavior from the mirrors listed at <a href="http://www.postfix.org/download.html">http://www.postfix.org/download.html</a>.
|
||||
</p>
|
||||
|
||||
<p> The following measures can be applied temporarily during overload.
|
||||
They still allow <b>most</b> legitimate clients to connect and send
|
||||
mail, but may affect some legitimate clients. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
@ -312,16 +330,9 @@ such as a mailing list that contains a few no-longer-active user
|
||||
names that didn't bother to unsubscribe. No mail should be lost,
|
||||
as long as this measure is used only temporarily. </p>
|
||||
|
||||
<li> <p> Disable remote SMTP client hostname lookups, so that all
|
||||
SMTP client hostnames become "unknown" (line 5 below). This feature
|
||||
was introduced with Postfix 2.3. Unfortunately, this measure is
|
||||
more problematic than the other ones proposed sofar. First, this
|
||||
will result in loss of mail when you use hostname-based access rules
|
||||
that reject mail from "unknown" SMTP clients (examples:
|
||||
<a href="postconf.5.html#reject_unknown_client_hostname">reject_unknown_client_hostname</a>, <a href="postconf.5.html#reject_unknown_reverse_client_hostname">reject_unknown_reverse_client_hostname</a>).
|
||||
Second, this may result in loss of mail when you subject "unknown"
|
||||
SMTP clients to additional restrictions such as <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>.
|
||||
</p>
|
||||
<li> <p> Use an <a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> of 1 instead of the default
|
||||
100. This prevents clients from keeping idle connections open by
|
||||
repeatedly sending NOOP or RSET commands. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -330,40 +341,60 @@ SMTP clients to additional restrictions such as <a href="postconf.5.html#reject_
|
||||
1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
2 <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> = 10
|
||||
3 <a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> = 1
|
||||
4 # Caution: line 5 may trigger REJECTs by hostname-based access rules
|
||||
5 <a href="postconf.5.html#smtpd_peername_lookup">smtpd_peername_lookup</a> = no
|
||||
4 <a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> = 1
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Except with the last measure, no mail should be lost, as long
|
||||
<p> With these measures, no mail should be lost, as long
|
||||
as these measures are used only temporarily. The next section of
|
||||
this document introduces a way to automate this process. </p>
|
||||
|
||||
<h2><a name="adapt"> Make Postfix behavior stress-adaptive </a></h2>
|
||||
<h2><a name="adapt"> Automatic stress-adaptive behavior </a></h2>
|
||||
|
||||
<p> Postfix version 2.5 introduces automatic stress-adaptive behavior.
|
||||
This is also available as an add-on patch for Postfix versions 2.4
|
||||
and 2.3 from the mirrors listed at <a href="http://www.postfix.org/download.html">http://www.postfix.org/download.html</a>.
|
||||
</p>
|
||||
This is also available as a source code patch for Postfix versions
|
||||
2.4 and 2.3 from the mirrors listed at
|
||||
<a href="http://www.postfix.org/download.html">http://www.postfix.org/download.html</a>. </p>
|
||||
|
||||
<p> It works as follows. When a "public" network service runs into
|
||||
an "all server ports are busy" condition, the <a href="master.8.html">master(8)</a> daemon logs
|
||||
a warning, restarts the service (without interrupting existing
|
||||
network sessions), and runs the service with "-o stress=yes" on the
|
||||
command line. Normally, it runs a stress-adaptive service with "-o
|
||||
stress=" on the command line (i.e. with an empty parameter value).
|
||||
Other services never have "-o stress" parameters on the command
|
||||
line, including services that listen on a loopback interface only.
|
||||
<p> It works as follows. When a "public" network service such as
|
||||
the SMTP server runs into an "all server ports are busy" condition,
|
||||
the Postfix <a href="master.8.html">master(8)</a> daemon logs a warning, restarts the service
|
||||
(without interrupting existing network sessions), and runs the
|
||||
service with "-o stress=yes" on the server process command line:
|
||||
</p>
|
||||
|
||||
<p> The stress pseudo-parameter value is the key to making <a href="postconf.5.html">main.cf</a>
|
||||
parameter settings stress adaptive: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||
2 <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> = ${stress?10}${stress:300}
|
||||
3 <a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> = ${stress?1}${stress:20}
|
||||
80821 ?? S 0:00.24 smtpd -n smtp -t inet -u -c -o stress=yes
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Normally, the Postfix <a href="master.8.html">master(8)</a> daemon runs such a service with
|
||||
"-o stress=" on the command line (i.e. with an empty parameter
|
||||
value): </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
83326 ?? S 0:00.28 smtpd -n smtp -t inet -u -c -o stress=
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Services that have local access only never have "-o stress"
|
||||
parameters on the command line. This includes services internal to
|
||||
Postfix such as the queue manager, and services that listen on a
|
||||
loopback interface only, such as after-filter SMTP services. </p>
|
||||
|
||||
<p> The "stress" parameter value is the key to making <a href="postconf.5.html">main.cf</a>
|
||||
parameter settings stress adaptive. The following settings are the
|
||||
default with Postfix 2.6 and later. With earlier Postfix versions
|
||||
that have stress-adaptive support, append the lines below to the
|
||||
<a href="postconf.5.html">main.cf</a> file and issue a "postfix reload" command: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
1 <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> = ${stress?10}${stress:300}s
|
||||
2 <a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> = ${stress?1}${stress:20}
|
||||
3 <a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> = ${stress?1}${stress:100}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
@ -371,11 +402,29 @@ parameter settings stress adaptive: </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Line 2: under conditions of stress, use an <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a>
|
||||
value of 10 seconds instead of the default 300 seconds,
|
||||
<li> <p> Line 1: under conditions of stress, use an <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a>
|
||||
value of 10 seconds instead of the default 300 seconds. Experience
|
||||
on the postfix-users list from a variety of sysadmins shows that
|
||||
reducing the "normal" <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> to 60s is unlikely to affect
|
||||
legitimate clients. However, it is unlikely to become the Postfix
|
||||
default because it's not RFC compliant. Setting <a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> to
|
||||
10s (line 2 below) or even 5s under stress will still allow most
|
||||
legitimate clients to connect and send mail, but may delay mail
|
||||
from some clients. No mail should be lost, as long as this measure
|
||||
is used only temporarily. </p>
|
||||
|
||||
<li> <p> Line 3: under conditions of stress, use an <a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a>
|
||||
of 1 instead of the default 20. </p>
|
||||
<li> <p> Line 2: under conditions of stress, use an <a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a>
|
||||
of 1 instead of the default 20. This helps by disconnecting clients
|
||||
after a single error, giving other clients a chance to connect.
|
||||
However, this may cause significant delays with legitimate mail,
|
||||
such as a mailing list that contains a few no-longer-active user
|
||||
names that didn't bother to unsubscribe. No mail should be lost,
|
||||
as long as this measure is used only temporarily. </p>
|
||||
|
||||
<li> <p> Line 3: under conditions of stress, use an
|
||||
<a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> of 1 instead of the default 100. This
|
||||
prevents clients from keeping idle connections open by repeatedly
|
||||
sending NOOP or RSET commands. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -463,6 +512,20 @@ services that accept remote connections. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="other"> Other measures to off-load zombies </h2>
|
||||
|
||||
<p> OpenBSD <a href="http://www.openbsd.org/spamd/">spamd</a>
|
||||
implements a daemon that handles all connections from "new" clients.
|
||||
Only well-behaved mail clients are allowed to talk to the mail
|
||||
server. Other clients are tarpitted, and will never get a chance
|
||||
to affect mail server performance. </p>
|
||||
|
||||
<p> At some point in the future, Postfix may come with a simple
|
||||
front-end daemon that does basic greylisting and pipelining detection
|
||||
to keep zombies and other ratware away from Postfix itself. This
|
||||
would use the "pass" service type which has been available in
|
||||
stable Postfix releases since Postfix 2.5. </p>
|
||||
|
||||
<h2><a name="credits"> Credits </a></h2>
|
||||
|
||||
<ul>
|
||||
|
@ -46,6 +46,8 @@ configuration examples </a>
|
||||
|
||||
<li> <a href="IPV6_README.html"> IP Version 6 Support </a>
|
||||
|
||||
<li> <a href="MULTI_INSTANCE_README.html"> Multiple-instance management </a>
|
||||
|
||||
<li> <a href="INSTALL.html"> Installation from source code </a>
|
||||
|
||||
</ul>
|
||||
|
@ -179,8 +179,8 @@ POSTMULTI(1) POSTMULTI(1)
|
||||
<b>New or existing instance name assignment</b>
|
||||
<b>-I</b> <i>name</i>
|
||||
Assign the specified instance <i>name</i> to an existing
|
||||
instance or to a newly created or imported
|
||||
instance. Instance names other than "-" (which
|
||||
instance, newly-created instance, or imported
|
||||
instance. Instance names other than "-" (which
|
||||
makes the instance "nameless") must start with
|
||||
"postfix-". This restriction reduces the likeli-
|
||||
hood of name collisions with system files.
|
||||
|
@ -599,7 +599,7 @@ ${WARN='-Wall -Wno-comment -Wformat -Wimplicit -Wmissing-prototypes \
|
||||
export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
|
||||
|
||||
# Snapshot only.
|
||||
CCARGS="$CCARGS -DSNAPSHOT"
|
||||
#CCARGS="$CCARGS -DSNAPSHOT"
|
||||
|
||||
# Non-production: needs thorough testing, or major changes are still
|
||||
# needed before the code stabilizes.
|
||||
|
@ -176,8 +176,9 @@ primary Postfix instance.
|
||||
.SH "New or existing instance name assignment"
|
||||
.IP "\fB-I \fIname\fR"
|
||||
Assign the specified instance \fIname\fR to an existing
|
||||
instance or to a newly created or imported instance. Instance
|
||||
names other than "-" (which makes the instance "nameless")
|
||||
instance, newly-created instance, or imported instance.
|
||||
Instance
|
||||
names other than "-" (which makes the instance "nameless")
|
||||
must start with "postfix-". This restriction reduces the
|
||||
likelihood of name collisions with system files.
|
||||
.IP "\fB-G \fIgroup\fR"
|
||||
|
@ -126,10 +126,10 @@ stress=
|
||||
an empty value ("name="), or sends a zero value ("name=0") in
|
||||
the case of a numerical attribute. </p>
|
||||
|
||||
<li> <p> The "recipient" attribute is available only in the
|
||||
"RCPT TO" stage, and in the "DATA" and "END-OF-MESSAGE" stages
|
||||
when Postfix accepted only one recipient for the current message.
|
||||
</p>
|
||||
<li> <p> The "recipient" attribute is available in the "RCPT
|
||||
TO" stage. It is also available in the "DATA" and "END-OF-MESSAGE"
|
||||
stages if Postfix accepted only one recipient for the current
|
||||
message. </p>
|
||||
|
||||
<li> <p> The "recipient_count" attribute (Postfix 2.3 and later)
|
||||
is non-zero only in the "DATA" and "END-OF-MESSAGE" stages. It
|
||||
|
@ -21,13 +21,11 @@ Stress-Dependent Configuration</h1>
|
||||
<h2>Overview </h2>
|
||||
|
||||
<p> This document describes the symptoms of Postfix SMTP server
|
||||
overload, and how to avoid the condition under normal conditions.
|
||||
When the condition is caused by botnets or other malware, the
|
||||
document suggests configuration settings that help to minimize the
|
||||
impact on legitimate mail. Finally, the document introduces
|
||||
stress-adaptive behavior, introduced with Postfix 2.5, and how it
|
||||
can be used to automatically switch configuration settings under
|
||||
overload. </p>
|
||||
overload. It presents permanent main.cf changes to avoid overload
|
||||
during normal operation, and temporary main.cf changes to cope with
|
||||
an unexpected burst of mail. This document makes specific suggestions
|
||||
for Postfix 2.5 and later which support stress-adaptive behavior,
|
||||
and for earlier Postfix versions that don't. </p>
|
||||
|
||||
<p> Topics covered in this document: </p>
|
||||
|
||||
@ -41,47 +39,52 @@ overload. </p>
|
||||
|
||||
<li><a href="#hangup"> Disconnect suspicious SMTP clients </a>
|
||||
|
||||
<li><a href="#desperate"> Take desperate measures </a>
|
||||
<li><a href="#legacy"> Temporary measures for older Postfix releases </a>
|
||||
|
||||
<li><a href="#adapt"> Make Postfix behavior stress-adaptive </a>
|
||||
<li><a href="#adapt"> Automatic stress-adaptive behavior </a>
|
||||
|
||||
<li><a href="#feature"> Detecting support for stress-adaptive behavior </a>
|
||||
|
||||
<li><a href="#forcing"> Forcing stress-adaptive behavior on or off </a>
|
||||
|
||||
<li><a href="#other"> Other measures to off-load zombies </a>
|
||||
|
||||
<li><a href="#credits"> Credits </a>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2><a name="overload"> Symptoms of Postfix SMTP server overload </a></h2>
|
||||
|
||||
<p> Under normal conditions, Postfix responds immediately when a
|
||||
remote SMTP client connects. The time needed to deliver mail should
|
||||
be noticeable only with very large messages. Performance degrades
|
||||
more dramatically when the number of remote SMTP clients exceeds
|
||||
the number of Postfix SMTP server processes. When a client connects
|
||||
while all server processes are busy, the client must wait until a
|
||||
server process becomes available. </p>
|
||||
<p> Under normal conditions, the Postfix SMTP server responds
|
||||
immediately when an SMTP client connects to it; the time to deliver
|
||||
mail is noticeable only with large messages. Performance degrades
|
||||
dramatically when the number of SMTP clients exceeds the number of
|
||||
Postfix SMTP server processes. When an SMTP client connects while
|
||||
all Postfix SMTP server processes are busy, the client must wait
|
||||
until a server process becomes available. </p>
|
||||
|
||||
<p> Overload may be caused by a legitimate mail (example: a DNS
|
||||
registrar opens a new zone for registrations), by mistake (mail
|
||||
explosion caused by a forwarding loop) or by illegitimate mail (worm
|
||||
outbreak, botnet, or other malware activity). Symptoms of Postfix
|
||||
SMTP mail server overload are: </p>
|
||||
<p> SMTP server overload may be caused by a surge of legitimate
|
||||
mail (example: a DNS registrar opens a new zone for registrations),
|
||||
by mistake (mail explosion caused by a forwarding loop) or by malice
|
||||
(worm outbreak, botnet, or other illegitimate activity). </p>
|
||||
|
||||
<p> Symptoms of Postfix SMTP server overload are: </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Remote SMTP clients experience a long delay before Postfix
|
||||
sends the "220 hostname.example.com ESMTP Postfix" greeting. If
|
||||
this affects end-user mail clients, enable the "submission" service
|
||||
entry in master.cf (present since Postfix 2.1), and tell users to
|
||||
connect to this instead of the public SMTP service. </p>
|
||||
sends the "220 hostname.example.com ESMTP Postfix" greeting. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> NOTE: Broken DNS configurations also cause lengthy delays
|
||||
before Postfix sends "220 hostname.example.com ...". In this case
|
||||
the delay happens even when Postfix is not busy. </p>
|
||||
<li> <p> NOTE: Broken DNS configurations can also cause lengthy
|
||||
delays before Postfix sends "220 hostname.example.com ...". These
|
||||
delays also exist when Postfix is NOT overloaded. </p>
|
||||
|
||||
<li> <p> NOTE: To avoid "overload" delays for end-user mail
|
||||
clients, enable the "submission" service entry in master.cf (present
|
||||
since Postfix 2.1), and tell users to connect to this instead of
|
||||
the public SMTP service. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -91,8 +94,8 @@ clients disconnect before Postfix answers the connection. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> NOTE: A portscan for open SMTP ports also results in "lost
|
||||
connection ..." logfile messages. </p>
|
||||
<li> <p> NOTE: A portscan for open SMTP ports can also result in
|
||||
"lost connection ..." logfile messages. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -111,14 +114,16 @@ Oct 3 20:39:27 spike postfix/master[28905]: warning: to avoid this
|
||||
</ul>
|
||||
|
||||
<p> Legitimate mail that doesn't get through during an episode of
|
||||
overload is not necessarily lost. It should still arrive once the
|
||||
situation returns to normal, as long as the overload condition is
|
||||
temporary. </p>
|
||||
Postfix SMTP server overload is not necessarily lost. It should
|
||||
still arrive once the situation returns to normal, as long as the
|
||||
overload condition is temporary. </p>
|
||||
|
||||
<h2><a name="concurrency"> Service more SMTP clients at the same time </a> </h2>
|
||||
|
||||
<p> To service more SMTP clients simultaneously, you need to increase
|
||||
the number of SMTP server processes. This will improve the
|
||||
<p> One measure to avoid the "all server processes busy" condition
|
||||
is to service more SMTP clients simultaneously. For this you need
|
||||
to increase the number of Postfix SMTP server processes. This will
|
||||
improve the
|
||||
responsiveness for remote SMTP clients, as long as the server machine
|
||||
has enough hardware and software resources to run the additional
|
||||
processes, and as long as the file system can keep up with the
|
||||
@ -137,7 +142,8 @@ later, and an operating system that supports kernel-based event
|
||||
filters (BSD kqueue(2), Linux epoll(4), or Solaris /dev/poll).
|
||||
</p>
|
||||
|
||||
<li> <p> You can reduce the Postfix memory footprint by using cdb:
|
||||
<li> <p> More processes use more memory. You can reduce the Postfix
|
||||
memory footprint by using cdb:
|
||||
lookup tables instead of Berkeley DB's hash: or btree: tables. </p>
|
||||
|
||||
<pre>
|
||||
@ -181,9 +187,9 @@ Issue a "postfix reload" command to make the change effective. </p>
|
||||
|
||||
<p> When increasing the number of SMTP server processes is not
|
||||
practical, you can improve Postfix server responsiveness by eliminating
|
||||
unnecessary work. When Postfix spends less time per SMTP session, the
|
||||
same number of SMTP server processes can service more clients in the
|
||||
same amount of time. </p>
|
||||
delays. When Postfix spends less time per SMTP session, the same
|
||||
number of SMTP server processes can service more clients in a given
|
||||
amount of time. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
@ -201,18 +207,18 @@ emergency patterns to block the latest worm explosion or backscatter
|
||||
mail. See BACKSCATTER_README for examples of the latter.
|
||||
|
||||
<li> <p> Group your header_checks and body_checks patterns to avoid
|
||||
unnecessary pattern matching operations.
|
||||
unnecessary pattern matching operations:
|
||||
|
||||
<pre>
|
||||
1 /etc/postfix/header_checks:
|
||||
2 if /^Subject:/
|
||||
3 /^Subject: virus found in mail from you/ reject
|
||||
4 /^Subject: ..../ ....
|
||||
4 /^Subject: ..other../ reject
|
||||
5 endif
|
||||
6
|
||||
7 if /^Received:/
|
||||
8 /^Received: from (postfix\.org) / reject forged client name in received header: $1
|
||||
9 /^Received: from .../ ....
|
||||
9 /^Received: from ..other../ reject ....
|
||||
10 endif
|
||||
</pre>
|
||||
|
||||
@ -226,20 +232,22 @@ clients get a chance to talk to Postfix. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Use "521" reply codes (Postfix 2.6 and later) for
|
||||
botnet-related RBLs or for selected non-RBL restrictions. With
|
||||
Postfix 2.3-2.5 use "421" for a similar result. The Postfix SMTP
|
||||
server will disconnect immediately without waiting for the remote
|
||||
SMTP client to send a QUIT command. </p>
|
||||
<li> <p> Use "521" SMTP reply codes (Postfix 2.6 and later) or "421"
|
||||
(Postfix 2.3-2.5) to hang up on clients that that match botnet-related
|
||||
RBLs (see next bullet) or that match selected non-RBL restrictions
|
||||
such as SMTP access maps. The Postfix SMTP server will reject mail
|
||||
and disconnect without waiting for the remote SMTP client to send
|
||||
a QUIT command. </p>
|
||||
|
||||
<p> You can set individual reject codes for RBLs, and for individual
|
||||
responses from a specific RBL. We'll use zen.spamhaus.org as an
|
||||
example; by the time you read this document, details may have
|
||||
changed. Right now, their documents say that a response of 127.0.0.10
|
||||
or 127.0.0.11 indicates a dynamic client IP address, which means
|
||||
that the machine is probably running a bot of some kind. To give
|
||||
a 521 response instead of the default 554 response, use something
|
||||
like: </p>
|
||||
<li> <p> To hang up connections from blacklisted zombies, you can
|
||||
set specific Postfix SMTP server reject codes for specific RBLs,
|
||||
and for individual responses from specific RBLs. We'll use
|
||||
zen.spamhaus.org as an example; by the time you read this document,
|
||||
details may have changed. Right now, their documents say that a
|
||||
response of 127.0.0.10 or 127.0.0.11 indicates a dynamic client IP
|
||||
address, which means that the machine is probably running a bot of
|
||||
some kind. To give a 521 response instead of the default 554
|
||||
response, use something like: </p>
|
||||
|
||||
<pre>
|
||||
1 /etc/postfix/main.cf:
|
||||
@ -252,45 +260,55 @@ like: </p>
|
||||
8 rbl_reply_maps = hash:/etc/postfix/rbl_reply_maps
|
||||
9
|
||||
10 /etc/postfix/rbl_reply_maps:
|
||||
11 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable;
|
||||
12 $rbl_class [$rbl_what] blocked using
|
||||
13 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
14
|
||||
15 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable;
|
||||
16 $rbl_class [$rbl_what] blocked using
|
||||
17 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
11 # With Postfix 2.3-2.5 use "421" to hang up connections.
|
||||
12 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable;
|
||||
13 $rbl_class [$rbl_what] blocked using
|
||||
14 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
15
|
||||
16 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable;
|
||||
17 $rbl_class [$rbl_what] blocked using
|
||||
18 $rbl_domain${rbl_reason?; $rbl_reason}
|
||||
</pre>
|
||||
|
||||
<p> Although the above shows three RBL lookups (lines 4-6), Postfix
|
||||
will still only do a single DNS query, so the performance difference
|
||||
is negligible. </p>
|
||||
<p> Although the above example shows three RBL lookups (lines 4-6),
|
||||
Postfix will only do a single DNS query, so it does not affect the
|
||||
performance. </p>
|
||||
|
||||
<p> With Postfix 2.3-2.5, use 421 (reply code 521 will not cause
|
||||
Postfix to disconnect). The down-side of sending 421 is that
|
||||
it works only for zombies and other malware. If the client is running
|
||||
a real MTA, then it may connect again several times until the mail
|
||||
expires in its queue. When this is a problem, stick with the default
|
||||
554 reply, and use "smtpd_hard_error_limit = 1" as described below.
|
||||
</p>
|
||||
<li> <p> With Postfix 2.3-2.5, use reply code 421 (521 will not
|
||||
cause Postfix to disconnect). The down-side of replying with 421
|
||||
is that it works only for zombies and other malware. If the client
|
||||
is running a real MTA, then it may connect again several times until
|
||||
the mail expires in its queue. When this is a problem, stick with
|
||||
the default 554 reply, and use "smtpd_hard_error_limit = 1" as
|
||||
described below. </p>
|
||||
|
||||
<p> With Postfix 2.5, or with earlier releases that contain the
|
||||
stress-adaptive behavior patch, you can turn on the above under
|
||||
overload by replacing line 8 with: </p>
|
||||
<li> <p> You can automatically turn on the above overload measure
|
||||
with Postfix 2.5 and later, or with earlier releases that contain
|
||||
the stress-adaptive behavior source code patch from the mirrors
|
||||
listed at http://www.postfix.org/download.html. Simply replace line
|
||||
above 8 with: </p>
|
||||
|
||||
<pre>
|
||||
8 rbl_reply_maps = ${stress?hash:/etc/postfix/rbl_reply_maps}
|
||||
</pre>
|
||||
|
||||
<p> More information about automatic stress-adaptive behavior is
|
||||
at the end of this document. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2><a name="desperate"> Take desperate measures </a></h2>
|
||||
<p> More information about automatic stress-adaptive behavior is
|
||||
in section "<a href="#adapt">Automatic stress-adaptive behavior</a>".
|
||||
</p>
|
||||
|
||||
<p> The following measures will still allow <b>most</b> legitimate
|
||||
clients to connect and send mail, but may affect some legitimate
|
||||
clients. </p>
|
||||
<h2><a name="legacy"> Temporary measures for older Postfix releases </a></h2>
|
||||
|
||||
<p> See the next section, "<a href="#adapt">Automatic stress-adaptive
|
||||
behavior</a>", if you are running Postfix version 2.5 or later, or
|
||||
if you have applied the source code patch for stress-adaptive
|
||||
behavior from the mirrors listed at http://www.postfix.org/download.html.
|
||||
</p>
|
||||
|
||||
<p> The following measures can be applied temporarily during overload.
|
||||
They still allow <b>most</b> legitimate clients to connect and send
|
||||
mail, but may affect some legitimate clients. </p>
|
||||
|
||||
<ul>
|
||||
|
||||
@ -312,16 +330,9 @@ such as a mailing list that contains a few no-longer-active user
|
||||
names that didn't bother to unsubscribe. No mail should be lost,
|
||||
as long as this measure is used only temporarily. </p>
|
||||
|
||||
<li> <p> Disable remote SMTP client hostname lookups, so that all
|
||||
SMTP client hostnames become "unknown" (line 5 below). This feature
|
||||
was introduced with Postfix 2.3. Unfortunately, this measure is
|
||||
more problematic than the other ones proposed sofar. First, this
|
||||
will result in loss of mail when you use hostname-based access rules
|
||||
that reject mail from "unknown" SMTP clients (examples:
|
||||
reject_unknown_client_hostname, reject_unknown_reverse_client_hostname).
|
||||
Second, this may result in loss of mail when you subject "unknown"
|
||||
SMTP clients to additional restrictions such as reject_unverified_sender.
|
||||
</p>
|
||||
<li> <p> Use an smtpd_junk_command_limit of 1 instead of the default
|
||||
100. This prevents clients from keeping idle connections open by
|
||||
repeatedly sending NOOP or RSET commands. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -330,40 +341,60 @@ SMTP clients to additional restrictions such as reject_unverified_sender.
|
||||
1 /etc/postfix/main.cf:
|
||||
2 smtpd_timeout = 10
|
||||
3 smtpd_hard_error_limit = 1
|
||||
4 # Caution: line 5 may trigger REJECTs by hostname-based access rules
|
||||
5 smtpd_peername_lookup = no
|
||||
4 smtpd_junk_command_limit = 1
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Except with the last measure, no mail should be lost, as long
|
||||
<p> With these measures, no mail should be lost, as long
|
||||
as these measures are used only temporarily. The next section of
|
||||
this document introduces a way to automate this process. </p>
|
||||
|
||||
<h2><a name="adapt"> Make Postfix behavior stress-adaptive </a></h2>
|
||||
<h2><a name="adapt"> Automatic stress-adaptive behavior </a></h2>
|
||||
|
||||
<p> Postfix version 2.5 introduces automatic stress-adaptive behavior.
|
||||
This is also available as an add-on patch for Postfix versions 2.4
|
||||
and 2.3 from the mirrors listed at http://www.postfix.org/download.html.
|
||||
</p>
|
||||
This is also available as a source code patch for Postfix versions
|
||||
2.4 and 2.3 from the mirrors listed at
|
||||
http://www.postfix.org/download.html. </p>
|
||||
|
||||
<p> It works as follows. When a "public" network service runs into
|
||||
an "all server ports are busy" condition, the master(8) daemon logs
|
||||
a warning, restarts the service (without interrupting existing
|
||||
network sessions), and runs the service with "-o stress=yes" on the
|
||||
command line. Normally, it runs a stress-adaptive service with "-o
|
||||
stress=" on the command line (i.e. with an empty parameter value).
|
||||
Other services never have "-o stress" parameters on the command
|
||||
line, including services that listen on a loopback interface only.
|
||||
<p> It works as follows. When a "public" network service such as
|
||||
the SMTP server runs into an "all server ports are busy" condition,
|
||||
the Postfix master(8) daemon logs a warning, restarts the service
|
||||
(without interrupting existing network sessions), and runs the
|
||||
service with "-o stress=yes" on the server process command line:
|
||||
</p>
|
||||
|
||||
<p> The stress pseudo-parameter value is the key to making main.cf
|
||||
parameter settings stress adaptive: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
1 /etc/postfix/main.cf:
|
||||
2 smtpd_timeout = ${stress?10}${stress:300}
|
||||
3 smtpd_hard_error_limit = ${stress?1}${stress:20}
|
||||
80821 ?? S 0:00.24 smtpd -n smtp -t inet -u -c -o stress=yes
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Normally, the Postfix master(8) daemon runs such a service with
|
||||
"-o stress=" on the command line (i.e. with an empty parameter
|
||||
value): </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
83326 ?? S 0:00.28 smtpd -n smtp -t inet -u -c -o stress=
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Services that have local access only never have "-o stress"
|
||||
parameters on the command line. This includes services internal to
|
||||
Postfix such as the queue manager, and services that listen on a
|
||||
loopback interface only, such as after-filter SMTP services. </p>
|
||||
|
||||
<p> The "stress" parameter value is the key to making main.cf
|
||||
parameter settings stress adaptive. The following settings are the
|
||||
default with Postfix 2.6 and later. With earlier Postfix versions
|
||||
that have stress-adaptive support, append the lines below to the
|
||||
main.cf file and issue a "postfix reload" command: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
1 smtpd_timeout = ${stress?10}${stress:300}s
|
||||
2 smtpd_hard_error_limit = ${stress?1}${stress:20}
|
||||
3 smtpd_junk_command_limit = ${stress?1}${stress:100}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
@ -371,11 +402,29 @@ parameter settings stress adaptive: </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Line 2: under conditions of stress, use an smtpd_timeout
|
||||
value of 10 seconds instead of the default 300 seconds,
|
||||
<li> <p> Line 1: under conditions of stress, use an smtpd_timeout
|
||||
value of 10 seconds instead of the default 300 seconds. Experience
|
||||
on the postfix-users list from a variety of sysadmins shows that
|
||||
reducing the "normal" smtpd_timeout to 60s is unlikely to affect
|
||||
legitimate clients. However, it is unlikely to become the Postfix
|
||||
default because it's not RFC compliant. Setting smtpd_timeout to
|
||||
10s (line 2 below) or even 5s under stress will still allow most
|
||||
legitimate clients to connect and send mail, but may delay mail
|
||||
from some clients. No mail should be lost, as long as this measure
|
||||
is used only temporarily. </p>
|
||||
|
||||
<li> <p> Line 3: under conditions of stress, use an smtpd_hard_error_limit
|
||||
of 1 instead of the default 20. </p>
|
||||
<li> <p> Line 2: under conditions of stress, use an smtpd_hard_error_limit
|
||||
of 1 instead of the default 20. This helps by disconnecting clients
|
||||
after a single error, giving other clients a chance to connect.
|
||||
However, this may cause significant delays with legitimate mail,
|
||||
such as a mailing list that contains a few no-longer-active user
|
||||
names that didn't bother to unsubscribe. No mail should be lost,
|
||||
as long as this measure is used only temporarily. </p>
|
||||
|
||||
<li> <p> Line 3: under conditions of stress, use an
|
||||
smtpd_junk_command_limit of 1 instead of the default 100. This
|
||||
prevents clients from keeping idle connections open by repeatedly
|
||||
sending NOOP or RSET commands. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -463,6 +512,20 @@ services that accept remote connections. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="other"> Other measures to off-load zombies </h2>
|
||||
|
||||
<p> OpenBSD <a href="http://www.openbsd.org/spamd/">spamd</a>
|
||||
implements a daemon that handles all connections from "new" clients.
|
||||
Only well-behaved mail clients are allowed to talk to the mail
|
||||
server. Other clients are tarpitted, and will never get a chance
|
||||
to affect mail server performance. </p>
|
||||
|
||||
<p> At some point in the future, Postfix may come with a simple
|
||||
front-end daemon that does basic greylisting and pipelining detection
|
||||
to keep zombies and other ratware away from Postfix itself. This
|
||||
would use the "pass" service type which has been available in
|
||||
stable Postfix releases since Postfix 2.5. </p>
|
||||
|
||||
<h2><a name="credits"> Credits </a></h2>
|
||||
|
||||
<ul>
|
||||
|
@ -624,6 +624,10 @@ static void cleanup_header_done_callback(void *context)
|
||||
* ID uniqueness only within a second, we must ensure that the time in
|
||||
* the message ID matches the queue ID creation time, as long as we use
|
||||
* the queue ID in the message ID.
|
||||
*
|
||||
* XXX We log a dummy name=value record so that we (hopefully) don't break
|
||||
* compatibility with existing logfile analyzers, and so that we don't
|
||||
* complicate future code that wants to log more name=value attributes.
|
||||
*/
|
||||
if ((state->hdr_rewrite_context || var_always_add_hdrs)
|
||||
&& (state->headers_seen & (1 << (state->resent[0] ?
|
||||
@ -636,7 +640,11 @@ static void cleanup_header_done_callback(void *context)
|
||||
msg_info("%s: %smessage-id=<%s.%s@%s>",
|
||||
state->queue_id, *state->resent ? "resent-" : "",
|
||||
time_stamp, state->queue_id, var_myhostname);
|
||||
state->headers_seen |= (1 << (state->resent[0] ?
|
||||
HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID));
|
||||
}
|
||||
if ((state->headers_seen & (1 << HDR_MESSAGE_ID)) == 0)
|
||||
msg_info("%s: message-id=<>", state->queue_id);
|
||||
|
||||
/*
|
||||
* Add a missing (Resent-)Date: header. The date is in local time units,
|
||||
|
@ -207,6 +207,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
|
||||
static RCPT_BUF *rcpt_buf;
|
||||
int rcpt_count;
|
||||
int dsn_ret;
|
||||
int lock_tries;
|
||||
|
||||
/*
|
||||
* Initialize. For some reason I wanted to allow for multiple instances
|
||||
@ -335,8 +336,21 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("%s: file %s", myname, VSTREAM_PATH(request->fp));
|
||||
if (myflock(vstream_fileno(request->fp), INTERNAL_LOCK, DELIVER_LOCK_MODE) < 0)
|
||||
msg_fatal("shared lock %s: %m", VSTREAM_PATH(request->fp));
|
||||
|
||||
/*
|
||||
* XXX Originally, the queue manager would read new recipients AFTER all
|
||||
* the in-memory recipients were processed. either the queue manager held
|
||||
* an exclusive lock or delivery agents held a shared lock. Now we try a
|
||||
* few times.
|
||||
*/
|
||||
for (lock_tries = 0; /* see below */; lock_tries++) {
|
||||
if (myflock(vstream_fileno(request->fp), INTERNAL_LOCK, DELIVER_LOCK_MODE) == 0)
|
||||
break;
|
||||
if (lock_tries < 5)
|
||||
sleep(1);
|
||||
else
|
||||
msg_fatal("shared lock %s: %m", VSTREAM_PATH(request->fp));
|
||||
}
|
||||
close_on_exec(vstream_fileno(request->fp), CLOSE_ON_EXEC);
|
||||
|
||||
return (0);
|
||||
|
@ -20,8 +20,8 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20090404"
|
||||
#define MAIL_VERSION_NUMBER "2.6"
|
||||
#define MAIL_RELEASE_DATE "20090415"
|
||||
#define MAIL_VERSION_NUMBER "2.6.0-RC1"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
|
||||
|
@ -164,8 +164,9 @@
|
||||
/* .SH "New or existing instance name assignment"
|
||||
/* .IP "\fB-I \fIname\fR"
|
||||
/* Assign the specified instance \fIname\fR to an existing
|
||||
/* instance or to a newly created or imported instance. Instance
|
||||
/* names other than "-" (which makes the instance "nameless")
|
||||
/* instance, newly-created instance, or imported instance.
|
||||
/* Instance
|
||||
/* names other than "-" (which makes the instance "nameless")
|
||||
/* must start with "postfix-". This restriction reduces the
|
||||
/* likelihood of name collisions with system files.
|
||||
/* .IP "\fB-G \fIgroup\fR"
|
||||
|
@ -107,5 +107,6 @@
|
||||
VAR_SMTP_SENDER_AUTH, DEF_SMTP_SENDER_AUTH, &var_smtp_sender_auth,
|
||||
VAR_SMTP_CNAME_OVERR, DEF_SMTP_CNAME_OVERR, &var_smtp_cname_overr,
|
||||
VAR_SMTP_SASL_AUTH_SOFT_BOUNCE, DEF_SMTP_SASL_AUTH_SOFT_BOUNCE, &var_smtp_sasl_auth_soft_bounce,
|
||||
VAR_LMTP_ASSUME_FINAL, DEF_LMTP_ASSUME_FINAL, &var_lmtp_assume_final,
|
||||
0,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user