diff --git a/doc/postfwd.CHANGELOG b/doc/postfwd.CHANGELOG index e1391eb..eacb5b0 100644 --- a/doc/postfwd.CHANGELOG +++ b/doc/postfwd.CHANGELOG @@ -1,3 +1,41 @@ +1.35 +==== +- code: rate(), size() and rcpt() function index is now case insensitive by default + (same limit counters for from@example.org and fRom@eXample.org) + if you need to treat the localpart case-sensitive according to rfc5321 + you may use rate5321(), size5321() and rcpt5321() + +1.34 +==== +- bugfix: fixed taint mode logging error for verbose --showconfig and --stdoutlog + options and newer perl versions. +- bugfix: check_* functions use print/getline instead of send/recv for large + --dumpcache output (thanks to Alexandre Simon) +- code: log_* routines added to allow the same plugins for postfwd1 and postfwd2 +- code: added more information when using --debug=cleanup +- docs: documentation updates +- feature: new sendmail(sendmail-path::from::to::subject::body) action. + Please take a look at the manual, especially about + it's limitations, before using it! + ------------------------------------------------------------ + # alert + action=sendmail(/usr/sbin/sendmail::from@example.org::to@example.org::Subject::Text) + ------------------------------------------------------------ + + +1.33 +==== +- feature: new compare operators * + ==================================================================== + *ITEM > VALUE true if ITEM > VALUE + *ITEM < VALUE true if ITEM < VALUE + ==================================================================== +- bugfix: fixed bug when computing scores with more than 1 digit after the "." (n.nn) +- bugfix: fixed bug when computing negative values with the set action +- bugfix: ITEMS plugins returning zero values were handled incorrectly +- bugfix: max command recursion was not reset for each rule + + 1.32 ==== - feature: new option --save_rates= allows to load and save diff --git a/doc/postfwd.html b/doc/postfwd.html index c3023ff..7f7233a 100644 --- a/doc/postfwd.html +++ b/doc/postfwd.html @@ -1,14 +1,18 @@ + postfwd - postfix firewall daemon + -

+ +
+

+ +
+
-

NAME

@@ -111,7 +117,8 @@ --config_timeout <i> parser timeout in seconds --keep_rates do not clear rate limit counters on reload --save_rates <file> save and load rate limits on disk - --fast_limit_evaluation evaluate rate limits before ruleset is parsed + --fast_limit_evaluation evaluate rate limits before ruleset is parsed + (please note the limitations)
         Plugins:
             --plugins <file>        loads postfwd plugins from file
@@ -165,6 +172,8 @@ is not important. So the following would lead to the same result as the previous ITEM == VALUE true if ITEM equals VALUE ITEM => VALUE true if ITEM >= VALUE ITEM =< VALUE true if ITEM <= VALUE + ITEM > VALUE true if ITEM > VALUE + ITEM < VALUE true if ITEM < VALUE ITEM =~ VALUE true if ITEM ~= /^VALUE$/i ITEM != VALUE false if ITEM equals VALUE ITEM !> VALUE false if ITEM >= VALUE @@ -442,7 +451,7 @@ necessary. Of course this might increase the system load, so please use it with
         -- FILE /etc/postfwd/clients_west.cf --
         192.168.3.0/24
-

Remind that there is currently no loop detection (/a/file calls /a/file) and that this feature is only available +

Note that there is currently no loop detection (/a/file calls /a/file) and that this feature is only available with postfwd1 v1.15 and postfwd2 v0.18 and higher.

@@ -456,7 +465,7 @@ request attributes by preceeding $$ characters, like:

id=R-003; client_name = !!$$helo_name; action=WARN helo '$$(helo_name)' does not match DNS '$$(client_name)'

postfix actions

