1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
|
PPoossttffiixx BBeeffoorree--QQuueeuuee CCoonntteenntt FFiilltteerr
-------------------------------------------------------------------------------
WWAARRNNIINNGG
The before-queue content filtering feature described in this document limits
the amount of mail that a site can handle. See the "Pros and Cons" section
below for details.
TThhee PPoossttffiixx bbeeffoorree--qquueeuuee ccoonntteenntt ffiilltteerr ffeeaattuurree
As of version 2.1, the Postfix SMTP server can forward all incoming mail to a
content filtering proxy server that inspects all mail BEFORE it is stored in
the Postfix mail queue. It is roughly equivalent in capabilities to the
approach described in MILTER_README, except that the latter uses a dedicated
protocol instead of SMTP.
The before-queue content filter is meant to be used as follows:
Postfix BBeeffoorree Postfix Postfix Postfix smtp
Internet -> SMTP -> qquueeuuee -> SMTP -> cleanup -> queue -< local
server ffiilltteerr server server virtual
The before-queue content filter is not to be confused with the approach
described in the FILTER_README document, where mail is filtered AFTER it is
stored in the Postfix mail queue.
This document describes the following topics:
* Principles of operation
* Pros and cons of before-queue content filtering
* Configuring the Postfix SMTP pass-through proxy feature
* Configuration parameters
* How Postfix talks to the before-queue content filter
PPrriinncciipplleess ooff ooppeerraattiioonn
As shown in the diagram above, the before-queue filter sits between two Postfix
SMTP server processes.
* The before-filter Postfix SMTP server accepts connections from the Internet
and does the usual relay access control, SASL authentication, TLS
negotiation, RBL lookups, rejecting non-existent sender or recipient
addresses, etc.
* The before-queue filter receives unfiltered mail content from Postfix and
does one of the following:
1. Re-inject the mail back into Postfix via SMTP, perhaps after changing
its content and/or destination.
2. Discard or quarantine the mail.
3. Reject the mail by sending a suitable SMTP status code back to Postfix.
Postfix passes the status back to the remote SMTP client. This way,
Postfix does not have to send a bounce message.
* The after-filter Postfix SMTP server receives mail from the content filter.
From then on Postfix processes the mail as usual.
The before-queue content filter described here works just like the after-queue
content filter described in the FILTER_README document. In many cases you can
use the same software, within the limitations as discussed in the "Pros and
Cons" section below.
PPrrooss aanndd ccoonnss ooff bbeeffoorree--qquueeuuee ccoonntteenntt ffiilltteerriinngg
* Pro: Postfix can reject mail before the incoming SMTP mail transfer
completes, so that Postfix does not have to send rejected mail back to the
sender (which is usually forged anyway). Mail that is not accepted remains
the responsibility of the remote SMTP client.
* Con: The smtpd(8) service before the smtpd_proxy_filter cannot support
features that involve header or body access, or that involve queue file
manipulation (i.e., anything that involves processing by the cleanup(8)
service).
o No support for HOLD actions in Postfix smtpd access(5) restrictions.
o No support for smtpd_milters features that involve message header or
body content.
o No support for receive_override_options.
Instead, specify those features with the smtpd(8) service behind the
smtpd_proxy_filter. In some cases, it may be possible to combine a before-
filter PREPEND action that emits a unique pattern (for example containing
the MTA domain name), with an after-filter header_checks action that does
what you want, and with an smtp_header_checks IGNORE action that deletes
the prepended header from transit mail.
* Con: The remote SMTP client expects an SMTP reply within a deadline. As the
system load increases, fewer and fewer CPU cycles remain available to
answer within the deadline, and eventually you either have to stop
accepting mail or you have to stop filtering mail. It is for this reason
that the before-queue content filter limits the amount of mail that a site
can handle.
* Con: Content filtering software can use lots of memory resources. You have
to reduce the number of simultaneous content filter processes so that a
burst of mail will not drive your system into the ground.
o With Postfix versions 2.7 and later, SMTP clients will experience an
increase in the delay between the time the client sends "end-of-
message" and the time the Postfix SMTP server replies (here, the number
of before-filter SMTP server processes can be larger than the number of
filter processes).
o With Postfix versions before 2.7, SMTP clients will experience an
increase in the delay before they can receive service (here, the number
of before-filter SMTP server processes is always equal to the number of
filter processes).
CCoonnffiigguurriinngg tthhee PPoossttffiixx SSMMTTPP ppaassss--tthhrroouugghh pprrooxxyy ffeeaattuurree
In the following example, the before-filter Postfix SMTP server gives mail to a
content filter that listens on localhost port 10025. The after-filter Postfix
SMTP server receives mail from the content filter via localhost port 10026.
From then on mail is processed as usual.
The content filter itself is not described here. You can use any filter that is
SMTP enabled. For non-SMTP capable content filtering software, Bennett Todd's
SMTP proxy implements a nice Perl-based framework. See: https://
web.archive.org/web/20151022025756/http://bent.latency.net/smtpprox/ or https:/
/github.com/jnorell/smtpprox/
Postfix
Postfix filter on SMTP server Postfix Postfix
Internet -> SMTP server -> localhost -> on -> cleanup -> incoming
on port 25 port 10025 localhost server queue
port 10026
This is configured by editing the master.cf file:
/etc/postfix/master.cf:
# =============================================================
# service type private unpriv chroot wakeup maxproc command
# (yes) (yes) (yes) (never) (100)
# =============================================================
#
# Before-filter SMTP server. Receive mail from the network and
# pass it to the content filter on localhost port 10025.
#
smtp inet n - n - 20 smtpd
-o smtpd_proxy_filter=127.0.0.1:10025
-o smtpd_client_connection_count_limit=10
# Postfix 2.7 and later performance feature.
# -o smtpd_proxy_options=speed_adjust
#
# After-filter SMTP server. Receive mail from the content filter
# on localhost port 10026.
#
127.0.0.1:10026 inet n - n - - smtpd
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
# Postfix 2.10 and later: specify empty smtpd_relay_restrictions.
-o smtpd_relay_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=
-o mynetworks=127.0.0.0/8
-o receive_override_options=no_unknown_recipient_checks
Note: do not specify spaces around the "=" or "," characters.
The before-filter SMTP server entry is a modified version of the default
Postfix SMTP server entry that is normally configured at the top of the
master.cf file:
* The number of SMTP sessions is reduced from the default 100 to only 20.
This prevents a burst of mail from running your system into the ground with
too many content filter processes.
* The "-o smtpd_client_connection_count_limit=10" prevents one SMTP client
from using up all 20 SMTP server processes. This limit is not necessary if
you receive all mail from a trusted relay host.
Note: this setting is available in Postfix version 2.2 and later. Earlier
Postfix versions will ignore it.
* The "-o smtpd_proxy_filter=127.0.0.1:10025" tells the before-filter SMTP
server that it should give incoming mail to the content filter that listens
on localhost TCP port 10025.
* The "-o smtpd_proxy_options=speed_adjust" tells the before-filter SMTP
server that it should receive an entire email message before it connects to
a content filter. This reduces the number of simultaneous filter processes.
NOTE 1: When this option is turned on, a content filter must not
selectively reject recipients of a multi-recipient message. Rejecting all
recipients is OK, as is accepting all recipients.
NOTE 2: This feature increases the minimum amount of free queue space by
$message_size_limit. The extra space is needed to save the message to a
temporary file.
* Postfix >= 2.3 supports both TCP and UNIX-domain filters. The above filter
could be specified as "inet:127.0.0.1:10025". To specify a UNIX-domain
filter, specify "unix:pathname". A relative pathname is interpreted
relative to the Postfix queue directory.
The after-filter SMTP server is a new master.cf entry:
* The "127.0.0.1:10026" makes the after-filter SMTP server listen on the
localhost address only, without exposing it to the network. NEVER expose
the after-filter SMTP server to the Internet :-)
* The "-o smtpd_authorized_xforward_hosts=127.0.0.0/8" allows the after-
filter SMTP server to receive remote SMTP client information from the
before-filter SMTP server, so that the after-filter Postfix daemons log the
remote SMTP client information instead of logging localhost[127.0.0.1].
* The other after-filter SMTP server settings avoid duplication of work that
is already done in the "before filter" SMTP server.
By default, the filter has 100 seconds to do its work. If it takes longer then
Postfix gives up and reports an error to the remote SMTP client. You can
increase this time limit (see the "Configuration parameters" section below) but
doing so is pointless because you can't control when the remote SMTP client
times out.
CCoonnffiigguurraattiioonn ppaarraammeetteerrss
Parameters that control proxying:
* smtpd_proxy_filter (syntax: host:port): The host and TCP port of the
before-queue content filter. When no host or host: is specified here,
localhost is assumed.
* smtpd_proxy_timeout (default: 100s): Timeout for connecting to the before-
queue content filter and for sending and receiving commands and data. All
proxy errors are logged to the maillog file. For privacy reasons, all the
remote SMTP client sees is "451 Error: queue file write error". It would
not be right to disclose internal details to strangers.
* smtpd_proxy_ehlo (default: $myhostname): The hostname to use when sending
an EHLO command to the before-queue content filter.
HHooww PPoossttffiixx ttaallkkss ttoo tthhee bbeeffoorree--qquueeuuee ccoonntteenntt ffiilltteerr
The before-filter Postfix SMTP server connects to the content filter, delivers
one message, and disconnects. While sending mail into the content filter,
Postfix speaks ESMTP but uses no command pipelining. Postfix generates its own
EHLO, XFORWARD (for logging the remote client IP address instead of localhost
[127.0.0.1]), DATA and QUIT commands, and forwards unmodified copies of all the
MAIL FROM and RCPT TO commands that the before-filter Postfix SMTP server
didn't reject itself. Postfix sends no other SMTP commands.
The content filter should accept the same MAIL FROM and RCPT TO command syntax
as the before-filter Postfix SMTP server, and should forward the commands
without modification to the after-filter SMTP server. If the content filter or
after-filter SMTP server does not support all the ESMTP features that the
before-filter Postfix SMTP server supports, then the missing features must be
turned off in the before-filter Postfix SMTP server with the
smtpd_discard_ehlo_keywords parameter.
When the filter rejects content, it should send a negative SMTP response back
to the before-filter Postfix SMTP server, and it should abort the connection
with the after-filter Postfix SMTP server without completing the SMTP
conversation with the after-filter Postfix SMTP server.
|