1POSTFWD3(1) User Contributed Perl Documentation POSTFWD3(1)
2
3
4
6 postfwd3 - postfix firewall daemon
7
9 postfwd3 [OPTIONS] [COMMAND]
10
11 postfwd3 [OPTIONS] --cmd [SOURCE1, SOURCE2, ...]
12
13 Ruleset: (at least one, multiple use is allowed):
14 -f, --file <file> reads rules from <file>
15 -r, --rule <rule> adds <rule> to config
16 -s, --scores <v>=<r> returns <r> when score exceeds <v>
17
18 Settings: (multiple use allowed)
19 -F, --loadsettings <file> loads program settings from <file>
20 --savesettings <file> saves program settings to <file>
21 --showsettings exports program settings to stdout
22
23 Server:
24 -i, --interface <dev> listen on interface <dev>
25 -p, --port <port> listen on port <port>
26 --proto <proto> socket type (tcp or unix)
27 --server_socket <sock> e.g. tcp:127.0.0.1:10045
28 -u, --user <name> set uid to user <name>
29 -g, --group <name> set gid to group <name>
30 --umask <mask> umask for master filepermissions
31 --server_umask <mask> umask for server filepermissions
32 --pidfile <path> create pidfile under <path>
33 --min_servers <i> spawn at least <i> children
34 --max_servers <i> do not spawn more than <i> children
35 --min_spare_servers <i> minimum idle children
36 --max_spare_servers <i> maximum idle children
37
38 Cache:
39 -c, --cache <int> sets the request-cache timeout to <int> seconds
40 --cleanup-requests <int> cleanup interval in seconds for request cache
41 --cache_interface <dev> listen on interface <dev>
42 --cache_port <port> listen on port <port>
43 --cache_proto <proto> socket type (tcp or unix)
44 --cache_socket <sock> e.g. tcp:127.0.0.1:10043
45 --cache_umask <mask> umask for cache filepermissions
46 --cacheid <list> list of request items for cache-id
47 --cacheid_md5 cacheid => md5sum(request)
48 --cache-rdomain-only skip recipient localpart for cache-id
49 --cache-no-sender skip sender address for cache-id
50 --cache-no-size skip size for cache-id
51 --no_parent_request_cache disable parent request cache
52 --no_parent_rate_cache disable parent rate cache
53 --no_parent_dns_cache disable parent dns cache (default)
54 --no_parent_group_cache disable parent group cache
55 --no_parent_cache disable all parent caches
56
57 Groups:
58 --default_group_ttl <i> default group TTL
59 --group_maxitems <i> max items per group
60 --cleanup-groups <int> cleanup interval in seconds for group objects
61
62 Rates:
63 --cleanup-rates <int> cleanup interval in seconds for rate cache
64
65 Control:
66 -k, --kill, --stop terminate postfwd3
67 --reload, --hup reload postfwd3
68 --watchdog <w> watchdog timer in seconds
69 --respawn <r> respawn delay in seconds
70 --failures <f> max respawn failure counter
71 -d, --daemon execute program in background
72 --nodaemon execute program in foreground
73 --daemons <list> list of daemons to start
74 --personality <type> type of policy server, allows 'PreFork' or 'Multiplex'
75 --autopersonality determine personality by program name (see manpage)
76 --noautopersonality don't do it (see above :)
77 --v1 set personality to 'Multiplex'
78 --v2 set personality to 'PreFork'
79 --dumpcache show cache contents
80 --dumpstats show statistics
81 -R, --chroot <path> chroot to <path> before start
82 --delcache <item> removes an item from the request cache
83 --delrate <item> removes an item from the rate cache
84
85 DNS:
86 -n, --nodns skip any dns based test
87 --dns_timeout <i> dns query timeout in seconds
88 --dns_timeout_max <i> disable dnsbl after <i> timeouts
89 --dns_timeout_interval <i> reenable dnsbl after <i> seconds
90 --cache-rbl-timeout <i> default dns ttl if not specified in ruleset
91 --cache-rbl-default <s> default dns pattern if not specified in ruleset
92 --cleanup-rbls <i> cleanup old dns cache items every <i> seconds
93 --dns_async_txt perform dnsbl A and TXT lookups simultaneously
94 --dns_max_ns_lookups max names to look up with sender_ns_addrs
95 --dns_max_mx_lookups max names to look up with sender_mx_addrs
96 --ipv6_dnsbl enables dnsbl checks for IPv6 addresses
97
98 Optional:
99 -t, --test testing, always returns "dunno"
100 -S, --summary <i> show stats every <i> seconds
101 --noidlestats disables statistics when idle
102 --norulestats disables per rule statistics
103 -I, --instantcfg reloads ruleset on every new request
104 --config_timeout <i> parser timeout in seconds
105 --keep_groups do not clear group cache on reload
106 --save_groups <file> save and load group cache on disk
107 --keep_rates do not clear rate limit counters on reload
108 --save_rates <file> save and load rate limits on disk
109 -A, --aggregate_addrs pre-compute ip address lists to subnets
110 --no_netaddr don't use NetAddr::IP functions
111 --no_netcidr don't use Net::CIDR::Lite functions
112 --cidr_method=s use method <s> for network checks
113
114
115 Plugins:
116 --plugins <file> loads postfwd plugins from file
117
118 Logging:
119 -l, --logname <label> label for syslog messages
120 --facility <s> use syslog facility <s>
121 --socktype <s> use syslog socktype <s>
122 --nodnslog do not log dns results
123 --anydnslog log any dns (even cached) results
124 --norulelog do not log rule actions
125 --nolog|--perfmon no logging at all
126 -v, --verbose verbose logging, use twice to increase
127 --debug <s> list of debugging classes
128 --debugclasses shows all available debug classes
129 and exits the program
130
131 Information (use only at command-line!):
132 -h, --help display this help and exit
133 -m, --manual shows program manual
134 -V, --version output version information and exit
135 -D, --defaults show postfwd3 settings and exit
136 -C, --showconfig show postfwd3 ruleset and exit (-v allowed)
137 -L, --stdout redirect syslog messages to stdout (--stdoutlog works for compatibility)
138 --stdin pull request from stdin instead of a network socket
139 --cmd shorthand form of --stdin, --stdout and --nodaemon
140 -q, --quiet no syslogging, no stdout (-P works for compatibility)
141
142 Commands:
143 start start the program [default]
144 stop same as --stop
145 reload same as --reload
146 dumpcache same as --dumpcache
147 dumpstats same as --dumpstats
148 defaults same as --defaults
149 showsettings same as --showsettings
150 delcache <item> same as --delcache <item>
151 delrate <item> same as --delrate <item>
152
153 Obsolete (only for compatibility with postfwd v1):
154 --shortlog, --dns_queuesize, --dns_retries
155
157 INTRODUCTION
158 postfwd3 is written to combine complex postfix restrictions in a
159 ruleset similar to those of the most firewalls. The program uses the
160 postfix policy delegation protocol to control access to the mail system
161 before a message has been accepted (please visit
162 <http://www.postfix.org/SMTPD_POLICY_README.html> for more
163 information).
164
165 postfwd3 allows you to choose an action (e.g. reject, dunno) for a
166 combination of several smtp parameters (like sender and recipient
167 address, size or the client's TLS fingerprint). Also it offers simple
168 macros/acls which should allow straightforward and easy-to-read
169 configurations.
170
171 Features:
172
173 * Complex combinations of smtp parameters
174
175 * Combined RBL/RHSBL lookups with arbitrary actions depending on
176 results
177
178 * Scoring system
179
180 * Date/time based rules
181
182 * Macros/ACLs, Dynamic groups, Negation
183
184 * Compare request attributes (e.g. client_name and helo_name)
185
186 * Internal caching for requests and dns lookups
187
188 * Built in statistics for rule efficiency analysis
189
190 CONFIGURATION
191 A configuration line consists of optional item=value pairs, separated
192 by semicolons (`;`) and the appropriate desired action:
193
194 [ <item1>=<value>; <item2>=<value>; ... ] action=<result>
195
196 Example:
197
198 client_address=192.168.1.1 ; sender==no@bad.local ; action=REJECT
199
200 This will deny all mail from 192.168.1.1 with envelope sender
201 no@bad.local. The order of the elements is not important. So the
202 following would lead to the same result as the previous example:
203
204 action=REJECT ; client_address=192.168.1.1 ; sender==no@bad.local
205
206 The way how request items are compared to the ruleset can be influenced
207 in the following way:
208
209 ====================================================================
210 ITEM == VALUE true if ITEM equals VALUE
211 ITEM => VALUE true if ITEM >= VALUE
212 ITEM =< VALUE true if ITEM <= VALUE
213 ITEM > VALUE true if ITEM > VALUE
214 ITEM < VALUE true if ITEM < VALUE
215 ITEM =~ VALUE true if ITEM ~= /^VALUE$/i
216 ITEM != VALUE false if ITEM equals VALUE
217 ITEM !> VALUE false if ITEM >= VALUE
218 ITEM !< VALUE false if ITEM <= VALUE
219 ITEM !~ VALUE false if ITEM ~= /^VALUE$/i
220 ITEM = VALUE default behaviour (see ITEMS section)
221 ====================================================================
222
223 To identify single rules in your log files, you may add an unique
224 identifier for each of it:
225
226 id=R_001 ; action=REJECT ; client_address=192.168.1.1 ; sender==no@bad.local
227
228 You may use these identifiers as target for the `jump()` command (see
229 ACTIONS section below). Leading or trailing whitespace characters will
230 be ignored. Use '#' to comment your configuration. Others will
231 appreciate.
232
233 A ruleset consists of one or multiple rules, which can be loaded from
234 files or passed as command line arguments. Please see the COMMAND LINE
235 section below for more information on this topic.
236
237 Since postfwd version 1.30 rules spanning span multiple lines can be
238 defined by prefixing the following lines with one or multiple
239 whitespace characters (or '}' for macros):
240
241 id=RULE001
242 client_address=192.168.1.0/24
243 sender==no@bad.local
244 action=REJECT no access
245
246 postfwd versions prior to 1.30 require trailing ';' and '\'-characters:
247
248 id=RULE001; \
249 client_address=192.168.1.0/24; \
250 sender==no@bad.local; \
251 action=REJECT no access
252
253 ITEMS
254 id - a unique rule id, which can be used for log analysis
255 ids also serve as targets for the "jump" command.
256
257 date, time - a time or date range within the specified rule shall hit
258 # FORMAT:
259 # Feb, 29th
260 date=29.02.2008
261 # Dec, 24th - 26th
262 date=24.12.2008-26.12.2008
263 # from today until Nov, 23rd
264 date=-23.09.2008
265 # from April, 1st until today
266 date=01.04.2008-
267
268 days, months - a range of weekdays (Sun-Sat) or months (Jan-Dec)
269 within the specified rule shall hit
270
271 score - when the specified score is hit (see ACTIONS section)
272 the specified action will be returned to postfix
273 scores are set global until redefined!
274
275 request_score - this value allows to access a request's score. it
276 may be used as variable ($$request_score).
277
278 rbl, rhsbl, - query the specified RBLs/RHSBLs, possible values are:
279 rhsbl_client, <name>[/<reply>/<maxcache>, <name>/<reply>/<maxcache>]
280 rhsbl_sender, (defaults: reply=^127\.0\.0\.\d+$ maxcache=3600)
281 rhsbl_reverse_client the results of all rhsbl_* queries will be combined
282 in rhsbl_count (see below).
283
284 rblcount, rhsblcount - minimum RBL/RHSBL hitcounts to match. if not specified
285 a single RBL/RHSBL hit will match the rbl/rhsbl items.
286 you may specify 'all' to evaluate all items, and use
287 it as variable in an action (see ACTIONS section)
288 (default: 1)
289
290 sender_localpart, - the local-/domainpart of the sender address
291 sender_domain
292
293 recipient_localpart, - the local-/domainpart of the recipient address
294 recipient_domain
295
296 helo_address - postfwd3 tries to look up the helo_name. use
297 helo_address=!!(0.0.0.0/0) to check for unknown.
298 Please do not use this for positive access control
299 (whitelisting), as it might be forged.
300
301 sender_ns_names, - postfwd3 tries to look up the names/ip addresses
302 sender_ns_addrs of the nameservers for the sender domain part.
303 Please do not use this for positive access control
304 (whitelisting), as it might be forged.
305
306 sender_mx_names, - postfwd3 tries to look up the names/ip addresses
307 sender_mx_addrs of the mx records for the sender domain part.
308 Please do not use this for positive access control
309 (whitelisting), as it might be forged.
310
311 version - postfwd3 version, contains "postfwd3 n.nn"
312 this enables version based checks in your rulesets
313 (e.g. for migration). works with old versions too,
314 because a non-existing item always returns false:
315 # version >= 1.10
316 id=R01; version~=1\.[1-9][0-9]; sender_domain==some.org \
317 ; action=REJECT sorry no access
318
319 postfwd_port - postfwd server port, allows to use the same ruleset different
320 instances:
321 # rule only hits for instance at port 10045
322 id=PORT10045; postfwd_port==10045; action=DUNNO
323
324 postfwd_interface - postfwd server initerface, see postfwd_port
325
326 ratecount - only available for rate(), size() and rcpt() actions.
327 contains the actual limit counter:
328 id=R01; action=rate(sender/200/600/REJECT limit of 200 exceeded [$$ratecount hits])
329 id=R02; action=rate(sender/100/600/WARN limit of 100 exceeded [$$ratecount hits])
330
331 Besides these you can specify any attribute of the postfix policy
332 delegation protocol. Feel free to combine them the way you need it
333 (have a look at the EXAMPLES section below).
334
335 Most values can be specified as regular expressions (PCRE). Please see
336 the table below for details:
337
338 # ==========================================================
339 # ITEM=VALUE TYPE
340 # ==========================================================
341 id=something mask = string
342 date=01.04.2007-22.04.2007 mask = date (DD.MM.YYYY-DD.MM.YYYY)
343 time=08:30:00-17:00:00 mask = time (HH:MM:SS-HH:MM:SS)
344 days=Mon-Wed mask = weekdays (Mon-Wed) or numeric (1-3)
345 months=Feb-Apr mask = months (Feb-Apr) or numeric (1-3)
346 score=5.0 mask = maximum floating point value
347 rbl=zen.spamhaus.org mask = <name>/<reply>/<maxcache>[,...]
348 rblcount=2 mask = numeric, will match if rbl hits >= 2
349 helo_address=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
350 sender_ns_names=some.domain.tld mask = PCRE
351 sender_mx_names=some.domain.tld mask = PCRE
352 sender_ns_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
353 sender_mx_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
354 # ------------------------------
355 # Postfix version 2.1 and later:
356 # ------------------------------
357 client_address=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
358 client_name=another.domain.tld mask = PCRE
359 reverse_client_name=another.domain.tld mask = PCRE
360 helo_name=some.domain.tld mask = PCRE
361 sender=foo@bar.tld mask = PCRE
362 recipient=bar@foo.tld mask = PCRE
363 recipient_count=5 mask = numeric, will match if recipients >= 5
364 # ------------------------------
365 # Postfix version 2.2 and later:
366 # ------------------------------
367 sasl_method=plain mask = PCRE
368 sasl_username=you mask = PCRE
369 sasl_sender= mask = PCRE
370 size=12345 mask = numeric, will match if size >= 12345
371 ccert_subject=blackhole.nowhere.local mask = PCRE (only if tls verified)
372 ccert_issuer=John+20Doe mask = PCRE (only if tls verified)
373 ccert_fingerprint=AA:BB:CC:DD:EE:... mask = PCRE (do NOT use "..." here)
374 # ------------------------------
375 # Postfix version 2.3 and later:
376 # ------------------------------
377 encryption_protocol=TLSv1/SSLv3 mask = PCRE
378 encryption_cipher=DHE-RSA-AES256-SHA mask = PCRE
379 encryption_keysize=256 mask = numeric, will match if keysize >= 256
380 ...
381
382 the current list can be found at
383 <http://www.postfix.org/SMTPD_POLICY_README.html>. Please read
384 carefully about which attribute can be used at which level of the smtp
385 transaction (e.g. size will only work reliably at END-OF-MESSAGE
386 level). Pattern matching is performed case insensitive.
387
388 Multiple use of the same item is allowed and will compared as logical
389 OR, which means that this will work as expected:
390
391 id=TRUST001; action=OK; encryption_keysize=64
392 ccert_fingerprint=11:22:33:44:55:66:77:88:99
393 ccert_fingerprint=22:33:44:55:66:77:88:99:00
394 ccert_fingerprint=33:44:55:66:77:88:99:00:11
395 sender=@domain\.local$
396
397 client_address, rbl and rhsbl items may also be specified as
398 whitespace-or-comma-separated values:
399
400 id=SKIP01; action=dunno
401 client_address=192.168.1.0/24, 172.16.254.23
402 id=SKIP02; action=dunno
403 client_address= 10.10.3.32 10.216.222.0/27
404
405 The following items must be unique:
406
407 id, minimum and maximum values, rblcount and rhsblcount
408
409 Any item can be negated by preceeding '!!' to it, e.g.:
410
411 id=HOST001 ; hostname == !!secure.trust.local ; action=REJECT only secure.trust.local please
412
413 or using the right compare operator:
414
415 id=HOST001 ; hostname != secure.trust.local ; action=REJECT only secure.trust.local please
416
417 To avoid confusion with regexps or simply for better visibility you can
418 use '!!(...)':
419
420 id=USER01 ; sasl_username =~ !!( /^(bob|alice)$/ ) ; action=REJECT who is that?
421
422 Request attributes can be compared by preceeding '$$' characters, e.g.:
423
424 id=R-003 ; client_name = !! $$helo_name ; action=WARN helo does not match DNS
425 # or
426 id=R-003 ; client_name = !!($$(helo_name)) ; action=WARN helo does not match DNS
427
428 This is only valid for PCRE values (see list above). The comparison
429 will be performed as case insensitive exact match. Use the '-vv'
430 option to debug.
431
432 These special items will be reset for any new rule:
433
434 rblcount - contains the number of RBL answers
435 rhsblcount - contains the number of RHSBL answers
436 matches - contains the number of matched items
437 dnsbltext - contains the dns TXT part of all RBL and RHSBL replies in the form
438 rbltype:rblname:<txt>; rbltype:rblname:<txt>; ...
439
440 These special items will be changed for any matching rule:
441
442 request_hits - contains ids of all matching rules
443
444 This means that it might be necessary to save them, if you plan to use
445 these values in later rules:
446
447 # set vals
448 id=RBL01 ; rhsblcount=all; rblcount=all
449 action=set(HIT_rhls=$$rhsblcount,HIT_rbls=$$rblcount,HIT_txt=$$dnsbltext)
450 rbl=list.dsbl.org, bl.spamcop.net, dnsbl.sorbs.net, zen.spamhaus.org
451 rhsbl_client=rddn.dnsbl.net.au, rhsbl.ahbl.org, rhsbl.sorbs.net
452 rhsbl_sender=rddn.dnsbl.net.au, rhsbl.ahbl.org, rhsbl.sorbs.net
453
454 # compare
455 id=RBL02 ; HIT_rhls>=1 ; HIT_rbls>=1 ; action=554 5.7.1 blocked using $$HIT_rhls RHSBLs and $$HIT_rbls RBLs [INFO: $$HIT_txt]
456 id=RBL03 ; HIT_rhls>=2 ; action=554 5.7.1 blocked using $$HIT_rhls RHSBLs [INFO: $$HIT_txt]
457 id=RBL04 ; HIT_rbls>=2 ; action=554 5.7.1 blocked using $$HIT_rbls RBLs [INFO: $$HIT_txt]
458
459 FILES
460 Since postfwd1 v1.15 and postfwd3 v0.18 long item lists can be stored
461 in separate files:
462
463 id=R001 ; ccert_fingerprint==file:/etc/postfwd/wl_ccerts ; action=DUNNO
464
465 postfwd3 will read a list of items (one item per line) from
466 /etc/postfwd/wl_ccerts. comments are allowed:
467
468 # client1
469 11:22:33:44:55:66:77:88:99
470 # client2
471 22:33:44:55:66:77:88:99:00
472 # client3
473 33:44:55:66:77:88:99:00:11
474
475 To use existing tables in key=value format, you can use:
476
477 id=R001 ; ccert_fingerprint==table:/etc/postfwd/wl_ccerts ; action=DUNNO
478
479 This will ignore the right-hand value. Items can be mixed:
480
481 id=R002 ; action=REJECT
482 client_name==unknown
483 client_name==file:/etc/postfwd/blacklisted
484
485 and for non pcre (comma separated) items:
486
487 id=R003 ; action=REJECT
488 client_address==10.1.1.1, file:/etc/postfwd/blacklisted
489
490 id=R004 ; action=REJECT
491 rbl=myrbl.home.local, zen.spamhaus.org, file:/etc/postfwd/rbls_changing
492
493 You can check your configuration with the --show_config option at the
494 command line:
495
496 # postfwd3 --showconfig --rule='action=DUNNO; client_address=10.1.0.0/16, file:/etc/postfwd/wl_clients, 192.168.2.1'
497
498 should give something like:
499
500 Rule 0: id->"R-0"; action->"DUNNO"; client_address->"=;10.1.0.0/16, =;194.123.86.10, =;186.4.6.12, =;192.168.2.1"
501
502 If a file can not be read, it will be ignored:
503
504 # postfwd3 --showconfig --rule='action=DUNNO; client_address=10.1.0.0/16, file:/etc/postfwd/wl_clients, 192.168.2.1'
505 [LOG warning]: error: file /etc/postfwd/wl_clients not found - file will be ignored ?
506 Rule 0: id->"R-0"; action->"DUNNO"; client_address->"=;10.1.0.0/16, =;192.168.2.1"
507
508 File items are evaluated at configuration stage. Therefore postfwd3
509 needs to be reloaded if a file has changed
510
511 If you want to specify a file, that will be reloaded for each request,
512 you can use lfile: and ltable:
513
514 id=R001; client_address=lfile:/etc/postfwd/client_whitelist; action=dunno
515
516 This will check the modification time of /etc/postfwd/client_whitelist
517 every time the rule is evaluated and reload it as necessary. Of course
518 this might increase the system load, so please use it with care.
519
520 The --showconfig option illustrates the difference:
521
522 ## evaluated at configuration stage
523 # postfwd3 --nodaemon -L --rule='client_address=table:/etc/postfwd/clients; action=dunno' -C
524 Rule 0: id->"R-0"; action->"dunno"; client_address->"=;1.1.1.1, =;1.1.1.2, =;1.1.1.3"
525
526 ## evaluated for any rulehit
527 # postfwd3 --nodaemon -L --rule='client_address=ltable:/etc/postfwd/clients; action=dunno' -C
528 Rule 0: id->"R-0"; action->"dunno"; client_address->"=;ltable:/etc/postfwd/clients"
529
530 Files can refer to other files. The following is valid.
531
532 -- FILE /etc/postfwd/rules.cf --
533 id=R01; client_address=file:/etc/postfwd/clients_master.cf; action=DUNNO
534
535 -- FILE /etc/postfwd/clients_master.cf --
536 192.168.1.0/24
537 file:/etc/postfwd/clients_east.cf
538 file:/etc/postfwd/clients_west.cf
539
540 -- FILE /etc/postfwd/clients_east.cf --
541 192.168.2.0/24
542
543 -- FILE /etc/postfwd/clients_west.cf --
544 192.168.3.0/24
545
546 Note that there is currently no loop detection (/a/file calls /a/file)
547 and that this feature is only available with postfwd1 v1.15 and
548 postfwd3 v0.18 and higher.
549
550 ACTIONS
551 General
552
553 Actions will be executed, when all rule items have matched a request
554 (or at least one of any item list). You can refer to request attributes
555 by preceeding $$ characters, like:
556
557 id=R-003; client_name = !!$$helo_name; action=WARN helo '$$helo_name' does not match DNS '$$client_name'
558 # or
559 id=R-003; client_name = !!$$helo_name; action=WARN helo '$$(helo_name)' does not match DNS '$$(client_name)'
560
561 postfix actions
562
563 Actions will be replied to postfix as result to policy delegation
564 requests. Any action that postfix understands is allowed - see "man 5
565 access" or <http://www.postfix.org/access.5.html> for a description. If
566 no action is specified, the postfix WARN action which simply logs the
567 event will be used for the corresponding rule.
568
569 postfwd3 will return dunno if it has reached the end of the ruleset and
570 no rule has matched. This can be changed by placing a last rule
571 containing only an action statement:
572
573 ...
574 action=dunno ; sender=@domain.local # sender is ok
575 action=reject # default deny
576
577 postfwd3 actions
578
579 postfwd3 actions control the behaviour of the program. Currently you
580 can specify the following:
581
582 jump (<id>)
583 jumps to rule with id <id>, use this to skip certain rules.
584 you can jump backwards - but remember that there is no loop
585 detection at the moment! jumps to non-existing ids will be skipped.
586
587 score (<score>)
588 the request's score will be modified by the specified <score>,
589 which must be a floating point value. the modificator can be either
590 +n.nn adds n.nn to current score
591 -n.nn sustracts n.nn from the current score
592 *n.nn multiplies the current score by n.nn
593 /n.nn divides the current score through n.nn
594 =n.nn sets the current score to n.nn
595 if the score exceeds the maximum set by `--scores` option (see
596 COMMAND LINE) or the score item (see ITEMS section), the action
597 defined for this case will be returned (default: 5.0=>"REJECT postfwd3 score exceeded").
598
599 set (<item>=<value>,<item>=<value>,...)
600 this command allows you to insert or override request attributes, which then may be
601 compared to your further ruleset. use this to speed up repeated comparisons to large item lists.
602 please see the EXAMPLES section for more information. you may separate multiple key=value pairs
603 by "," characters.
604
605 rate (<item>/<max>/<time>/<action>)
606 this command creates a counter for the given <item>, which will be increased any time a request
607 containing it arrives. if it exceeds <max> within <time> seconds it will return <action> to postfix.
608 rate counters are very fast as they are executed before the ruleset is parsed.
609 please note that <action> was limited to postfix actions (no postfwd actions) for postfwd versions <1.33!
610 # no more than 3 requests per 5 minutes
611 # from the same "unknown" client
612 id=RATE01 ; client_name==unknown
613 action=rate(client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)
614
615 size (<item>/<max>/<time>/<action>)
616 this command works similar to the rate() command with the difference, that the rate counter is
617 increased by the request's size attribute. to do this reliably you should call postfwd3 from
618 smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
619 # size limit 1.5mb per hour per client
620 id=SIZE01 ; protocol_state==END-OF-MESSAGE ; client_address==!!(10.1.1.1)
621 action=size(client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)
622
623 rcpt (<item>/<max>/<time>/<action>)
624 this command works similar to the rate() command with the difference, that the rate counter is
625 increased by the request's recipient_count attribute. to do this reliably you should call postfwd
626 from smtpd_data_restrictions or smtpd_end_of_data_restrictions. if you want to be sure, you could
627 check it within the ruleset:
628 # recipient count limit 3 per hour per client
629 id=RCPT01 ; protocol_state==END-OF-MESSAGE ; client_address==!!(10.1.1.1)
630 action=rcpt(client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)
631
632 rate5321,size5321,rcpt5321 (<item>/<max>/<time>/<action>)
633 same as the corresponding non-5321 functions, with the difference that the localpart of
634 sender oder recipient addresses are evaluated case-sensitive according to rfc5321. That
635 means that requests from bob@example.local and BoB@example.local will be treated differently
636
637 groupadd(<groupname>/<item>[/<ttl>])
638 saves <item> to dynamic group <group> for later use. the object will be removed from that
639 group after ttl seconds. if not set, postfwd3 will use the default --default_group_ttl [3600s].
640 Please read the chapter about dynamic groups before use!
641 # add client_address to group %%blacklisted_hosts
642 id=ADDGROUP
643 rbl=zen.spamhaus.org,bl.spamcop.net,ix.dnsbl.manitu.net
644 action=groupadd(%%blacklisted_hosts/client_address/86400)
645
646 groupdel(<groupname>/<item>)
647 removes <item> from dynamic group <group>. Please read the chapter about dynamic groups before use!
648 # remove a client_address from group %%blacklisted_hosts
649 id=DELGROUP
650 rbl=lists.dnswl.org
651 action=groupdel(%%blacklisted_hosts/client_address)
652
653 ask (<addr>:<port>[:<ignore>])
654 allows to delegate the policy decision to another policy service (e.g. postgrey). the first
655 and the second argument (address and port) are mandatory. a third optional argument may be
656 specified to tell postfwd3 to ignore certain answers and go on parsing the ruleset:
657 # example1: query postgrey and return it's answer to postfix
658 id=GREY; client_address==10.1.1.1; action=ask(127.0.0.1:10031)
659 # example2: query postgrey but ignore it's answer, if it matches 'DUNNO'
660 # and continue parsing postfwd's ruleset
661 id=GREY; client_address==10.1.1.1; action=ask(127.0.0.1:10031:^dunno$)
662
663 mail(server/helo/from/to/subject/body)
664 This command is deprecated. You should try to use the sendmail() action instead.
665 Very basic mail command, that sends a message with the given arguments. LIMITATIONS:
666 This basically performs a telnet. No authentication or TLS are available. Additionally it does
667 not track notification state and will notify you any time, the corresponding rule hits.
668
669 sendmail(sendmail-path::from::to::subject::body)
670 Mail command, that uses an existing sendmail binary and sends a message with the given arguments.
671 LIMITATIONS: The command does not track notification state and will notify you any time, the
672 corresponding rule hits (which could mean 100 mails for a mail with 100 recipients at RCPT stage).
673
674 wait (<delay>)
675 pauses the program execution for <delay> seconds. use this for
676 delaying or throtteling connections.
677
678 note (<string>)
679 just logs the given string and continues parsing the ruleset.
680 if the string is empty, nothing will be logged (noop).
681
682 quit (<code>)
683 terminates the program with the given exit-code. postfix doesn`t
684 like that too much, so use it with care.
685
686 You can reference to request attributes, like
687
688 id=R-HELO ; helo_name=^[^\.]+$ ; action=REJECT invalid helo '$$helo_name'
689
690 Since postfwd3 version 2.00 a rule can have multiple postfwd actions,
691 like
692
693 # if client is found on list.dnswl.org,
694 # 1. send a note
695 # 2. add it's ip to group %%WHITELISTED
696 # 3. permit the request
697 id=ADDR01
698 rbl=list.dnswl.org
699 action=note(adding $$client_address to WHITELIST)
700 action=groupadd(%%WHITELISTED/client_address)
701 action=PERMIT_AUTH_DESTINATION
702
703 MACROS/ACLS
704 Multiple use of long items or combinations of them may be abbreviated
705 by macros. Those must be prefixed by '&&' (two '&' characters). First
706 the macros have to be defined as follows:
707
708 &&RBLS { rbl=zen.spamhaus.org,list.dsbl.org,bl.spamcop.net,dnsbl.sorbs.net,ix.dnsbl.manitu.net; };
709
710 Then these may be used in your rules, like:
711
712 &&RBLS ; client_name=^unknown$ ; action=REJECT
713 &&RBLS ; client_name=(\d+[\.-_]){4} ; action=REJECT
714 &&RBLS ; client_name=[\.-_](adsl|dynamic|ppp|)[\.-_] ; action=REJECT
715
716 Macros can contain actions, too:
717
718 # definition
719 &&GONOW { action=REJECT your request caused our spam detection policy to reject this message. More info at http://www.domain.local; };
720 # rules
721 &&GONOW ; &&RBLS ; client_name=^unknown$
722 &&GONOW ; &&RBLS ; client_name=(\d+[\.-_]){4}
723 &&GONOW ; &&RBLS ; client_name=[\.-_](adsl|dynamic|ppp|)[\.-_]
724
725 Macros can contain macros, too:
726
727 # definition
728 &&RBLS{
729 rbl=zen.spamhaus.org
730 rbl=list.dsbl.org
731 rbl=bl.spamcop.net
732 rbl=dnsbl.sorbs.net
733 rbl=ix.dnsbl.manitu.net
734 };
735 &&DYNAMIC{
736 client_name=^unknown$
737 client_name=(\d+[\.-_]){4}
738 client_name=[\.-_](adsl|dynamic|ppp|)[\.-_]
739 };
740 &&GOAWAY { &&RBLS; &&DYNAMIC; };
741 # rules
742 &&GOAWAY ; action=REJECT dynamic client and listed on RBL
743
744 Basically macros are simple text substitutions - see the "PARSER"
745 section for more information.
746
747 DYNAMIC GROUPS
748 Dynamic groups are list objects. You can add or remove items and
749 compare request items to their content within your ruleset. Groups are
750 saved persistant for further requests. This way you can save
751 information for later use. Every item of a group has a time-to-live
752 value.
753
754 Group-names have to be preceeded by double '%'-characters, like
755 %%GROUPNAME:
756
757 # add client_address to group %%BLACKLISTED, if sent to spamtrap
758 id=SPAMTRAP; recipient==spamtrap@domain.local; action=groupadd(%%BLACKLISTED/client_address)
759
760 # reject any request from client_address in group %%BLACKLISTED
761 id=BLACKLISTED; client_address=%%BLACKLISTED; action=REJECT
762
763 The groupadd() function receives the following arguments. The <ttl>
764 value is optional. If not specified, postfwd3 will use the default
765 --default_group_ttl [300s]:
766
767 groupadd ( <Groupname> / <item> [ / <ttl> ] )
768
769 postfwd will save this data in the following structure:
770
771 %Group_Cache -> %<Groupname> -> $<item> = <ttl>
772
773 The groupdel() function removes an item from a group:
774
775 groupdel ( <Groupname> / <item> )
776
777 Expired members will be removed at cleanup stage after --cleanup_groups
778 <i> seconds.
779
780 To compare requests with dynamic groups, these must be refered by
781 preceeding '%%'-characters:
782
783 <item> = %%<Groupname>
784
785 Empty groups always compare false. The following ruleset is possible:
786
787 # allow any request from client_address in group %%WHITELISTED
788 id=WHITEGROUP; client_address=%%WHITELISTED; action=DUNNO
789
790 # reject any request from client_address in group %%BLACKLISTED
791 id=BLACKGROUP; client_address=%%BLACKLISTED; action=REJECT
792
793 # ... other rules ...
794
795 # ... whitelist file ...
796 id=W_TRUST; action=set(WHITE=1)
797 client_address=file:/etc/postfwd/whitelist_networks
798
799 # ... whitelist dns ...
800 id=W_DNSWL; action=set(WHITE=1)
801 rbl=list.dnswl.org
802
803 # ... -> add it to whitelist for a day and allow request
804 id=W_GROUP; WHITE==1
805 action=groupadd(%%WHITELISTED/client_address/86400)
806 action=DUNNO
807
808 # ... or blacklist by sending to spamtrap ...
809 id=B_SPAMTRAP; action=set(BLACK=1)
810 recipient==spamtrap@domain.local
811
812 # ... or blacklisted by dns ...
813 id=B_DNSBL; action=set(BLACK=1)
814 rbl=zen.spamhaus.org
815
816 # ... -> add it to group BLACKLISTED for 1 hour and reject
817 id=B_GROUP; BLACK==1
818 action=groupadd(%%BLACKLISTED/client_address/3600)
819 action=REJECT
820
821 Limitations
822
823 Currently dynamic groups are kept in memory. By default postfwd3 will
824 only accept a maximum of 999999 members in a group. To deactivate this
825 limit set --group_maxitems to '-1'.
826
827 With PreFork personality, you should be aware that this information
828 must be shared through the cache daemon.
829
830 In short: Don't let these lists get excessively big unless you have
831 enough system capacity to do so. If necessary tune your config by
832 setting the <ttl> and --group_maxitems.
833
834 PLUGINS
835 Description
836
837 The plugin interface allow you to define your own checks and enhance
838 postfwd's functionality. Feel free to share useful things!
839
840 Warning
841
842 Note that the plugin interface is still at devel stage. Please test
843 your plugins carefully, because errors may cause postfwd to break! It
844 is also allowed to override attributes or built-in functions, but be
845 sure that you know what you do because some of them are used
846 internally.
847
848 Please keep security in mind, when you access sensible ressources and
849 never, ever run postfwd as privileged user! Also never trust your input
850 (especially hostnames, and e-mail addresses).
851
852 ITEMS
853
854 Item plugins are perl subroutines which integrate additional attributes
855 to requests before they are evaluated against postfwd's ruleset like
856 any other item of the policy delegation protocol. This allows you to
857 create your own checks.
858
859 plugin-items can not be used selective. these functions will be
860 executed for every request postfwd receives, so keep performance in
861 mind.
862
863 SYNOPSIS: postfwd_items_plugin{<name>}($request)
864
865 means that your subroutine, called <name>, has access to a hash-
866 reference called $request, which contains all request attributes, like
867 $request->{client_name} and saves values in the following form:
868
869 save: $result->{<item>} = <value>
870
871 this creates the new item <item> containing <value>, which will be
872 integrated in the policy delegation request and therefore may be used
873 in postfwd's ruleset.
874
875 # do NOT remove the next line
876 %postfwd_items_plugin = (
877
878 # EXAMPLES - integrated in postfwd. no need to activate them here.
879
880 # allows to check postfwd version in ruleset
881 "version" => sub {
882 my($request) = shift;
883 $request->{version} => $NAME." ".$VERSION,
884 },
885
886 # sender_domain and recipient_domain
887 "address_parts" => sub {
888 my($request) = shift;
889 $request->{sender} =~ /@([^@]*)$/;
890 $request->{sender_domain} = ($1 || '');
891 $request->{recipient} =~ /@([^@]*)$/;
892 $request->{recipient_domain} = ($1 || '');
893 },
894
895 # do NOT remove the next line
896 );
897
898 COMPARE
899
900 Compare plugins allow you to define how your new items should be
901 compared to the ruleset. These are optional. If you don't specify one,
902 the default (== for exact match, =~ for PCRE, ...) will be used.
903
904 SYNOPSIS: <item> => sub { return &{$postfwd_compare{<type>}}(@_); },
905
906 # do NOT remove the next line
907 %postfwd_compare_plugin = (
908
909 EXAMPLES - integrated in postfwd. no need to activate them here.
910
911 # Simple example
912 # SYNOPSIS: <result> = <item> (return &{$postfwd_compare{<type>}}(@_))
913 "client_address" => sub { return &{$postfwd_compare{cidr}}(@_); },
914 "size" => sub { return &{$postfwd_compare{numeric}}(@_); },
915 "recipient_count" => sub { return &{$postfwd_compare{numeric}}(@_); },
916
917 # Complex example
918 # SYNOPSIS: <result> = <item>(<operator>, <ruleset value>, <request value>, <request>)
919 "numeric" => sub {
920 my($cmp,$val,$myitem,$request) = @_;
921 my($myresult) = undef; $myitem ||= "0"; $val ||= "0";
922 if ($cmp eq '==') {
923 $myresult = ($myitem == $val);
924 } elsif ($cmp eq '=<') {
925 $myresult = ($myitem <= $val);
926 } elsif ($cmp eq '=>') {
927 $myresult = ($myitem >= $val);
928 } elsif ($cmp eq '<') {
929 $myresult = ($myitem < $val);
930 } elsif ($cmp eq '>') {
931 $myresult = ($myitem > $val);
932 } elsif ($cmp eq '!=') {
933 $myresult = not($myitem == $val);
934 } elsif ($cmp eq '!<') {
935 $myresult = not($myitem <= $val);
936 } elsif ($cmp eq '!>') {
937 $myresult = not($myitem >= $val);
938 } else {
939 $myresult = ($myitem >= $val);
940 };
941 return $myresult;
942 },
943
944 # do NOT remove the next line
945 );
946
947 ACTIONS
948
949 Action plugins allow to define new postfwd actions. By setting the
950 $stop-flag you can decide to continue or to stop parsing the ruleset.
951
952 SYNOPSIS: (<stop rule parsing>, <next rule index>, <return action>, <logprefix>) =
953 <action> (<current rule index>, <current time>, <command name>, <argument>, <logprefix>, <request>)
954
955 # do NOT remove the next line
956 %postfwd_actions_plugin = (
957
958 # EXAMPLES - integrated in postfwd. no need to activate them here.
959
960 # note(<logstring>) command
961 "note" => sub {
962 my($index,$now,$mycmd,$myarg,$myline,$request) = @_;
963 my($myaction) = 'dunno'; my($stop) = 0;
964 log_info "[RULES] ".$myline." - note: ".$myarg if $myarg;
965 return ($stop,$index,$myaction,$myline);
966 },
967
968 # skips next <myarg> rules
969 "skip" => sub {
970 my($index,$now,$mycmd,$myarg,$myline,$request) = @_;
971 my($myaction) = 'dunno'; my($stop) = 0;
972 $index += $myarg if ( $myarg and not(($index + $myarg) > $#Rules) );
973 return ($stop,$index,$myaction,$myline);
974 },
975
976 # dumps current request contents to syslog
977 "dumprequest" => sub {
978 my($index,$now,$mycmd,$myarg,$myline,$request) = @_;
979 my($myaction) = 'dunno'; my($stop) = 0;
980 map { log_info "[DUMP] rule=$index, Attribute: $_=$request{$_}" } (keys %{$request});
981 return ($stop,$index,$myaction,$myline);
982 },
983
984 # do NOT remove the next line
985 );
986
987 COMMAND LINE
988 Ruleset
989
990 The following arguments are used to specify the source of the postfwd3
991 ruleset. This means that at least one of the following is required for
992 postfwd3 to work.
993
994 -f, --file <file>
995 Reads rules from <file>. Please see the CONFIGURATION section
996 for more information.
997
998 -r, --rule <rule>
999 Adds <rule> to ruleset. Remember that you might have to quote
1000 strings that contain whitespaces or shell characters.
1001
1002 Settings
1003
1004 -F, --loadsettings <file>
1005 Loads program settings from <file>. data must be in Data::Dumper format.
1006 Please read the SETTINGS section for more information.
1007
1008 --savesettings <file>
1009 Saves program settings to <file> in Data::Dumper format.
1010 Please read the SETTINGS section for more information.
1011
1012 --showsettings
1013 Exports program settings in Data::Dumper format to stdout. This output
1014 can be saved to a file and later used with the --loadsettings option.
1015
1016 Scoring
1017
1018 -s, --scores <val>=<action>
1019 Returns <action> to postfix, when the request's score exceeds <val>
1020
1021 Multiple usage is allowed. Just chain your arguments, like:
1022
1023 postfwd3 -r "<item>=<value>;action=<result>" -f <file> -f <file> ...
1024 or
1025 postfwd3 --scores 4.5="WARN high score" --scores 5.0="REJECT postfwd3 score too high" ...
1026
1027 In case of multiple scores, the highest match will count. The order of
1028 the arguments will be reflected in the postfwd3 ruleset.
1029
1030 Networking
1031
1032 postfwd3 can be run as daemon so that it listens on the network for
1033 incoming requests. The following arguments will control it's behaviour
1034 in this case.
1035
1036 -d, --daemon, --nodaemon
1037 postfwd3 will run as daemon and listen on the network for incoming
1038 queries (default 127.0.0.1:10045). Use --nodaemon to keep postfwd3
1039 running in foreground.
1040
1041 -i, --interface <dev>
1042 Bind postfwd3 to the specified interface (default 127.0.0.1).
1043
1044 -p, --port <port>
1045 postfwd3 listens on the specified port (default tcp/10045).
1046
1047 --proto <type>
1048 The protocol type for postfwd's socket. Currently you may use 'tcp' or 'unix' here.
1049 To use postfwd3 with a unix domain socket, run it as follows:
1050 postfwd3 --proto=unix --port=/somewhere/postfwd.socket
1051
1052 -u, --user <name>
1053 Changes real and effective user to <name>.
1054
1055 -g, --group <name>
1056 Changes real and effective group to <name>.
1057
1058 --personality <type>
1059 Type of policy server, allows 'PreFork' or 'Multiplex'.
1060 This option overrides --autopersonality.
1061
1062 --v1
1063 set personality to 'Multiplex'
1064 This option overrides --autopersonality.
1065
1066 --v2
1067 set personality to 'PreFork'
1068 This option overrides --autopersonality.
1069
1070 --autopersonality
1071 postfwd3 determines the personality by program name:
1072 * 'Multiplex' for 'postfwd' or 'postfwd1'
1073 * 'PreFork' for 'postfwd2'
1074 you can disable this by using --noautopersonality or
1075 explicitly using --personality, --v1 or --v2
1076
1077 --umask <mask>
1078 Changes the umask for filepermissions of the master process (pidfile).
1079 Attention: This is umask, not chmod - you have to specify the bits that
1080 should NOT apply. E.g.: umask 077 equals to chmod 700.
1081
1082 --cache_umask <mask>
1083 Changes the umask for filepermissions of the cache process (unix domain socket).
1084
1085 --server_umask <mask>
1086 Changes the umask for filepermissions of the server process (unix domain socket).
1087
1088 -R, --chroot <path>
1089 Chroot the process to the specified path.
1090 Please look at http://postfwd.org/postfwd3-chroot.html before use!
1091
1092 --pidfile <path>
1093 The process id will be saved in the specified file.
1094
1095 --facility <f>
1096 sets the syslog facility, default is 'mail'
1097
1098 --socktype <s>
1099 sets the Sys::Syslog socktype to 'native', 'inet' or 'unix'.
1100 Default is to auto-detect this depening on module version and os.
1101
1102 -l, --logname <label>
1103 Labels the syslog messages. Useful when running multiple
1104 instances of postfwd.
1105
1106 --loglen <int>
1107 Truncates any syslog message after <int> characters.
1108
1109 Plugins
1110
1111 --plugins <file>
1112 Loads postfwd plugins from file. Please see http://postfwd.org/postfwd.plugins
1113 or the plugins.postfwd.sample that is available from the tarball for more info.
1114
1115 Optional arguments
1116
1117 These parameters influence the way postfwd3 is working. Any of them can
1118 be combined.
1119
1120 -v, --verbose
1121 Verbose logging displays a lot of useful information but can cause
1122 your logfiles to grow noticeably. So use it with caution. Set the option
1123 twice (-vv) to get more information (logs all request attributes).
1124
1125 -c, --cache <int> (default=600)
1126 Timeout for request cache, results for identical requests will be
1127 cached until config is reloaded or this time (in seconds) expired.
1128 A setting of 0 disables this feature.
1129
1130 --cache-no-size
1131 Ignores size attribute for cache comparisons which will lead to better
1132 cache-hit rates. You should set this option, if you don't use the size
1133 item in your ruleset.
1134
1135 --cache-no-sender
1136 Ignores sender address for cache comparisons which will lead to better
1137 cache-hit rates. You should set this option, if you don't use the sender
1138 item in your ruleset.
1139
1140 --cache-rdomain-only
1141 This will strip the localpart of the recipient's address before filling the
1142 cache. This may considerably increase cache-hit rates.
1143
1144 --cache-rbl-timeout <timeout> (default=3600)
1145 This default value will be used as timeout in seconds for rbl cache items,
1146 if not specified in the ruleset.
1147
1148 --cache-rbl-default <pattern> (default=^127\.0\.0\.\d+$)
1149 Matches <pattern> to rbl/rhsbl answers (regexp) if not specified in the ruleset.
1150
1151 --cacheid <item>, <item>, ...
1152 This csv-separated list of request attributes will be used to construct
1153 the request cache identifier. Use this only, if you know exactly what you
1154 are doing. If you, for example, use postfwd3 only for RBL/RHSBL control,
1155 you may set this to
1156 postfwd3 --cache=3600 --cacheid=client_name,client_address
1157 This increases efficiency of caching and improves postfwd's performance.
1158 Warning: You should list all items here, which are used in your ruleset!
1159
1160 --cacheid_md5, --nocacheid_md5 (default=1)
1161 The cacheid will be created with a md5sum of the request items.
1162
1163 --cleanup-requests <interval> (default=600)
1164 The request cache will be searched for timed out items after this <interval> in
1165 seconds. It is a minimum value. The cleanup process will only take place, when
1166 a new request arrives.
1167
1168 --cleanup-rbls <interval> (default=600)
1169 The rbl cache will be searched for timed out items after this <interval> in
1170 seconds. It is a minimum value. The cleanup process will only take place, when
1171 a new request arrives.
1172
1173 --cleanup-rates <interval> (default=600)
1174 The rate cache will be searched for timed out items after this <interval> in
1175 seconds. It is a minimum value. The cleanup process will only take place, when
1176 a new request arrives.
1177
1178 -S, --summary <int> (default=600)
1179 Shows some usage statistics (program uptime, request counter, matching rules)
1180 every <int> seconds. This option is included by the -v switch.
1181 This feature uses the alarm signal, so you can force postfwd3 to dump the stats
1182 using `kill -ALRM <pid>` (where <pid> is the process id of postfwd).
1183
1184 Example:
1185 Aug 19 12:39:45 mail1 postfwd[666]: [STATS] Counters: 213000 seconds uptime, 39 rules
1186 Aug 19 12:39:45 mail1 postfwd[666]: [STATS] Requests: 71643 overall, 49 last interval, 62.88% cache hits
1187 Aug 19 12:39:45 mail1 postfwd[666]: [STATS] Averages: 20.18 overall, 4.90 last interval, 557.30 top
1188 Aug 19 12:39:45 mail1 postfwd[666]: [STATS] Contents: 44 cached requests, 239 cached dnsbl results
1189 Aug 19 12:39:45 mail1 postfwd[666]: [STATS] Rule ID: R-001 matched: 2704 times
1190 Aug 19 12:39:45 mail1 postfwd[666]: [STATS] Rule ID: R-002 matched: 9351 times
1191 Aug 19 12:39:45 mail1 postfwd[666]: [STATS] Rule ID: R-003 matched: 3116 times
1192 ...
1193
1194 --no-rulestats
1195 Disables per rule statistics. Keeps your log clean, if you do not use them.
1196 This option has no effect without --summary or --verbose set.
1197
1198 -L, --stdout
1199 Redirects all syslog messages to stdout for debugging. Do not use this in daemon mode!
1200
1201 --stdin
1202 Tells postfwd to get the request data from STDIN instead of a network socket. This
1203 may be used to test rulesets at the command-line:
1204
1205 Example:
1206 postfwd -f /etc/postfwd/postfwd.cf --stdin --stdout --nodaemon ../tools/request.sample
1207
1208 --cmd
1209 Shorthand for the combination --stdin, --stdout and --nodaemon
1210
1211 Example:
1212 postfwd -f /etc/postfwd/postfwd.cf --cmd ../tools/request.sample
1213
1214 -t, --test
1215 In test mode postfwd3 always returns "dunno", but logs according
1216 to it`s ruleset. -v will be set automatically with this option.
1217
1218 -n, --nodns
1219 Disables all DNS based checks like RBL checks. Rules containing
1220 such elements will be ignored.
1221
1222 -n, --nodnslog
1223 Disables logging of dns events.
1224
1225 --dns_timeout (default: 14)
1226 Sets the timeout for asynchonous dns queries in seconds. This value will apply to
1227 all dns items in a rule.
1228
1229 --dns_timeout_max (default: 10)
1230 Sets the maximum timeout counter for dnsbl lookups. If the timeouts exceed this value
1231 the corresponding dnsbl will be deactivated for a while (see --dns_timeout_interval).
1232
1233 --dns_timeout_interval (default=1200)
1234 The dnsbl timeout counter will be cleaned after this interval in seconds. Use this
1235 in conjunction with the --dns_timeout_max parameter.
1236
1237 --dns_async_txt
1238 Perform dnsbl A and TXT lookups simultaneously (otherwise only for listings with at
1239 least one A record). This needs more network bandwidth due to increased queries but
1240 might increase throughput because the lookups can be parallelized.
1241
1242 --dns_max_ns_lookups (default=0)
1243 maximum ns names to lookup up with sender_ns_addrs item. use 0 for no maximum.
1244
1245 --dns_max_mx_lookups (default=0)
1246 maximum mx names to lookup up with sender_mx_addrs item. use 0 for no maximum.
1247
1248 --ipv6_dnsbl (default=0)
1249 enables dnsbl checks for IPv6 addresses
1250
1251 -I, --instantcfg
1252 The config files, specified by -f will be re-read for every request
1253 postfwd3 receives. This enables on-the-fly configuration changes
1254 without restarting. Though files will be read only if necessary
1255 (which means their access times changed since last read) this might
1256 significantly increase system load.
1257
1258 --config_timeout (default=3)
1259 timeout in seconds to parse a single configuration line. if exceeded, the rule will
1260 be skipped. this is used to prevent problems due to large files or loops.
1261
1262 --keep_groups (default=0)
1263 With this option set postfwd3 does not clear the group cache on reload. Please
1264 note that you have to restart (not reload) postfwd with this option if you change
1265 any group based rules.
1266
1267 --save_groups (default=none)
1268 With this option postfwd saves existing groups to disk and reloads them on program
1269 start. This allows persistent rate limits across program restarts or reboots.
1270 Please note that postfwd needs read and write access to the specified file.
1271
1272 --keep_rates (default=0)
1273 With this option set postfwd3 does not clear the rate limit counters on reload. Please
1274 note that you have to restart (not reload) postfwd with this option if you change
1275 any rate limit rules.
1276
1277 --save_rates (default=none)
1278 With this option postfwd saves existing rate limit counters to disk and reloads them
1279 on program start. This allows persistent rate limits across program restarts or reboots.
1280 Please note that postfwd needs read and write access to the specified file.
1281
1282 -A, --aggregate_addrs, --noaggregate_addrs
1283 Pre-computes ip address lists to subnets, so that e.g.:
1284
1285 client_address=10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24, 10.0.3.0/24
1286 will result in
1287 client_address=10.0.0.0/22
1288
1289 This increases the performance of cidr-matching
1290
1291 --no_netaddr
1292 Do not use functions from module NetAddr::IP, even if it was found
1293 on the system. This option implicitly disables --aggregate_addrs.
1294
1295 --no_netcidr
1296 Do not use functions from module Net::CIDR::Lite, even if it was found
1297 on the system.
1298
1299 --cidr_method=s (default=autodetect)
1300 Use method <s> for network checks. Valid arguments are:
1301 netcidr - compare networks using Net::CIDR::Lite Module (v4 and v6 cidr)
1302 netaddr - compare networks using NetAddr::IP Module (v4 and v6 cidr)
1303 postfwd - old but very fast method (v4=cidr, v6=regex)
1304 If not specified postfwd tries to load modules in the above order and falls back
1305 to 'postfwd' if nothing found.
1306
1307 Informational arguments
1308
1309 These arguments are for command line usage only. Never ever use them
1310 with postfix!
1311
1312 -C, --showconfig
1313 Displays the current ruleset. Use -v for verbose output.
1314
1315 -V, --version
1316 Displays the program version.
1317
1318 -h, --help
1319 Shows program usage.
1320
1321 -m, --manual
1322 Displays the program manual.
1323
1324 -D, --defaults
1325 displays complete postfwd3 settings.
1326
1327 -P, --perfmon
1328 This option turns of any syslogging and output. It is included
1329 for performance testing.
1330
1331 --dumpstats
1332 Displays program usage statistics.
1333
1334 --dumpcache
1335 Displays cache contents.
1336
1337 --delcache <item>
1338 Removes an item from the request cache. Use --dumpcache to identify objects.
1339 E.g.:
1340 # postfwd --dumpcache
1341 ...
1342 %rate_cache -> %sender=gmato@jqvo.org -> %RATE002+2_600 -> @count -> '1'
1343 %rate_cache -> %sender=gmato@jqvo.org -> %RATE002+2_600 -> @maxcount -> '2'
1344 ...
1345 # postfwd --delrate="sender=gmato@jqvo.org"
1346 rate cache item 'sender=gmato@jqvo.org' removed
1347
1348 --delrate <item>
1349 Removes an item from the rate cache. Use --dumpcache to identify objects.
1350
1351 REFRESH
1352 In daemon mode postfwd3 reloads it's ruleset after receiving a HUP
1353 signal. Please see the description of the '-I' switch to have your
1354 configuration refreshed for every request postfwd3 receives.
1355
1356 EXAMPLES
1357 ## whitelisting
1358 # 1. networks 192.168.1.0/24, 192.168.2.4
1359 # 2. client_names *.gmx.net and *.gmx.de
1360 # 3. sender *@someshop.tld from 11.22.33.44
1361 id=WL001; action=dunno ; client_address=192.168.1.0/24, 192.168.2.4
1362 id=WL002; action=dunno ; client_name=\.gmx\.(net|de)$
1363 id=WL003; action=dunno ; sender=@someshop\.tld$ ; client_address=11.22.33.44
1364
1365 ## TLS control
1366 # 1. *@authority.tld only with correct TLS fingerprint
1367 # 2. *@secret.tld only with keysizes >=64
1368 id=TL001; action=dunno ; sender=@authority\.tld$ ; ccert_fingerprint=AA:BB:CC..
1369 id=TL002; action=REJECT wrong TLS fingerprint ; sender=@authority\.tld$
1370 id=TL003; action=REJECT tls keylength < 64 ; sender=@secret\.tld$ ; encryption_keysize=64
1371
1372 ## Combined RBL checks
1373 # This will reject mail if
1374 # 1. listed on ix.dnsbl.manitu.net
1375 # 2. listed on zen.spamhaus.org (sbl and xbl, dns cache timeout 1200s instead of 3600s)
1376 # 3. listed on min 2 of bl.spamcop.net, list.dsbl.org, dnsbl.sorbs.net
1377 # 4. listed on bl.spamcop.net and one of rhsbl.ahbl.org, rhsbl.sorbs.net
1378 id=RBL01 ; action=REJECT listed on ix.dnsbl.manitu.net ; rbl=ix.dnsbl.manitu.net
1379 id=RBL02 ; action=REJECT listed on zen.spamhaus.org ; rbl=zen.spamhaus.org/127.0.0.[2-8]/1200
1380 id=RBL03 ; action=REJECT listed on too many RBLs ; rblcount=2 ; rbl=bl.spamcop.net, list.dsbl.org, dnsbl.sorbs.net
1381 id=RBL04 ; action=REJECT combined RBL+RHSBL check ; rbl=bl.spamcop.net ; rhsbl=rhsbl.ahbl.org, rhsbl.sorbs.net
1382
1383 ## Message size (requires message_size_limit to be set to 30000000)
1384 # 1. 30MB for systems in *.customer1.tld
1385 # 2. 20MB for SASL user joejob
1386 # 3. 10MB default
1387 id=SZ001; protocol_state==END-OF-MESSAGE; action=DUNNO; size<=30000000 ; client_name=\.customer1.tld$
1388 id=SZ002; protocol_state==END-OF-MESSAGE; action=DUNNO; size<=20000000 ; sasl_username==joejob
1389 id=SZ002; protocol_state==END-OF-MESSAGE; action=DUNNO; size<=10000000
1390 id=SZ100; protocol_state==END-OF-MESSAGE; action=REJECT message too large
1391
1392 ## Selective Greylisting
1393 ##
1394 ## Note that postfwd does not include greylisting. This setup requires a running postgrey service
1395 ## at port 10031 and the following postfix restriction class in your main.cf:
1396 ##
1397 ## smtpd_restriction_classes = check_postgrey, ...
1398 ## check_postgrey = check_policy_service inet:127.0.0.1:10031
1399 #
1400 # 1. if listed on zen.spamhaus.org with results 127.0.0.10 or .11, dns cache timeout 1200s
1401 # 2. Client has no rDNS
1402 # 3. Client comes from several dialin domains
1403 id=GR001; action=check_postgrey ; rbl=dul.dnsbl.sorbs.net, zen.spamhaus.org/127.0.0.1[01]/1200
1404 id=GR002; action=check_postgrey ; client_name=^unknown$
1405 id=GR003; action=check_postgrey ; client_name=\.(t-ipconnect|alicedsl|ish)\.de$
1406
1407 ## Date Time
1408 date=24.12.2007-26.12.2007 ; action=450 4.7.1 office closed during christmas
1409 time=04:00:00-05:00:00 ; action=450 4.7.1 maintenance ongoing, try again later
1410 time=-07:00:00 ; sasl_username=jim ; action=450 4.7.1 to early for you, jim
1411 time=22:00:00- ; sasl_username=jim ; action=450 4.7.1 to late now, jim
1412 months=-Apr ; action=450 4.7.1 see you in may
1413 days=!!Mon-Fri ; action=check_postgrey
1414
1415 ## Usage of jump
1416 # The following allows a message size of 30MB for different
1417 # users/clients while others will only have 10MB.
1418 id=R001 ; action=jump(R100) ; sasl_username=^(Alice|Bob|Jane)$
1419 id=R002 ; action=jump(R100) ; client_address=192.168.1.0/24
1420 id=R003 ; action=jump(R100) ; ccert_fingerprint=AA:BB:CC:DD:...
1421 id=R004 ; action=jump(R100) ; ccert_fingerprint=AF:BE:CD:DC:...
1422 id=R005 ; action=jump(R100) ; ccert_fingerprint=DD:CC:BB:DD:...
1423 id=R099 ; protocol_state==END-OF-MESSAGE; action=REJECT message too big (max. 10MB); size=10000000
1424 id=R100 ; protocol_state==END-OF-MESSAGE; action=REJECT message too big (max. 30MB); size=30000000
1425
1426 ## Usage of score
1427 # The following rejects a mail, if the client
1428 # - is listed on 1 RBL and 1 RHSBL
1429 # - is listed in 1 RBL or 1 RHSBL and has no correct rDNS
1430 # - other clients without correct rDNS will be greylist-checked
1431 # - some whitelists are used to lower the score
1432 id=S01 ; score=2.6 ; action=check_postgrey
1433 id=S02 ; score=5.0 ; action=REJECT postfwd score too high
1434 id=R00 ; action=score(-1.0) ; rbl=exemptions.ahbl.org,list.dnswl.org,query.bondedsender.org,spf.trusted-forwarder.org
1435 id=R01 ; action=score(2.5) ; rbl=bl.spamcop.net, list.dsbl.org, dnsbl.sorbs.net
1436 id=R02 ; action=score(2.5) ; rhsbl=rhsbl.ahbl.org, rhsbl.sorbs.net
1437 id=N01 ; action=score(-0.2) ; client_name==$$helo_name
1438 id=N02 ; action=score(2.7) ; client_name=^unknown$
1439 ...
1440
1441 ## Usage of rate and size
1442 # The following temporary rejects requests from "unknown" clients, if they
1443 # 1. exceeded 30 requests per hour or
1444 # 2. tried to send more than 1.5mb within 10 minutes
1445 id=RATE01 ; client_name==unknown ; protocol_state==RCPT
1446 action=rate(client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
1447 id=SIZE01 ; client_name==unknown ; protocol_state==END-OF-MESSAGE
1448 action=size(client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)
1449
1450 ## Macros
1451 # definition
1452 &&RBLS { rbl=zen.spamhaus.org,list.dsbl.org,bl.spamcop.net,dnsbl.sorbs.net,ix.dnsbl.manitu.net; };
1453 &&GONOW { action=REJECT your request caused our spam detection policy to reject this message. More info at http://www.domain.local; };
1454 # rules
1455 &&GONOW ; &&RBLS ; client_name=^unknown$
1456 &&GONOW ; &&RBLS ; client_name=(\d+[\.-_]){4}
1457 &&GONOW ; &&RBLS ; client_name=[\.-_](adsl|dynamic|ppp|)[\.-_]
1458
1459 ## Groups
1460 # definition
1461 &&RBLS{
1462 rbl=zen.spamhaus.org
1463 rbl=list.dsbl.org
1464 rbl=bl.spamcop.net
1465 rbl=dnsbl.sorbs.net
1466 rbl=ix.dnsbl.manitu.net
1467 };
1468 &&RHSBLS{
1469 ...
1470 };
1471 &&DYNAMIC{
1472 client_name==unknown
1473 client_name~=(\d+[\.-_]){4}
1474 client_name~=[\.-_](adsl|dynamic|ppp|)[\.-_]
1475 ...
1476 };
1477 &&BAD_HELO{
1478 helo_name==my.name.tld
1479 helo_name~=^([^\.]+)$
1480 helo_name~=\.(local|lan)$
1481 ...
1482 };
1483 &&MAINTENANCE{
1484 date=15.01.2007
1485 date=15.04.2007
1486 date=15.07.2007
1487 date=15.10.2007
1488 time=03:00:00 - 04:00:00
1489 };
1490 # rules
1491 id=COMBINED ; &&RBLS ; &&DYNAMIC ; action=REJECT dynamic client and listed on RBL
1492 id=MAINTENANCE ; &&MAINTENANCE ; action=DEFER maintenance time - please try again later
1493
1494 # now with the set() command, note that long item
1495 # lists don't have to be compared twice
1496 id=RBL01 ; &&RBLS ; action=set(HIT_rbls=1)
1497 id=HELO01 ; &&BAD_HELO ; action=set(HIT_helo=1)
1498 id=DYNA01 ; &&DYNAMIC ; action=set(HIT_dyna=1)
1499 id=REJECT01 ; HIT_rbls==1 ; HIT_helo==1 ; action=REJECT please see http://some.org/info?reject=01 for more info
1500 id=REJECT02 ; HIT_rbls==1 ; HIT_dyna==1 ; action=REJECT please see http://some.org/info?reject=02 for more info
1501 id=REJECT03 ; HIT_helo==1 ; HIT_dyna==1 ; action=REJECT please see http://some.org/info?reject=03 for more info
1502
1503 ## combined with enhanced rbl features
1504 #
1505 id=RBL01 ; rhsblcount=all ; rblcount=all ; &&RBLS ; &&RHSBLS
1506 action=set(HIT_dnsbls=$$rhsblcount,HIT_dnsbls+=$$rblcount,HIT_dnstxt=$$dnsbltext)
1507 id=RBL02 ; HIT_dnsbls>=2 ; action=554 5.7.1 blocked using $$HIT_dnsbls DNSBLs [INFO: $$HIT_dnstxt]
1508
1509 PARSER
1510 Configuration
1511
1512 The postfwd3 ruleset can be specified at the commandline (-r option) or
1513 be read from files (-f). The order of your arguments will be kept. You
1514 should check the parser with the -C | --showconfig switch at the
1515 command line before applying a new config. The following call:
1516
1517 postfwd3 --showconfig \
1518 -r "id=TEST; recipient_count=100; action=WARN mail with 100+ recipients" \
1519 -f /etc/postfwd.cf \
1520 -r "id=DEFAULT; action=dunno";
1521
1522 will produce the following output:
1523
1524 Rule 0: id->"TEST" action->"WARN mail with 100+ recipients"; recipient_count->"100"
1525 ...
1526 ... <content of /etc/postfwd.cf> ...
1527 ...
1528 Rule <n>: id->"DEFAULT" action->"dunno"
1529
1530 Multiple items of the same type will be added to lists (see the "ITEMS"
1531 section for more info):
1532
1533 postfwd3 --showconfig \
1534 -r "client_address=192.168.1.0/24; client_address=172.16.26.32; action=dunno"
1535
1536 will result in:
1537
1538 Rule 0: id->"R-0"; action->"dunno"; client_address->"192.168.1.0/24, 172.16.26.32"
1539
1540 Macros are evaluated at configuration stage, which means that
1541
1542 postfwd3 --showconfig \
1543 -r "&&RBLS { rbl=bl.spamcop.net; client_name=^unknown$; };" \
1544 -r "id=RBL001; &&RBLS; action=REJECT listed on spamcop and bad rdns";
1545
1546 will result in:
1547
1548 Rule 0: id->"RBL001"; action->"REJECT listed on spamcop and bad rdns"; rbl->"bl.spamcop.net"; client_name->"^unknown$"
1549
1550 Request processing
1551
1552 When a policy delegation request arrives it will be compared against
1553 postfwd`s ruleset. To inspect the processing in detail you should
1554 increase verbority using use the "-v" or "-vv" switch. "-L" redirects
1555 log messages to stdout.
1556
1557 Keeping the order of the ruleset in general, items will be compared in
1558 random order, which basically means that
1559
1560 id=R001; action=dunno; client_address=192.168.1.1; sender=bob@alice.local
1561
1562 equals to
1563
1564 id=R001; sender=bob@alice.local; client_address=192.168.1.1; action=dunno
1565
1566 Lists will be evaluated in the specified order. This allows to place
1567 faster expressions at first:
1568
1569 postfwd3 -vv --cmd -r "id=RBL001; rbl=localrbl.local zen.spamhaus.org; action=REJECT" /some/where/request.sample
1570
1571 produces the following
1572
1573 [LOGS info]: compare rbl: "remotehost.remote.net[68.10.1.7]" -> "localrbl.local"
1574 [LOGS info]: count1 rbl: "2" -> "0"
1575 [LOGS info]: query rbl: localrbl.local 7.1.10.68 (7.1.10.68.localrbl.local)
1576 [LOGS info]: count2 rbl: "2" -> "0"
1577 [LOGS info]: match rbl: FALSE
1578 [LOGS info]: compare rbl: "remotehost.remote.net[68.10.1.7]" -> "zen.spamhaus.org"
1579 [LOGS info]: count1 rbl: "2" -> "0"
1580 [LOGS info]: query rbl: zen.spamhaus.org 7.1.10.68 (7.1.10.68.zen.spamhaus.org)
1581 [LOGS info]: count2 rbl: "2" -> "0"
1582 [LOGS info]: match rbl: FALSE
1583 [LOGS info]: Action: dunno
1584
1585 The negation operator !!(<value>) has the highest priority and
1586 therefore will be evaluated first. Then variable substitutions are
1587 performed:
1588
1589 postfwd3 -vv --cmd -r "id=TEST; action=REJECT; client_name=!!($$heloname)" /some/where/request.sample
1590
1591 will give
1592
1593 [LOGS info]: compare client_name: "unknown" -> "!!($$helo_name)"
1594 [LOGS info]: negate client_name: "unknown" -> "$$helo_name"
1595 [LOGS info]: substitute client_name: "unknown" -> "english-breakfast.cloud8.net"
1596 [LOGS info]: match client_name: TRUE
1597 [LOGS info]: Action: REJECT
1598
1599 Ruleset evaluation
1600
1601 A rule hits when all items (or at least one element of a list for each
1602 item) have matched. As soon as one item (or all elements of a list)
1603 fails to compare against the request attribute the parser will jump to
1604 the next rule in the postfwd3 ruleset.
1605
1606 If a rule matches, there are two options:
1607
1608 * Rule returns postfix action (dunno, reject, ...) The parser stops
1609 rule processing and returns the action to postfix. Other rules will not
1610 be evaluated.
1611
1612 * Rule returns postfwd3 action (jump(), note(), ...) The parser
1613 evaluates the given action and continues with the next rule (except for
1614 the jump() or quit() actions - please see the "ACTIONS" section for
1615 more information). Nothing will be sent to postfix.
1616
1617 If no rule has matched and the end of the ruleset is reached postfwd3
1618 will return dunno without logging anything unless in verbose mode. You
1619 may place a last catch-all rule to change that behaviour:
1620
1621 ... <your rules> ...
1622 id=DEFAULT ; action=dunno
1623
1624 will log any request that passes the ruleset without having hit a prior
1625 rule.
1626
1627 SETTINGS
1628 Since version postfwd3 2.00-pre6 the program settings can be retrieved
1629 from a file. The information must be parseable by perl eval() function.
1630 Comments are allowed:
1631
1632 # example settings for postfwd3
1633 {
1634 # enable verbose logging
1635 verbose => 1,
1636
1637 # user and group for postfwd
1638 base => {
1639 group => 'postfw',
1640 user => 'postfw'
1641 },
1642
1643 # server settings
1644 server => {
1645 proto => 'tcp',
1646 host => '127.0.0.1',
1647 port => '10099'
1648 }
1649 }
1650
1651 postfwd3 can also export the program settings in that format using
1652 Data::Dumper.
1653
1654 # show configuration
1655 postfwd3 --showsettings
1656
1657 # save configuration to file
1658 postfwd3 --savesettings=/path/to/file
1659
1660 # read configuration from file
1661 postfwd3 --loadsettings=/path/to/file
1662
1663 Multiple usage of --loadsettings or the short form -F is allowed. The
1664 order will be kept. Commandline arguments override the settings
1665 retrieved from a file.
1666
1667 # load base settings, override with node settings and set port and verbose logging
1668 postfwd3 -v -p 10050 -F /path/to/basefile -F /path/to/nodefile
1669
1670 Samples for settings files are distributed in the etc/-folder of the
1671 postfwd3 tarball.
1672
1673 DEBUGGING
1674 To debug special steps of the parser the '--debug' switch takes a list
1675 of debug classes. Since postfwd3 2.00 the list of available debug
1676 classes can be retrieved by running:
1677
1678 postfwd3 --debugclasses
1679
1680 INTEGRATION
1681 Integration via daemon mode
1682
1683 The common way to use postfwd3 is to start it as daemon, listening at a
1684 specified tcp port. postfwd3 will spawn multiple child processes which
1685 communicate with a parent cache. This is the prefered way to use
1686 postfwd3 in high volume environments. Start postfwd3 with the following
1687 parameters:
1688
1689 postfwd3 -d -f /etc/postfwd.cf -i 127.0.0.1 -p 10045 -u nobody -g nobody -S
1690
1691 For efficient caching you should check if you can use the options
1692 --cacheid, --cache-rdomain-only, --cache-no-sender and --cache-no-size.
1693
1694 Now check your syslogs (default facility "mail") for a line like:
1695
1696 Aug 9 23:00:24 mail postfwd[5158]: postfwd3 n.nn ready for input
1697
1698 and use `netstat -an|grep 10045` to check for something like
1699
1700 tcp 0 0 127.0.0.1:10045 0.0.0.0:* LISTEN
1701
1702 If everything works, open your postfix main.cf and insert the following
1703
1704 127.0.0.1:10045_time_limit = 3600 <--- integration
1705 smtpd_recipient_restrictions = permit_mynetworks <--- recommended
1706 reject_unauth_destination <--- recommended
1707 check_policy_service inet:127.0.0.1:10045 <--- integration
1708
1709 Reload your configuration with `postfix reload` and watch your logs. In
1710 it works you should see lines like the following in your mail log:
1711
1712 Aug 9 23:01:24 mail postfwd[5158]: rule=22, id=ML_POSTFIX, client=english-breakfast.cloud9.net[168.100.1.7], sender=owner-postfix-users@postfix.tld, recipient=someone@domain.local, helo=english-breakfast.cloud9.net, proto=ESMTP, state=RCPT, action=dunno
1713
1714 If you want to check for size or rcpt_count items you must integrate
1715 postfwd3 in smtp_data_restrictions or smtpd_end_of_data_restrictions.
1716 Of course you can also specify a restriction class and use it in your
1717 access tables. First create a file /etc/postfix/policy containing:
1718
1719 domain1.local postfwdcheck
1720 domain2.local postfwdcheck
1721 ...
1722
1723 Then postmap that file (`postmap hash:/etc/postfix/policy`), open your
1724 main.cf and enter
1725
1726 # Restriction Classes
1727 smtpd_restriction_classes = postfwdcheck, <some more>... <--- integration
1728 postfwdcheck = check_policy_service inet:127.0.0.1:10045 <--- integration
1729
1730 127.0.0.1:10045_time_limit = 3600 <--- integration
1731 smtpd_recipient_restrictions = permit_mynetworks, <--- recommended
1732 reject_unauth_destination, <--- recommended
1733 ... <--- optional
1734 check_recipient_access hash:/etc/postfix/policy, <--- integration
1735 ... <--- optional
1736
1737 Reload postfix and watch your logs.
1738
1739 Integration via docker
1740
1741 postfwd can be run in a docker container. The relevant options are
1742 --nodaemon and --stdout. More information can be found in the included
1743 doc/docker.html or at <http://postfwd.org/docker>.
1744
1745 TESTING
1746 First you have to create a ruleset (see Configuration section). Check
1747 it with
1748
1749 postfwd3 -f /etc/postfwd.cf -C
1750
1751 There is an example policy request distributed with postfwd, called
1752 'request.sample'. Simply change it to meet your requirements and use
1753
1754 postfwd3 --cmd -f /etc/postfwd.cf request.sample
1755
1756 You should get an answer like
1757
1758 action=<whateveryouconfigured>
1759
1760 For network tests I use netcat:
1761
1762 nc 127.0.0.1 10045 <request.sample
1763
1764 to send a request to postfwd. If you receive nothing, make sure that
1765 postfwd3 is running and listening on the specified network settings.
1766
1767 PERFORMANCE
1768 Some of these proposals might not match your environment. Please check
1769 your requirements and test new options carefully!
1770
1771 - use caching options
1772 - use the correct match operator ==, <=, >=
1773 - use ^ and/or $ in regular expressions
1774 - use item lists (faster than single rules)
1775 - use set() action on repeated item lists
1776 - use jumps and rate limits
1777 - use a pre-lookup rule for rbl/rhsbls with empty note() action
1778
1779 SEE ALSO
1780 See <http://www.postfix.org/SMTPD_POLICY_README.html> for a description
1781 of how Postfix policy servers work.
1782
1784 Development, testing and hosting of postfwd consumes time and
1785 ressources. It is and will stay free software (see "LICENSE" below). If
1786 you want to support this, consider a donation at
1787 https://www.paypal.me/postfwd.
1788
1790 postfwd3 is free software and released under BSD license, which
1791 basically means that you can do what you want as long as you keep the
1792 copyright notice:
1793
1794 Copyright (c) 2009, Jan Peter Kessler All rights reserved.
1795
1796 Redistribution and use in source and binary forms, with or without
1797 modification, are permitted provided that the following conditions are
1798 met:
1799
1800 * Redistributions of source code must retain the above copyright
1801 notice, this list of conditions and the following disclaimer.
1802 * Redistributions in binary form must reproduce the above copyright
1803 notice, this list of conditions and the following disclaimer in
1804 the documentation and/or other materials provided with the
1805 distribution.
1806 * Neither the name of the authors nor the names of his contributors
1807 may be used to endorse or promote products derived from this
1808 software without specific prior written permission.
1809
1810 THIS SOFTWARE IS PROVIDED BY ME ``AS IS'' AND ANY EXPRESS OR IMPLIED
1811 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1812 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1813 NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1814 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1815 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1816 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1817 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1818 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1819 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1820
1822 Jan Peter Kessler <info (AT) postfwd (DOT) org>. Let me know, if you
1823 have any suggestions.
1824
1825
1826
1827perl v5.30.3 2020-07-30 POSTFWD3(1)