Actions will be replied to postfix as result to policy delegation requests. Any action that postfix understands is allowed - see -``man 5 access'' or http://www.postfix.org/access.5.html for a description. If no action is specified, the postfix WARN action +"man 5 access" or http://www.postfix.org/access.5.html for a description. If no action is specified, the postfix WARN action which simply logs the event will be used for the corresponding rule.

postfwd will return dunno if it has reached the end of the ruleset and no rule has matched. This can be changed by placing a last rule containing only an action statement:

@@ -494,7 +503,7 @@ rule containing only an action statement:

this command creates a counter for the given <item>, which will be increased any time a request containing it arrives. if it exceeds <max> within <time> seconds it will return <action> to postfix. rate counters are very fast as they are executed before the ruleset is parsed. - please note that <action> is currently limited to postfix actions (no postfwd actions)! + please note that <action> was limited to postfix actions (no postfwd actions) for postfwd versions <1.33! # no more than 3 requests per 5 minutes # from the same "unknown" client id=RATE01 ; client_name==unknown @@ -525,6 +534,11 @@ rule containing only an action statement:

# recipient count limit 3 per hour per client id=RCPT01 ; protocol_state==END-OF-MESSAGE ; client_address!=10.1.1.1 action=rcpt(client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour) +
+        rate5321,size5321,rcpt5321 (<item>/<max>/<time>/<action>)
+        same as the corresponding non-5321 functions, with the difference that the localpart of
+        sender oder recipient addresses are evaluated case-sensitive according to rfc5321. That
+        means that requests from bob@example.local and BoB@example.local will be treated differently
         ask (<addr>:<port>[:<ignore>])
         allows to delegate the policy decision to another policy service (e.g. postgrey). the first
@@ -537,9 +551,15 @@ rule containing only an action statement:

id=GREY; client_address==10.1.1.1; action=ask(127.0.0.1:10031:^dunno$)
         mail(server/helo/from/to/subject/body)
+        This command is deprecated. You should try to use the sendmail() action instead.
         Very basic mail command, that sends a message with the given arguments. LIMITATIONS:
         This basically performs a telnet. No authentication or TLS are available. Additionally it does
         not track notification state and will notify you any time, the corresponding rule hits.
+
+        sendmail(sendmail-path::from::to::subject::body)
+        Mail command, that uses an existing sendmail binary and sends a message with the given arguments.
+        LIMITATIONS: The command does not track notification state and will notify you any time, the
+        corresponding rule hits (which could mean 100 mails for a mail with 100 recipients at RCPT stage).
         wait (<delay>)
         pauses the program execution for <delay> seconds. use this for
@@ -680,6 +700,10 @@ will be used.

