1176348Smarcel<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
2176348Smarcel        "http://www.w3.org/TR/html4/loose.dtd">
3176348Smarcel
4176348Smarcel<html>
5176348Smarcel
6176348Smarcel<head>
7176348Smarcel
8176348Smarcel<title>Postfix SMTP Access Policy Delegation </title>
9176348Smarcel
10176348Smarcel<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
11176348Smarcel
12176348Smarcel</head>
13176348Smarcel
14176348Smarcel<body>
15176348Smarcel
16176348Smarcel<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix SMTP Access Policy Delegation </h1>
17176348Smarcel
18176348Smarcel<hr>
19176348Smarcel
20176348Smarcel<h2>Purpose of Postfix SMTP access policy delegation</h2>
21176348Smarcel
22176348Smarcel<p> The Postfix SMTP server has a number of built-in mechanisms to
23176348Smarcelblock or accept mail at specific SMTP protocol stages. As of version
24176348Smarcel2.1, Postfix can delegate policy decisions to an external server
25176348Smarcelthat runs outside Postfix. </p>
26176348Smarcel
27176348Smarcel<p> With this policy delegation mechanism, a simple <a href="#greylist">
28176348Smarcelgreylist </a> policy can be implemented with only a dozen lines of
29176348SmarcelPerl, as is shown at the end of this document. A complete example
30176348Smarcelcan be found in the Postfix source code, in the directory
31176348Smarcelexamples/smtpd-policy. </p>
32176348Smarcel
33176348Smarcel<p> Another example of policy delegation is the SPF policy server
34176348Smarcelat http://www.openspf.org/Software.  </p>
35176348Smarcel
36176348Smarcel<p> Policy delegation is now the preferred method for adding policies
37177108Srajto Postfix. It's much easier to develop a new feature in few lines
38177108Srajof Perl, Python, Ruby, or TCL, than trying to do the same in C code.
39177108SrajThe difference in
40177108Srajperformance will be unnoticeable except in the most demanding
41177108Srajenvironments. On active systems a policy daemon process is used
42177108Srajmultiple times, for up to $max_use incoming SMTP connections. </p>
43177108Sraj
44177108Sraj<p> This document covers the following topics: </p>
45177108Sraj
46177108Sraj<ul>
47176348Smarcel
48176348Smarcel<li><a href="#protocol">Policy protocol description</a>
49176348Smarcel
50176348Smarcel<li><a href="#client_config">Policy client/server configuration</a>
51176348Smarcel
52177152Sobrien<li><a href="#greylist">Example: greylist policy server</a>
53176348Smarcel
54177152Sobrien<li><a href="#frequent">Greylisting mail from frequently forged domains</a>
55177152Sobrien
56177152Sobrien<li><a href="#all_mail">Greylisting all your mail</a>
57176348Smarcel
58177152Sobrien<li><a href="#maintenance">Routine greylist maintenance</a>
59177152Sobrien
60176348Smarcel<li><a href="#greylist_code">Example Perl greylist server</a>
61176348Smarcel
62177152Sobrien</ul>
63177152Sobrien
64176348Smarcel<h2><a name="protocol">Protocol description</a></h2>
65176348Smarcel
66176348Smarcel<p> The Postfix policy delegation protocol is really simple. The
67176348Smarcelclient request is a sequence of name=value attributes separated by
68176348Smarcelnewline, and is terminated by an empty line. The server reply is
69176348Smarcelone name=value attribute and it, too, is terminated by an empty
70177152Sobrienline. </p>
71176348Smarcel
72177152Sobrien<p> Here is an example of all the attributes that the Postfix SMTP
73server sends in a delegated SMTPD access policy request: </p>
74
75<blockquote>
76<pre>
77<b>Postfix version 2.1 and later:</b>
78request=smtpd_access_policy
79protocol_state=RCPT
80protocol_name=SMTP
81helo_name=some.domain.tld
82queue_id=8045F2AB23
83sender=foo@bar.tld
84recipient=bar@foo.tld
85recipient_count=0
86client_address=1.2.3.4
87client_name=another.domain.tld
88reverse_client_name=another.domain.tld
89instance=123.456.7
90<b>Postfix version 2.2 and later:</b>
91sasl_method=plain
92sasl_username=you
93sasl_sender=
94size=12345
95ccert_subject=solaris9.porcupine.org
96ccert_issuer=Wietse+20Venema
97ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04
98<b>Postfix version 2.3 and later:</b>
99encryption_protocol=TLSv1/SSLv3
100encryption_cipher=DHE-RSA-AES256-SHA
101encryption_keysize=256
102etrn_domain=
103<b>Postfix version 2.5 and later:</b>
104stress=
105[empty line]
106</pre>
107</blockquote>
108
109<p> Notes: </p>
110
111<ul>
112
113    <li> <p> The "request" attribute is required. In this example
114    the request type is "smtpd_access_policy". </p>
115
116    <li> <p> The order of the attributes does not matter. The policy
117    server should ignore any attributes that it does not care about.
118    </p>
119
120    <li> <p> When the same attribute name is sent more than once,
121    the server may keep the first value or the last attribute value.
122    </p>
123
124    <li> <p> When an attribute value is unavailable, the client
125    either does not send the attribute, sends the attribute with
126    an empty value ("name="), or sends a zero value ("name=0") in
127    the case of a numerical attribute. </p>
128
129    <li> <p> The "recipient" attribute is available in the "RCPT
130    TO" stage. It is also available in the "DATA" and "END-OF-MESSAGE"
131    stages if Postfix accepted only one recipient for the current
132    message.  </p>
133
134    <li> <p> The "recipient_count" attribute (Postfix 2.3 and later)
135    is non-zero only in the "DATA" and "END-OF-MESSAGE" stages. It
136    specifies the number of recipients that Postfix accepted for
137    the current message.  </p>
138
139    <li> <p> The client address is an IPv4 dotted quad in the form
140    1.2.3.4 or it is an IPv6 address in the form 1:2:3::4:5:6.
141    </p>
142
143    <li> <p> For a discussion of the differences between reverse
144    and verified client_name information, see the
145    reject_unknown_client_hostname discussion in the postconf(5)
146    document.  </p>
147
148    <li> <p> An attribute name must not contain "=", null or newline,
149    and an attribute value must not contain null or newline. </p>
150
151    <li> <p> The "instance" attribute value can be used to correlate
152    different requests regarding the same message delivery. These
153    requests are sent over the same policy connection (unless the
154    policy daemon terminates the connection).  Once Postfix sends
155    a query with a different instance attribute over that same
156    policy connection, the previous message delivery is either
157    completed or aborted. </p>
158
159    <li> <p> The "size" attribute value specifies the message size
160    that the client specified in the MAIL FROM command (zero if
161    none was specified). With Postfix 2.2 and later, it specifies
162    the actual message size when the client sends the END-OF-DATA
163    command.
164    </p>
165
166    <li> <p> The "sasl_*" attributes (Postfix 2.2 and later) specify
167    information about how the client was authenticated via SASL.
168    These attributes are empty in case of no SASL authentication.
169    </p>
170
171    <li> <p> The "ccert_*" attributes (Postfix 2.2 and later) specify
172    information about how the client was authenticated via TLS.
173    These attributes are empty in case of no certificate authentication.
174    As of Postfix 2.2.11 these attribute values are encoded as
175    xtext: some characters are represented by +XX, where XX is the
176    two-digit hexadecimal representation of the character value. With
177    Postfix 2.6 and later, the decoded string is an UTF-8 string
178    without non-printable ASCII characters.  </p>
179
180    <li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
181    specify information about how the connection is encrypted. With
182    plaintext connections the protocol and cipher attributes are
183    empty and the keysize is zero.  </p>
184
185    <li> <p> The "etrn_domain" attribute is defined only in the
186    context of the ETRN command, and specifies the ETRN command
187    parameter. </p>
188
189    <li> <p> The "stress" attribute is either empty or "yes".  See
190    the STRESS_README document for further information. </p>
191
192</ul>
193
194<p> The following is specific to SMTPD delegated policy requests:
195</p>
196
197<ul>
198
199    <li> <p> Protocol names are ESMTP or SMTP. </p>
200
201    <li> <p> Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT,
202    DATA, END-OF-MESSAGE, VRFY or ETRN; these are the SMTP protocol
203    states where
204    the Postfix SMTP server makes an OK/REJECT/HOLD/etc. decision.
205    </p>
206
207</ul>
208
209<p> The policy server replies with any action that is allowed in a
210Postfix SMTPD access(5) table. Example: </p>
211
212<blockquote>
213<pre>
214action=defer_if_permit Service temporarily unavailable
215[empty line]
216</pre>
217</blockquote>
218
219<p> This causes the Postfix SMTP server to reject the request with
220a 450 temporary error code and with text "Service temporarily
221unavailable", if the Postfix SMTP server finds no reason to reject
222the request permanently. </p>
223
224<p> In case of trouble the policy server must not send a reply.
225Instead the server must log a warning and disconnect.  Postfix will
226retry the request at some later time.  </p>
227
228<h2><a name="client_config">Policy client/server configuration</a></h2>
229
230<p> The Postfix delegated policy client can connect to a TCP socket
231or to a UNIX-domain socket. Examples: </p>
232
233<blockquote>
234<pre>
235inet:127.0.0.1:9998
236unix:/some/where/policy
237unix:private/policy
238</pre>
239</blockquote>
240
241<p> The first example specifies that the policy server listens on
242a TCP socket at 127.0.0.1 port 9998. The second example specifies
243an absolute pathname of a UNIX-domain socket. The third example
244specifies a pathname relative to the Postfix queue directory; use
245this for policy servers that are spawned by the Postfix master
246daemon. </p>
247
248<p> To create a policy service that listens on a UNIX-domain socket
249called "policy", and that runs under control of the Postfix spawn(8)
250daemon, you would use something like this: </p>
251
252<blockquote>
253<pre>
254 1 /etc/postfix/master.cf:
255 2     policy  unix  -       n       n       -       0       spawn
256 3       user=nobody argv=/some/where/policy-server
257 4 
258 5 /etc/postfix/main.cf:
259 6     smtpd_recipient_restrictions =
260 7         ... 
261 8         reject_unauth_destination 
262 9         check_policy_service unix:private/policy 
26310         ...
26411     policy_time_limit = 3600
265</pre>
266</blockquote>
267
268<p> NOTES: </p>
269
270<ul>
271
272<li> <p> Lines 2, 11: the Postfix spawn(8) daemon by default kills
273its child process after 1000 seconds.  This is too short for a
274policy daemon that may need to run for as long as the SMTP server
275process that talks to it. The default time limit is overruled in
276main.cf with an explicit "policy_time_limit" setting.  The name of
277the parameter is the name of the master.cf entry ("policy")
278concatenated with the "_time_limit" suffix. See spawn(8) for
279more information about the time limit parameter.  </p>
280
281<li> <p> Line 2: specify a "0" process limit instead of the default
282"-", to avoid "connection refused" and other problems when the smtpd
283process limit exceeds the default_process_limit setting. </p>
284
285<li> <p> Lines 8, 9: always specify "check_policy_service" AFTER
286"reject_unauth_destination" or else your system could become an
287open relay. </p>
288
289<li> <p> Solaris UNIX-domain sockets do not work reliably. Use
290TCP sockets instead: </p>
291
292</ul>
293
294<blockquote>
295<pre>
296 1 /etc/postfix/master.cf:
297 2     127.0.0.1:9998  inet  n       n       n       -       0       spawn
298 3       user=nobody argv=/some/where/policy-server
299 4 
300 5 /etc/postfix/main.cf:
301 6     smtpd_recipient_restrictions =
302 7         ... 
303 8         reject_unauth_destination 
304 9         check_policy_service inet:127.0.0.1:9998
30510         ...
30611     127.0.0.1:9998_time_limit = 3600
307</pre>
308</blockquote>
309
310<p> Other configuration parameters that control the client side of
311the policy delegation protocol: </p>
312
313<ul>
314
315<li> <p> smtpd_policy_service_max_idle (default: 300s): The amount
316of time before the Postfix SMTP server closes an unused policy
317client connection. </p>
318
319<li> <p> smtpd_policy_service_max_ttl (default: 1000s): The amount
320of time before the Postfix SMTP server closes an active policy
321client connection. </p>
322
323<li> <p> smtpd_policy_service_timeout (default: 100s): The time
324limit to connect to, send to or receive from a policy server. </p>
325
326</ul>
327
328<h2><a name="greylist">Example: greylist policy server</a></h2>
329
330<p> Greylisting is a defense against junk email that is described at
331http://www.greylisting.org/. The idea was discussed on the
332postfix-users mailing list <a
333href="http://archives.neohapsis.com/archives/postfix/2002-03/0846.html">
334one year before it was popularized</a>. </p>
335
336<p> The file examples/smtpd-policy/greylist.pl in the Postfix source
337tree implements a simplified greylist policy server. This server
338stores a time stamp for every (client, sender, recipient) triple.
339By default, mail is not accepted until a time stamp is more than
34060 seconds old. This stops junk mail with randomly selected sender
341addresses, and mail that is sent through randomly selected open
342proxies. It also stops junk mail from spammers that change their
343IP address frequently. </p>
344
345<p> Copy examples/smtpd-policy/greylist.pl to /usr/libexec/postfix
346or whatever location is appropriate for your system. </p>
347
348<p> In the greylist.pl Perl script you need to specify the
349location of the greylist database file, and how long mail will
350be delayed before it is accepted. The default settings are:
351</p>
352
353<blockquote>
354<pre>
355$database_name="/var/mta/greylist.db";
356$greylist_delay=60;
357</pre>
358</blockquote>
359
360<p> The /var/mta directory (or whatever you choose) should be
361writable by "nobody", or by whatever username you configure below
362in master.cf for the policy service. </p>
363
364<p> Example: </p>
365
366<blockquote>
367<pre>
368# mkdir /var/mta
369# chown nobody /var/mta
370</pre>
371</blockquote>
372
373<p> Note: DO NOT create the greylist database in a world-writable
374directory such as /tmp or /var/tmp, and DO NOT create the greylist
375database in a file system that may run out of space. Postfix can
376survive "out of space" conditions with the mail queue and with the
377mailbox store, but it cannot survive a corrupted greylist database.
378If the file becomes corrupted you may not be able to receive mail
379at all until you delete the file by hand. </p>
380
381<p> The greylist.pl Perl script can be run under control by
382the Postfix master daemon.  For example, to run the script as user
383"nobody", using a UNIX-domain socket that is accessible by Postfix
384processes only: </p>
385
386<blockquote>
387<pre>
3881 /etc/postfix/master.cf:
3892     policy  unix  -       n       n       -       0       spawn
3903       user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl
3914 
3925 /etc/postfix/main.cf:
3936      policy_time_limit = 3600
394</pre>
395</blockquote>
396
397<p> Notes: </p>
398
399<ul>
400
401<li> <p> Line 3: Specify "greylist.pl -v" for verbose logging of
402each request and reply. </p>
403
404<li> <p> Lines 2, 6: the Postfix spawn(8) daemon by default kills
405its child process after 1000 seconds.  This is too short for a
406policy daemon that may run for as long as an SMTP client is connected
407to an SMTP server process. The default time limit is overruled in
408main.cf with an explicit "policy_time_limit" setting.  The name of
409the parameter is the name of the master.cf entry ("policy")
410concatenated with the "_time_limit" suffix.  </p>
411
412<li> <p> Line 2: specify a "0" process limit instead of the default
413"-", to avoid "connection refused" and other problems when the smtpd
414process limit exceeds the default_process_limit setting. </p>
415
416</ul>
417
418<p> On Solaris you must use inet: style sockets instead of unix:
419style, as detailed in the "<a href="#client_config">Policy
420client/server configuration</a>" section above.  </p>
421
422<blockquote>
423<pre>
4241 /etc/postfix/master.cf:
4252     127.0.0.1:9998  inet  n       n       n       -       0       spawn
4263       user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl
4274 
4285 /etc/postfix/main.cf:
4296      127.0.0.1:9998_time_limit = 3600
430</pre>
431</blockquote>
432
433<p> To invoke this service you would specify "check_policy_service
434inet:127.0.0.1:9998". </p>
435
436<h2><a name="frequent">Greylisting mail from frequently forged domains</a></h2>
437
438<p> It is relatively safe to turn on greylisting for specific
439domains that often appear in forged email.  At some point
440in cyberspace/time a list of frequently
441forged MAIL FROM domains could be found at
442http://www.monkeys.com/anti-spam/filtering/sender-domain-validate.in.
443
444<blockquote>
445<pre>
446 1 /etc/postfix/main.cf:
447 2     smtpd_recipient_restrictions =
448 3         reject_unlisted_recipient
449 4         ...
450 5         reject_unauth_destination 
451 6         check_sender_access hash:/etc/postfix/sender_access
452 7         ...
453 8     smtpd_restriction_classes = greylist
454 9     greylist = check_policy_service unix:private/policy
45510 
45611 /etc/postfix/sender_access:
45712     aol.com     greylist
45813     hotmail.com greylist
45914     bigfoot.com greylist
46015     ... <i>etcetera</i> ...
461</pre>
462</blockquote>
463
464<p> NOTES: </p>
465
466<ul>
467
468<li> <p> Line 9: On Solaris you must use inet: style sockets
469instead of unix: style, as detailed in the "<a href="#greylist">Example:
470greylist policy server</a>" section above.  </p>
471
472<li> <p> Line 6: Be sure to specify "check_sender_access" AFTER
473"reject_unauth_destination" or else your system could become an
474open mail relay. </p>
475
476<li> <p> Line 3: With Postfix 2.0 snapshot releases,
477"reject_unlisted_recipient" is called "check_recipient_maps".
478Postfix 2.1 understands both forms. </p>
479
480<li> <p> Line 3: The greylist database gets polluted quickly with
481bogus addresses.  It helps if you protect greylist lookups with
482other restrictions that reject unknown senders and/or recipients.
483</p>
484
485</ul>
486
487<h2><a name="all_mail">Greylisting all your mail</a></h2>
488
489<p> If you turn on greylisting for all mail you will almost certainly
490want to make exceptions for mailing lists that use one-time sender
491addresses, because such mailing lists can pollute your greylist
492database relatively quickly. </p>
493
494<blockquote>
495<pre>
496 1 /etc/postfix/main.cf:
497 2     smtpd_recipient_restrictions =
498 3         reject_unlisted_recipient
499 4         ...
500 5         reject_unauth_destination 
501 6         check_sender_access hash:/etc/postfix/sender_access
502 7         check_policy_service unix:private/policy
503 8         ...
504 9 
50510 /etc/postfix/sender_access:
50611     securityfocus.com OK
50712     ...
508</pre>
509</blockquote>
510
511<p> NOTES: </p>
512
513<ul>
514
515<li> <p> Line 7: On Solaris you must use inet: style sockets
516instead of unix: style, as detailed in the "<a href="#greylist">Example:
517greylist policy server</a>" section above.  </p>
518
519<li> <p> Lines 6-7: Be sure to specify check_sender_access and
520check_policy_service AFTER reject_unauth_destination or else your
521system could become an open mail relay. </p>
522
523<li> <p> Line 3: The greylist database gets polluted quickly with
524bogus addresses.  It helps if you precede greylist lookups with
525restrictions that reject unknown senders and/or recipients. </p>
526
527</ul>
528
529<h2><a name="maintenance">Routine greylist maintenance</a></h2>
530
531<p> The greylist database grows over time, because the greylist server
532never removes database entries. If left unattended, the greylist
533database will eventually run your file system out of space. </p>
534
535<p> When the status file size exceeds some threshold you can simply
536rename or remove the file without adverse effects; Postfix
537automatically creates a new file. In the worst case, new mail will
538be delayed by an hour or so. To lessen the impact, rename or remove
539the file in the middle of the night at the beginning of a weekend.
540</p>
541
542<h2><a name="greylist_code">Example Perl greylist server</a></h2>
543
544<p> This is the Perl subroutine that implements the example greylist
545policy.  It is part of a general purpose sample policy server that
546is distributed with the Postfix source as
547examples/smtpd-policy/greylist.pl. </p>
548
549<pre>
550#
551# greylist status database and greylist time interval. DO NOT create the
552# greylist status database in a world-writable directory such as /tmp
553# or /var/tmp. DO NOT create the greylist database in a file system
554# that can run out of space.
555#
556$database_name="/var/mta/greylist.db";
557$greylist_delay=60;
558
559#
560# Auto-whitelist threshold. Specify 0 to disable, or the number of
561# successful "come backs" after which a client is no longer subject
562# to greylisting.
563#
564$auto_whitelist_threshold = 10;
565
566#
567# Demo SMTPD access policy routine. The result is an action just like
568# it would be specified on the right-hand side of a Postfix access
569# table.  Request attributes are available via the %attr hash.
570#
571sub smtpd_access_policy {
572    my($key, $time_stamp, $now);
573
574    # Open the database on the fly.
575    open_database() unless $database_obj;
576
577    # Search the auto-whitelist.
578    if ($auto_whitelist_threshold &gt; 0) {
579        $count = read_database($attr{"client_address"});
580        if ($count &gt; $auto_whitelist_threshold) {
581            return "dunno";
582        }
583    }
584
585    # Lookup the time stamp for this client/sender/recipient.
586    $key =
587        lc $attr{"client_address"}."/".$attr{"sender"}."/".$attr{"recipient"};
588    $time_stamp = read_database($key);
589    $now = time();
590
591    # If new request, add this client/sender/recipient to the database.
592    if ($time_stamp == 0) {
593        $time_stamp = $now;
594        update_database($key, $time_stamp);
595    }
596
597    # The result can be any action that is allowed in a Postfix access(5) map.
598    #
599    # To label the mail, return ``PREPEND headername: headertext''
600    #
601    # In case of success, return ``DUNNO'' instead of ``OK'', so that the
602    # check_policy_service restriction can be followed by other restrictions.
603    #
604    # In case of failure, return ``DEFER_IF_PERMIT optional text...'',
605    # so that mail can still be blocked by other access restrictions.
606    #
607    syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose;
608    if ($now - $time_stamp &gt; $greylist_delay) {
609        # Update the auto-whitelist.
610        if ($auto_whitelist_threshold &gt; 0) {
611            update_database($attr{"client_address"}, $count + 1);
612        }
613        return "dunno";
614    } else {
615        return "defer_if_permit Service temporarily unavailable";
616    }
617}
618</pre>
619
620</body>
621
622</html>
623