$myresult = ($myitem <= $val); } elsif ($cmp eq '=>') { $myresult = ($myitem >= $val); + } elsif ($cmp eq '<') { + $myresult = ($myitem < $val); + } elsif ($cmp eq '>') { + $myresult = ($myitem > $val); } elsif ($cmp eq '!=') { $myresult = not($myitem == $val); } elsif ($cmp eq '!<') { @@ -709,15 +733,15 @@ continue or to stop parsing the ruleset.

# note(<logstring>) command "note" => sub { my($index,$now,$mycmd,$myarg,$myline,%request) = @_; - my($myaction) = $default_action; my($stop) = 0; - mylogs 'info', "[RULES] ".$myline." - note: ".$myarg if $myarg; + my($myaction) = 'dunno'; my($stop) = 0; + log_info "[RULES] ".$myline." - note: ".$myarg if $myarg; return ($stop,$index,$myaction,$myline,%request); }, # skips next <myarg> rules "skip" => sub { my($index,$now,$mycmd,$myarg,$myline,%request) = @_; - my($myaction) = $default_action; my($stop) = 0; + my($myaction) = 'dunno'; my($stop) = 0; $index += $myarg if ( $myarg and not(($index + $myarg) > $#Rules) ); return ($stop,$index,$myaction,$myline,%request); }, @@ -725,8 +749,8 @@ continue or to stop parsing the ruleset.

# dumps current request contents to syslog "dumprequest" => sub { my($index,$now,$mycmd,$myarg,$myline,%request) = @_; - my($myaction) = $default_action; my($stop) = 0; - map { mylogs 'info', "[DUMP] rule=$index, Attribute: $_=$request{$_}" } (keys %request); + my($myaction) = 'dunno'; my($stop) = 0; + map { log_info "[DUMP] rule=$index, Attribute: $_=$request{$_}" } (keys %request); return ($stop,$index,$myaction,$myline,%request); },
@@ -979,7 +1003,10 @@ The following arguments will control it's behaviour in this case.

Once a ratelimit was set by the ruleset, future requests will be evaluated against it before consulting the ruleset. This mode was the default behaviour until v1.30. With this mode rate limits will be faster, but also eventually set up - whitelisting-rules within the ruleset might not work as expected.
+ whitelisting-rules within the ruleset might not work as expected. + LIMITATIONS: This option does not allow nested postfwd commands like + action=rate(sender/3/60/wait(3)) + This option doe not work with the strict-rfc5321 rate() functions.

Informational arguments

These arguments are for command line usage only. Never ever use them with postfix spawn!

@@ -1193,7 +1220,7 @@ check the parser with the -C | --showconfig switch at the command line before ap
         Rule   0: id->"RBL001"; action->"REJECT listed on spamcop and bad rdns"; rbl->"bl.spamcop.net"; client_name->"^unknown$"

Request processing

When a policy delegation request arrives it will be compared against postfwd`s ruleset. To inspect the processing in detail you should increase -verbority using use the ``-v'' or ``-vv'' switch. ``-L'' redirects log messages to stdout.

+verbority using use the "-v" or "-vv" switch. "-L" redirects log messages to stdout.

Keeping the order of the ruleset in general, items will be compared in random order, which basically means that

         id=R001; action=dunno; client_address=192.168.1.1; sender=bob@alice.local
@@ -1232,7 +1259,7 @@ to compare against the request attribute the parser will jump to the next rule i

If a rule matches, there are two options:

* Rule returns postfix action (dunno, reject, ...) The parser stops rule processing and returns the action to postfix. Other rules will not be evaluated.

-

* Rule returns postfwd action (jump(), note(), ...) +

* Rule returns postfwd action (jump(), note(), ...) The parser evaluates the given action and continues with the next rule (except for the jump() or quit() actions - please see the ACTIONS section for more information). Nothing will be sent to postfix.

If no rule has matched and the end of the ruleset is reached postfwd will return dunno without logging anything unless in verbose mode. You may @@ -1252,7 +1279,7 @@ it`s internal caching in that case. Start postfwd with the following parameters: postfwd -d -f /etc/postfwd.cf -i 127.0.0.1 -p 10040 -u nobody -g nobody -S

For efficient caching you should check if you can use the options --cache-rdomain-only, --cache-no-sender and --cache-no-size.

-

Now check your syslogs (default facility ``mail'') for a line like:

+

Now check your syslogs (default facility "mail") for a line like:

         Aug  9 23:00:24 mail postfwd[5158]: postfwd n.nn ready for input

and use `netstat -an|grep 10040` to check for something like

@@ -1307,7 +1334,7 @@ I won`t discuss that here. If you plan to do so, just add the following line to disable = no }

and restart the xinetd daemon (usually a SIGHUP should be fine). If you experience problems -you might want to check your system's log for xinetd errors like ``socket already in use''.

+you might want to check your system's log for xinetd errors like "socket already in use".

The integration with postfix is similar to the Integration via daemon mode section above. Reload postfix and watch your logs to see if everything works.

diff --git a/doc/postfwd.txt b/doc/postfwd.txt index 299e75e..29b039f 100644 --- a/doc/postfwd.txt +++ b/doc/postfwd.txt @@ -66,6 +66,7 @@ SYNOPSIS --keep_rates do not clear rate limit counters on reload --save_rates save and load rate limits on disk --fast_limit_evaluation evaluate rate limits before ruleset is parsed + (please note the limitations) Plugins: --plugins loads postfwd plugins from file @@ -133,6 +134,8 @@ DESCRIPTION ITEM == VALUE true if ITEM equals VALUE ITEM => VALUE true if ITEM >= VALUE ITEM =< VALUE true if ITEM <= VALUE + ITEM > VALUE true if ITEM > VALUE + ITEM < VALUE true if ITEM < VALUE ITEM =~ VALUE true if ITEM ~= /^VALUE$/i ITEM != VALUE false if ITEM equals VALUE ITEM !> VALUE false if ITEM >= VALUE @@ -457,7 +460,7 @@ DESCRIPTION -- FILE /etc/postfwd/clients_west.cf -- 192.168.3.0/24 - Remind that there is currently no loop detection (/a/file calls /a/file) + Note that there is currently no loop detection (/a/file calls /a/file) and that this feature is only available with postfwd1 v1.15 and postfwd2 v0.18 and higher. @@ -520,7 +523,7 @@ DESCRIPTION this command creates a counter for the given , which will be increased any time a request containing it arrives. if it exceeds within

+ +
+

+ +
+
-

NAME

@@ -125,7 +131,8 @@ --config_timeout <i> parser timeout in seconds --keep_rates do not clear rate limit counters on reload --save_rates <file> save and load rate limits on disk - --fast_limit_evaluation evaluate rate limits before ruleset is parsed + --fast_limit_evaluation evaluate rate limits before ruleset is parsed + (please note the limitations)
         Plugins:
             --plugins <file>            loads postfwd plugins from file
@@ -194,6 +201,8 @@ is not important. So the following would lead to the same result as the previous ITEM == VALUE true if ITEM equals VALUE ITEM => VALUE true if ITEM >= VALUE ITEM =< VALUE true if ITEM <= VALUE + ITEM > VALUE true if ITEM > VALUE + ITEM < VALUE true if ITEM < VALUE ITEM =~ VALUE true if ITEM ~= /^VALUE$/i ITEM != VALUE false if ITEM equals VALUE ITEM !> VALUE false if ITEM >= VALUE @@ -471,7 +480,7 @@ necessary. Of course this might increase the system load, so please use it with
         -- FILE /etc/postfwd/clients_west.cf --
         192.168.3.0/24
-

Remind that there is currently no loop detection (/a/file calls /a/file) and that this feature is only available +

Note that there is currently no loop detection (/a/file calls /a/file) and that this feature is only available with postfwd1 v1.15 and postfwd2 v0.18 and higher.

@@ -485,7 +494,7 @@ request attributes by preceeding $$ characters, like:

id=R-003; client_name = !!$$helo_name; action=WARN helo '$$(helo_name)' does not match DNS '$$(client_name)'

postfix actions

Actions will be replied to postfix as result to policy delegation requests. Any action that postfix understands is allowed - see -``man 5 access'' or http://www.postfix.org/access.5.html for a description. If no action is specified, the postfix WARN action +"man 5 access" or http://www.postfix.org/access.5.html for a description. If no action is specified, the postfix WARN action which simply logs the event will be used for the corresponding rule.

postfwd2 will return dunno if it has reached the end of the ruleset and no rule has matched. This can be changed by placing a last rule containing only an action statement:

@@ -523,7 +532,7 @@ rule containing only an action statement:

this command creates a counter for the given <item>, which will be increased any time a request containing it arrives. if it exceeds <max> within <time> seconds it will return <action> to postfix. rate counters are very fast as they are executed before the ruleset is parsed. - please note that <action> is currently limited to postfix actions (no postfwd actions)! + please note that <action> was limited to postfix actions (no postfwd actions) for postfwd versions <1.33! # no more than 3 requests per 5 minutes # from the same "unknown" client id=RATE01 ; client_name==unknown @@ -545,6 +554,11 @@ rule containing only an action statement:

# recipient count limit 3 per hour per client id=RCPT01 ; protocol_state==END-OF-MESSAGE ; client_address==!!(10.1.1.1) action=rcpt(client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour) +
+        rate5321,size5321,rcpt5321 (<item>/<max>/<time>/<action>)
+        same as the corresponding non-5321 functions, with the difference that the localpart of
+        sender oder recipient addresses are evaluated case-sensitive according to rfc5321. That
+        means that requests from bob@example.local and BoB@example.local will be treated differently
         ask (<addr>:<port>[:<ignore>])
         allows to delegate the policy decision to another policy service (e.g. postgrey). the first
@@ -557,9 +571,15 @@ rule containing only an action statement:

id=GREY; client_address==10.1.1.1; action=ask(127.0.0.1:10031:^dunno$)
         mail(server/helo/from/to/subject/body)
+        This command is deprecated. You should try to use the sendmail() action instead.
         Very basic mail command, that sends a message with the given arguments. LIMITATIONS:
         This basically performs a telnet. No authentication or TLS are available. Additionally it does
         not track notification state and will notify you any time, the corresponding rule hits.
+
+        sendmail(sendmail-path::from::to::subject::body)
+        Mail command, that uses an existing sendmail binary and sends a message with the given arguments.
+        LIMITATIONS: The command does not track notification state and will notify you any time, the
+        corresponding rule hits (which could mean 100 mails for a mail with 100 recipients at RCPT stage).
         wait (<delay>)
         pauses the program execution for <delay> seconds. use this for
@@ -700,6 +720,10 @@ will be used.

$myresult = ($myitem <= $val); } elsif ($cmp eq '=>') { $myresult = ($myitem >= $val); + } elsif ($cmp eq '<') { + $myresult = ($myitem < $val); + } elsif ($cmp eq '>') { + $myresult = ($myitem > $val); } elsif ($cmp eq '!=') { $myresult = not($myitem == $val); } elsif ($cmp eq '!<') { @@ -729,15 +753,15 @@ continue or to stop parsing the ruleset.

# note(<logstring>) command "note" => sub { my($index,$now,$mycmd,$myarg,$myline,%request) = @_; - my($myaction) = $default_action; my($stop) = 0; - mylogs 'info', "[RULES] ".$myline." - note: ".$myarg if $myarg; + my($myaction) = 'dunno'; my($stop) = 0; + log_info "[RULES] ".$myline." - note: ".$myarg if $myarg; return ($stop,$index,$myaction,$myline,%request); }, # skips next <myarg> rules "skip" => sub { my($index,$now,$mycmd,$myarg,$myline,%request) = @_; - my($myaction) = $default_action; my($stop) = 0; + my($myaction) = 'dunno'; my($stop) = 0; $index += $myarg if ( $myarg and not(($index + $myarg) > $#Rules) ); return ($stop,$index,$myaction,$myline,%request); }, @@ -745,8 +769,8 @@ continue or to stop parsing the ruleset.

# dumps current request contents to syslog "dumprequest" => sub { my($index,$now,$mycmd,$myarg,$myline,%request) = @_; - my($myaction) = $default_action; my($stop) = 0; - map { mylogs 'info', "[DUMP] rule=$index, Attribute: $_=$request{$_}" } (keys %request); + my($myaction) = 'dunno'; my($stop) = 0; + map { log_info "[DUMP] rule=$index, Attribute: $_=$request{$_}" } (keys %request); return ($stop,$index,$myaction,$myline,%request); },
@@ -978,7 +1002,10 @@ The following arguments will control it's behaviour in this case.

Once a ratelimit was set by the ruleset, future requests will be evaluated against it before consulting the ruleset. This mode was the default behaviour until v1.30. With this mode rate limits will be faster, but also eventually set up - whitelisting-rules within the ruleset might not work as expected.
+ whitelisting-rules within the ruleset might not work as expected. + LIMITATIONS: This option does not allow nested postfwd commands like + action=rate(sender/3/60/wait(3)) + This option doe not work with the strict-rfc5321 rate() functions.

Informational arguments

These arguments are for command line usage only. Never ever use them with postfix!

@@ -1215,7 +1242,7 @@ check the parser with the -C | --showconfig switch at the command line before ap
         Rule   0: id->"RBL001"; action->"REJECT listed on spamcop and bad rdns"; rbl->"bl.spamcop.net"; client_name->"^unknown$"

Request processing

When a policy delegation request arrives it will be compared against postfwd`s ruleset. To inspect the processing in detail you should increase -verbority using use the ``-v'' or ``-vv'' switch. ``-L'' redirects log messages to stdout.

+verbority using use the "-v" or "-vv" switch. "-L" redirects log messages to stdout.

Keeping the order of the ruleset in general, items will be compared in random order, which basically means that

         id=R001; action=dunno; client_address=192.168.1.1; sender=bob@alice.local
@@ -1254,7 +1281,7 @@ to compare against the request attribute the parser will jump to the next rule i

If a rule matches, there are two options:

* Rule returns postfix action (dunno, reject, ...) The parser stops rule processing and returns the action to postfix. Other rules will not be evaluated.

-

* Rule returns postfwd2 action (jump(), note(), ...) +

* Rule returns postfwd2 action (jump(), note(), ...) The parser evaluates the given action and continues with the next rule (except for the jump() or quit() actions - please see the ACTIONS section for more information). Nothing will be sent to postfix.

If no rule has matched and the end of the ruleset is reached postfwd2 will return dunno without logging anything unless in verbose mode. You may @@ -1283,7 +1310,7 @@ the prefered way to use postfwd2 in high volume environments. Start postfwd2 wit postfwd2 -d -f /etc/postfwd.cf -i 127.0.0.1 -p 10045 -u nobody -g nobody -S

For efficient caching you should check if you can use the options --cacheid, --cache-rdomain-only, --cache-no-sender and --cache-no-size.

-

Now check your syslogs (default facility ``mail'') for a line like:

+

Now check your syslogs (default facility "mail") for a line like:

         Aug  9 23:00:24 mail postfwd[5158]: postfwd2 n.nn ready for input

and use `netstat -an|grep 10045` to check for something like

diff --git a/doc/postfwd2.txt b/doc/postfwd2.txt index be5c72c..17e0e71 100644 --- a/doc/postfwd2.txt +++ b/doc/postfwd2.txt @@ -79,6 +79,8 @@ SYNOPSIS --keep_rates do not clear rate limit counters on reload --save_rates save and load rate limits on disk --fast_limit_evaluation evaluate rate limits before ruleset is parsed + (please note the limitations) + Plugins: --plugins loads postfwd plugins from file @@ -161,6 +163,8 @@ DESCRIPTION ITEM == VALUE true if ITEM equals VALUE ITEM => VALUE true if ITEM >= VALUE ITEM =< VALUE true if ITEM <= VALUE + ITEM > VALUE true if ITEM > VALUE + ITEM < VALUE true if ITEM < VALUE ITEM =~ VALUE true if ITEM ~= /^VALUE$/i ITEM != VALUE false if ITEM equals VALUE ITEM !> VALUE false if ITEM >= VALUE @@ -485,7 +489,7 @@ DESCRIPTION -- FILE /etc/postfwd/clients_west.cf -- 192.168.3.0/24 - Remind that there is currently no loop detection (/a/file calls /a/file) + Note that there is currently no loop detection (/a/file calls /a/file) and that this feature is only available with postfwd1 v1.15 and postfwd2 v0.18 and higher. @@ -548,7 +552,7 @@ DESCRIPTION this command creates a counter for the given , which will be increased any time a request containing it arrives. if it exceeds within