Merge tag 'upstream/1.20'
Upstream version 1.20
This commit is contained in:
commit
19ceeb5e37
|
@ -7,6 +7,7 @@
|
||||||
PATH=/bin:/usr/bin:/usr/local/bin
|
PATH=/bin:/usr/bin:/usr/local/bin
|
||||||
|
|
||||||
# path to program
|
# path to program
|
||||||
|
#PFWCMD=/usr/local/postfwd/sbin/postfwd2
|
||||||
PFWCMD=/usr/local/postfwd/sbin/postfwd
|
PFWCMD=/usr/local/postfwd/sbin/postfwd
|
||||||
# rulesetconfig file
|
# rulesetconfig file
|
||||||
PFWCFG=/etc/postfix/postfwd.cf
|
PFWCFG=/etc/postfix/postfwd.cf
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
1.20
|
||||||
|
=====
|
||||||
|
- code: changed the default umask for the server socket to 0111
|
||||||
|
to support out-of-the-box postfix setup. Use the
|
||||||
|
--umask setting to change this
|
||||||
|
- bugfix: rbl check could fail on multiple dnsbl answers
|
||||||
|
- bugfix: rbl checks disabled for ipv6 addresses, cidr compare
|
||||||
|
will switch to default (regex/string)
|
||||||
|
|
||||||
|
1.19
|
||||||
|
=====
|
||||||
|
- code: Rate limit code rewritten
|
||||||
|
- code: new --umask setting allows to set filepermissions for pidfiles
|
||||||
|
and unix domain sockets. Default is 0117 (owner and group rw).
|
||||||
|
|
||||||
1.18
|
1.18
|
||||||
=====
|
=====
|
||||||
- bugfix: Fixed bug when comparing sender and recipient addresses, like
|
- bugfix: Fixed bug when comparing sender and recipient addresses, like
|
||||||
|
|
173
doc/CHANGELOG2
Normal file
173
doc/CHANGELOG2
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
postfwd2 1.00
|
||||||
|
=============
|
||||||
|
- code: changed the default umask for the server socket to 0111
|
||||||
|
to support out-of-the-box postfix setup. Use the
|
||||||
|
--server_umask setting to change this
|
||||||
|
- code: --dumpcache command does not require debug mode anymore
|
||||||
|
- code: rate hits included to cache stats
|
||||||
|
- bugfix: rbl checks disabled for ipv6 addresses, cidr compare
|
||||||
|
will switch to default (regex/string)
|
||||||
|
|
||||||
|
postfwd2 0.22
|
||||||
|
=============
|
||||||
|
- feature: Rate limits are completely supported by postfwd2 now.
|
||||||
|
Please note that the cache daemon is required for reliable operation.
|
||||||
|
- bugfix: --syslog_facility could not be changed
|
||||||
|
- code: rate limit code rewritten
|
||||||
|
- code: new --umask, --cache_umask and --server_umask settings allow to set
|
||||||
|
filepermissions for pidfiles and unix domain sockets. New defaults are:
|
||||||
|
* master (pidfile): 0177 (owner rw)
|
||||||
|
* cache (socket): 0177 (owner rw)
|
||||||
|
* server (socket): 0117 (owner and group rw)
|
||||||
|
|
||||||
|
postfwd2 0.21
|
||||||
|
=============
|
||||||
|
- bugfix: Fixed bug when comparing sender and recipient addresses, like
|
||||||
|
"sender=$$recipient". This affects only postfwd2 version 0.20.
|
||||||
|
|
||||||
|
postfwd2 0.20
|
||||||
|
=============
|
||||||
|
- bugfix: Invalid characters in variable substitutions were not correctly catched when
|
||||||
|
the '=' operator was used, like "client_name=$$helo_name". If you can not
|
||||||
|
upgrade for some reason change your rule to "client_name=~$$helo_name"
|
||||||
|
- code: Net::DNS errors will now be handled gracefully
|
||||||
|
- code: default for options --dns_max_ns_a_lookups and --dns_max_mx_a_lookups of 100
|
||||||
|
|
||||||
|
postfwd2 0.19
|
||||||
|
=============
|
||||||
|
- bugfix: this is a bugfix release for 0.18. anyone affected is encouraged to upgrade.
|
||||||
|
detail: the default behavior for the '=' operator with numeric items
|
||||||
|
(size, recipient_count, ...) changed with version 0.18 to '==' (equals to).
|
||||||
|
now these items are compared '>=' (greater than) again.
|
||||||
|
note: if you are using 0.18 and you are not able upgrade for some reason,
|
||||||
|
please change '=' to '>=' in your ruleset where you mean 'greater than'.
|
||||||
|
|
||||||
|
postfwd2 0.18
|
||||||
|
=============
|
||||||
|
- feature: items may now be retrieved from files using "item=file:/some/where"
|
||||||
|
more information in the postfwd manual (FILES section)
|
||||||
|
- feature: helo_address, and sender_(ns|mx)_addrs can now be csv items
|
||||||
|
- feature: new rcpt() command counts recipients for rate limits (thanks to Sahil Tandon)
|
||||||
|
- code: redirect syslog to stdout for --kill, --reload, --showconfig and --dump(cache|stats)
|
||||||
|
- code: option --reload (HUP signal) now reloads config, if the file is unchanged
|
||||||
|
- code: new --debug classes 'config' and 'request'
|
||||||
|
- code: configuration parser improvements:
|
||||||
|
* rules without defined action will be skipped at configuration stage
|
||||||
|
* undefined ACLs will now be detected and skipped at configuration stage
|
||||||
|
* parser timeout skips loading a rule after 4s, to prevent problems with
|
||||||
|
large files or loops. use --config_timeout to override
|
||||||
|
- bugfix: documentation fixed (missing "action=" in ask() examples)
|
||||||
|
- bugfix: fixed logging of an uninitialized value in cache cleanups
|
||||||
|
|
||||||
|
postfwd2 0.17
|
||||||
|
=============
|
||||||
|
- feature: new compare operators *
|
||||||
|
====================================================================
|
||||||
|
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$/i
|
||||||
|
*ITEM != VALUE false if ITEM equals VALUE
|
||||||
|
*ITEM !> VALUE false if ITEM >= VALUE
|
||||||
|
*ITEM !< VALUE false if ITEM <= VALUE
|
||||||
|
*ITEM !~ VALUE false if ITEM ~= /^VALUE$/i
|
||||||
|
ITEM = VALUE default behaviour (see ITEMS section)
|
||||||
|
====================================================================
|
||||||
|
- feature: added --nodaemon and --stdout options
|
||||||
|
- code: non dns items first: if a rule contains dns and non dns items, the
|
||||||
|
lookups will only be done if all non dns items matched
|
||||||
|
- bugfix: empty pcre with empty sender_(ns|mx)_names was parsed incorrectly.
|
||||||
|
this bug affects postfwd2 versions 0.15 - 0.16
|
||||||
|
- bugfix: negated pcre items with '~=' operator were parsed incorrectly.
|
||||||
|
this bug affects postfwd2 version 0.16
|
||||||
|
|
||||||
|
postfwd2 0.16
|
||||||
|
=============
|
||||||
|
- feature: enabled dns cache for sender(ns|mx) and helo address
|
||||||
|
- feature: new options --dns_max_ns_lookups and --dns_max_mx_lookups
|
||||||
|
- code: parent_dns_cache is now disabled by default. use
|
||||||
|
--parent_dns_cache if you have a slow nameserver
|
||||||
|
- bugfix: workaround: Net::Server died if a unix domain socket
|
||||||
|
filename without a dot ('.') was used (B. Frauendienst)
|
||||||
|
|
||||||
|
postfwd2 0.15
|
||||||
|
=============
|
||||||
|
- feature: new items sender_ns_names and sender_ns_addrs
|
||||||
|
- feature: new items sender_mx_names and sender_mx_addrs
|
||||||
|
- feature: new item helo_address, please see docs for more
|
||||||
|
- feature: new parent cache statistics. the command line option --dumpstats
|
||||||
|
uses the --daemons setting now (default: cache,server)
|
||||||
|
- feature: dnsbl txt lookups only for dnsbls with at least one a record.
|
||||||
|
use --dns_async_txt for the old behaviour (see docs for more).
|
||||||
|
- code: summary function went to postfwd::master (and will stay there ;)
|
||||||
|
- code: small performance improvement (5-10%) for pcre (~= or =~) items
|
||||||
|
- bugfix: network 0.0.0.0/0 did not work as expected on all platforms
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.14
|
||||||
|
=============
|
||||||
|
- code: summary function was moved from postfwd::cache to postfwd::policy.
|
||||||
|
the reduced policy <-> cache communication increases throughput
|
||||||
|
considerably and improves cpu balancing on multiprocessor systems
|
||||||
|
- bugfix: fixed potential division by zero in summary function
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.13
|
||||||
|
=============
|
||||||
|
- feature: new options --noidlestats and --norulestats
|
||||||
|
- feature: more informative --version
|
||||||
|
- feature: documentation updates
|
||||||
|
- bugfix: disabled parent_cache counters when --summary=0
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.12
|
||||||
|
=============
|
||||||
|
- feature: the ask() action allows to delegate the policy decision to another
|
||||||
|
policy service (like postgrey). a new parameter allows to specify
|
||||||
|
answer patterns which should be ignored by postfwd. please look
|
||||||
|
at the 'ACTIONS' section in the manual (postfwd2 -m) for details.
|
||||||
|
- feature: parent-request cache will now only be updated, if a rule matches.
|
||||||
|
if postfwd should cache all requests, you must place a last rule:
|
||||||
|
id=DEFAULT; action=dunno
|
||||||
|
- bugfix: reorganised some parent-cache loggings for -vv and *cache debug classes
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.11
|
||||||
|
=============
|
||||||
|
- bugfix: all postfwd settings are now detainted
|
||||||
|
- bugfix: cache-update used an uninitialized value when no rule had hit
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.10
|
||||||
|
=============
|
||||||
|
- bugfix: command line arguments --pidfile
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.09
|
||||||
|
=============
|
||||||
|
- bugfix: command line arguments --user and --group were not correctly de-tainted
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.08
|
||||||
|
=============
|
||||||
|
- bugfix: command line argument --pid_file was ignored
|
||||||
|
- bugfix: command line argument --manual (-m) did not work
|
||||||
|
|
||||||
|
|
||||||
|
postfwd2 0.07
|
||||||
|
=============
|
||||||
|
- first semi-public release of postfwd2
|
||||||
|
- full ruleset compatibility, no changes required when migrating from postfwd v1
|
||||||
|
- new architecture:
|
||||||
|
|
||||||
|
* Net::Server::PreFork
|
||||||
|
ruleset processor (server) forks new child for any request
|
||||||
|
|
||||||
|
* Net::Server::Multiplex for parent cache
|
||||||
|
offers a shared request, dns and rate cache for postfwd2 children
|
||||||
|
|
||||||
|
* Net::Server::Daemonize for master process
|
||||||
|
controls server and cache (watchdog function) and allows direct
|
||||||
|
access to statistics, cache-contents, ... from the command-line
|
||||||
|
|
||||||
|
- many new commandline options (see postfwd2 -h) for more information
|
|
@ -64,6 +64,7 @@
|
||||||
--proto <proto> socket type (tcp or unix)
|
--proto <proto> socket type (tcp or unix)
|
||||||
-u, --user <name> set uid to user <name>
|
-u, --user <name> set uid to user <name>
|
||||||
-g, --group <name> set gid to group <name>
|
-g, --group <name> set gid to group <name>
|
||||||
|
--umask <mask> set umask for file permissions
|
||||||
-R, --chroot <path> chroot the daemon to <path>
|
-R, --chroot <path> chroot the daemon to <path>
|
||||||
--pidfile <path> create pidfile under <path>
|
--pidfile <path> create pidfile under <path>
|
||||||
-l, --logname <label> label for syslog messages
|
-l, --logname <label> label for syslog messages
|
||||||
|
@ -443,10 +444,11 @@ rule containing only an action statement:</p>
|
||||||
this command creates a counter for the given <item>, which will be increased any time a request
|
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.
|
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.
|
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)!
|
||||||
# no more than 3 requests per 5 minutes
|
# no more than 3 requests per 5 minutes
|
||||||
# from the same "unknown" client
|
# from the same "unknown" client
|
||||||
id=RATE01 ; client_name==unknown ; \
|
id=RATE01 ; client_name==unknown ; \
|
||||||
action==rate($$client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)</pre>
|
action==rate(client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)</pre>
|
||||||
<pre>
|
<pre>
|
||||||
size (<item>/<max>/<time>/<action>)
|
size (<item>/<max>/<time>/<action>)
|
||||||
this command works similar to the rate() command with the difference, that the rate counter is
|
this command works similar to the rate() command with the difference, that the rate counter is
|
||||||
|
@ -454,7 +456,7 @@ rule containing only an action statement:</p>
|
||||||
smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
||||||
# size limit 1.5mb per hour per client
|
# size limit 1.5mb per hour per client
|
||||||
id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
||||||
action==size($$client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)</pre>
|
action==size(client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)</pre>
|
||||||
<pre>
|
<pre>
|
||||||
rcpt (<item>/<max>/<time>/<action>)
|
rcpt (<item>/<max>/<time>/<action>)
|
||||||
this command works similar to the rate() command with the difference, that the rate counter is
|
this command works similar to the rate() command with the difference, that the rate counter is
|
||||||
|
@ -463,7 +465,7 @@ rule containing only an action statement:</p>
|
||||||
check it within the ruleset:
|
check it within the ruleset:
|
||||||
# recipient count limit 3 per hour per client
|
# recipient count limit 3 per hour per client
|
||||||
id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
||||||
action==rcpt($$client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)</pre>
|
action==rcpt(client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)</pre>
|
||||||
<pre>
|
<pre>
|
||||||
ask (<addr>:<port>[:<ignore>])
|
ask (<addr>:<port>[:<ignore>])
|
||||||
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
||||||
|
@ -609,6 +611,11 @@ The following arguments will control it's behaviour in this case.</p>
|
||||||
<pre>
|
<pre>
|
||||||
-g, --group <name>
|
-g, --group <name>
|
||||||
Changes real and effective group to <name>.</pre>
|
Changes real and effective group to <name>.</pre>
|
||||||
|
<pre>
|
||||||
|
--umask <mask>
|
||||||
|
Changes the umask for filepermissions (unix domain sockets, pidfiles).
|
||||||
|
Attention: This is umask, not chmod - you have to specify the bits that
|
||||||
|
should NOT apply. E.g.: umask 077 equals to chmod 700.</pre>
|
||||||
<pre>
|
<pre>
|
||||||
-R, --chroot <path>
|
-R, --chroot <path>
|
||||||
Chroot the process to the specified path.
|
Chroot the process to the specified path.
|
||||||
|
@ -805,9 +812,10 @@ the '-I' switch to have your configuration refreshed for every request postfwd r
|
||||||
# 1. 30MB for systems in *.customer1.tld
|
# 1. 30MB for systems in *.customer1.tld
|
||||||
# 2. 20MB for SASL user joejob
|
# 2. 20MB for SASL user joejob
|
||||||
# 3. 10MB default
|
# 3. 10MB default
|
||||||
id=SZ001; state==END-OF-MESSAGE; action=REJECT message too large; size=30000000 ; client_name=\.customer1.tld$
|
id=SZ001; state==END-OF-MESSAGE; action=DUNNO; size<=30000000 ; client_name=\.customer1.tld$
|
||||||
id=SZ002; state==END-OF-MESSAGE; action=REJECT message too large; size=20000000 ; sasl_username==joejob
|
id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=20000000 ; sasl_username==joejob
|
||||||
id=SZ003; state==END-OF-MESSAGE; action=REJECT message too large; size=10000000</pre>
|
id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=10000000
|
||||||
|
id=SZ100; state==END-OF-MESSAGE; action=REJECT message too large</pre>
|
||||||
<pre>
|
<pre>
|
||||||
## Selective Greylisting
|
## Selective Greylisting
|
||||||
# 1. if listed on zen.spamhaus.org with results 127.0.0.10 or .11, dns cache timeout 1200s
|
# 1. if listed on zen.spamhaus.org with results 127.0.0.10 or .11, dns cache timeout 1200s
|
||||||
|
@ -856,9 +864,9 @@ the '-I' switch to have your configuration refreshed for every request postfwd r
|
||||||
# 1. exceeded 30 requests per hour or
|
# 1. exceeded 30 requests per hour or
|
||||||
# 2. tried to send more than 1.5mb within 10 minutes
|
# 2. tried to send more than 1.5mb within 10 minutes
|
||||||
id=RATE01 ; client_name==unknown ; state==RCPT ; \
|
id=RATE01 ; client_name==unknown ; state==RCPT ; \
|
||||||
action==rate($$client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
action==rate(client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
||||||
id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \
|
id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \
|
||||||
action==size($$client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)</pre>
|
action==size(client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)</pre>
|
||||||
<pre>
|
<pre>
|
||||||
## Macros
|
## Macros
|
||||||
# definition
|
# definition
|
||||||
|
|
|
@ -18,6 +18,7 @@ SYNOPSIS
|
||||||
--proto <proto> socket type (tcp or unix)
|
--proto <proto> socket type (tcp or unix)
|
||||||
-u, --user <name> set uid to user <name>
|
-u, --user <name> set uid to user <name>
|
||||||
-g, --group <name> set gid to group <name>
|
-g, --group <name> set gid to group <name>
|
||||||
|
--umask <mask> set umask for file permissions
|
||||||
-R, --chroot <path> chroot the daemon to <path>
|
-R, --chroot <path> chroot the daemon to <path>
|
||||||
--pidfile <path> create pidfile under <path>
|
--pidfile <path> create pidfile under <path>
|
||||||
-l, --logname <label> label for syslog messages
|
-l, --logname <label> label for syslog messages
|
||||||
|
@ -464,10 +465,11 @@ DESCRIPTION
|
||||||
this command creates a counter for the given <item>, which will be increased any time a request
|
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.
|
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.
|
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)!
|
||||||
# no more than 3 requests per 5 minutes
|
# no more than 3 requests per 5 minutes
|
||||||
# from the same "unknown" client
|
# from the same "unknown" client
|
||||||
id=RATE01 ; client_name==unknown ; \
|
id=RATE01 ; client_name==unknown ; \
|
||||||
action==rate($$client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)
|
action==rate(client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)
|
||||||
|
|
||||||
size (<item>/<max>/<time>/<action>)
|
size (<item>/<max>/<time>/<action>)
|
||||||
this command works similar to the rate() command with the difference, that the rate counter is
|
this command works similar to the rate() command with the difference, that the rate counter is
|
||||||
|
@ -475,7 +477,7 @@ DESCRIPTION
|
||||||
smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
||||||
# size limit 1.5mb per hour per client
|
# size limit 1.5mb per hour per client
|
||||||
id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
||||||
action==size($$client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)
|
action==size(client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)
|
||||||
|
|
||||||
rcpt (<item>/<max>/<time>/<action>)
|
rcpt (<item>/<max>/<time>/<action>)
|
||||||
this command works similar to the rate() command with the difference, that the rate counter is
|
this command works similar to the rate() command with the difference, that the rate counter is
|
||||||
|
@ -484,7 +486,7 @@ DESCRIPTION
|
||||||
check it within the ruleset:
|
check it within the ruleset:
|
||||||
# recipient count limit 3 per hour per client
|
# recipient count limit 3 per hour per client
|
||||||
id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
||||||
action==rcpt($$client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)
|
action==rcpt(client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)
|
||||||
|
|
||||||
ask (<addr>:<port>[:<ignore>])
|
ask (<addr>:<port>[:<ignore>])
|
||||||
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
||||||
|
@ -648,6 +650,11 @@ DESCRIPTION
|
||||||
-g, --group <name>
|
-g, --group <name>
|
||||||
Changes real and effective group to <name>.
|
Changes real and effective group to <name>.
|
||||||
|
|
||||||
|
--umask <mask>
|
||||||
|
Changes the umask for filepermissions (unix domain sockets, pidfiles).
|
||||||
|
Attention: This is umask, not chmod - you have to specify the bits that
|
||||||
|
should NOT apply. E.g.: umask 077 equals to chmod 700.
|
||||||
|
|
||||||
-R, --chroot <path>
|
-R, --chroot <path>
|
||||||
Chroot the process to the specified path.
|
Chroot the process to the specified path.
|
||||||
Test this before using - you might need some libs there.
|
Test this before using - you might need some libs there.
|
||||||
|
@ -847,9 +854,10 @@ DESCRIPTION
|
||||||
# 1. 30MB for systems in *.customer1.tld
|
# 1. 30MB for systems in *.customer1.tld
|
||||||
# 2. 20MB for SASL user joejob
|
# 2. 20MB for SASL user joejob
|
||||||
# 3. 10MB default
|
# 3. 10MB default
|
||||||
id=SZ001; state==END-OF-MESSAGE; action=REJECT message too large; size=30000000 ; client_name=\.customer1.tld$
|
id=SZ001; state==END-OF-MESSAGE; action=DUNNO; size<=30000000 ; client_name=\.customer1.tld$
|
||||||
id=SZ002; state==END-OF-MESSAGE; action=REJECT message too large; size=20000000 ; sasl_username==joejob
|
id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=20000000 ; sasl_username==joejob
|
||||||
id=SZ003; state==END-OF-MESSAGE; action=REJECT message too large; size=10000000
|
id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=10000000
|
||||||
|
id=SZ100; state==END-OF-MESSAGE; action=REJECT message too large
|
||||||
|
|
||||||
## Selective Greylisting
|
## Selective Greylisting
|
||||||
# 1. if listed on zen.spamhaus.org with results 127.0.0.10 or .11, dns cache timeout 1200s
|
# 1. if listed on zen.spamhaus.org with results 127.0.0.10 or .11, dns cache timeout 1200s
|
||||||
|
@ -898,9 +906,9 @@ DESCRIPTION
|
||||||
# 1. exceeded 30 requests per hour or
|
# 1. exceeded 30 requests per hour or
|
||||||
# 2. tried to send more than 1.5mb within 10 minutes
|
# 2. tried to send more than 1.5mb within 10 minutes
|
||||||
id=RATE01 ; client_name==unknown ; state==RCPT ; \
|
id=RATE01 ; client_name==unknown ; state==RCPT ; \
|
||||||
action==rate($$client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
action==rate(client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
||||||
id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \
|
id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \
|
||||||
action==size($$client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)
|
action==size(client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)
|
||||||
|
|
||||||
## Macros
|
## Macros
|
||||||
# definition
|
# definition
|
||||||
|
|
1182
doc/postfwd2.html
Normal file
1182
doc/postfwd2.html
Normal file
File diff suppressed because it is too large
Load diff
1270
doc/postfwd2.txt
Normal file
1270
doc/postfwd2.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -129,7 +129,7 @@
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "POSTFWD 1"
|
.IX Title "POSTFWD 1"
|
||||||
.TH POSTFWD 1 "2009-09-03" "perl v5.8.5" "User Contributed Perl Documentation"
|
.TH POSTFWD 1 "2010-11-14" "perl v5.8.5" "User Contributed Perl Documentation"
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
postfwd \- postfix firewall daemon
|
postfwd \- postfix firewall daemon
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
|
@ -147,7 +147,7 @@ postfwd [\s-1OPTIONS\s0] [\s-1SOURCE1\s0, \s-1SOURCE2\s0, ...]
|
||||||
\& -s, --scores <v>=<r> returns <r> when score exceeds <v>
|
\& -s, --scores <v>=<r> returns <r> when score exceeds <v>
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 11
|
.Vb 12
|
||||||
\& Networking:
|
\& Networking:
|
||||||
\& -d, --daemon run postfwd as daemon
|
\& -d, --daemon run postfwd as daemon
|
||||||
\& -i, --interface <dev> listen on interface <dev>
|
\& -i, --interface <dev> listen on interface <dev>
|
||||||
|
@ -155,6 +155,7 @@ postfwd [\s-1OPTIONS\s0] [\s-1SOURCE1\s0, \s-1SOURCE2\s0, ...]
|
||||||
\& --proto <proto> socket type (tcp or unix)
|
\& --proto <proto> socket type (tcp or unix)
|
||||||
\& -u, --user <name> set uid to user <name>
|
\& -u, --user <name> set uid to user <name>
|
||||||
\& -g, --group <name> set gid to group <name>
|
\& -g, --group <name> set gid to group <name>
|
||||||
|
\& --umask <mask> set umask for file permissions
|
||||||
\& -R, --chroot <path> chroot the daemon to <path>
|
\& -R, --chroot <path> chroot the daemon to <path>
|
||||||
\& --pidfile <path> create pidfile under <path>
|
\& --pidfile <path> create pidfile under <path>
|
||||||
\& -l, --logname <label> label for syslog messages
|
\& -l, --logname <label> label for syslog messages
|
||||||
|
@ -674,15 +675,16 @@ postfwd actions control the behaviour of the program. Currently you can specify
|
||||||
\& by "," characters.
|
\& by "," characters.
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 8
|
.Vb 9
|
||||||
\& rate (<item>/<max>/<time>/<action>)
|
\& rate (<item>/<max>/<time>/<action>)
|
||||||
\& this command creates a counter for the given <item>, which will be increased any time a request
|
\& 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.
|
\& 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.
|
\& 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)!
|
||||||
\& # no more than 3 requests per 5 minutes
|
\& # no more than 3 requests per 5 minutes
|
||||||
\& # from the same "unknown" client
|
\& # from the same "unknown" client
|
||||||
\& id=RATE01 ; client_name==unknown ; \e
|
\& id=RATE01 ; client_name==unknown ; \e
|
||||||
\& action==rate($$client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)
|
\& action==rate(client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 7
|
.Vb 7
|
||||||
|
@ -692,7 +694,7 @@ postfwd actions control the behaviour of the program. Currently you can specify
|
||||||
\& smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
\& smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
||||||
\& # size limit 1.5mb per hour per client
|
\& # size limit 1.5mb per hour per client
|
||||||
\& id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \e
|
\& id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \e
|
||||||
\& action==size($$client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)
|
\& action==size(client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 8
|
.Vb 8
|
||||||
|
@ -703,7 +705,7 @@ postfwd actions control the behaviour of the program. Currently you can specify
|
||||||
\& check it within the ruleset:
|
\& check it within the ruleset:
|
||||||
\& # recipient count limit 3 per hour per client
|
\& # recipient count limit 3 per hour per client
|
||||||
\& id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \e
|
\& id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \e
|
||||||
\& action==rcpt($$client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)
|
\& action==rcpt(client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 9
|
.Vb 9
|
||||||
|
@ -911,6 +913,13 @@ The following arguments will control it's behaviour in this case.
|
||||||
\& Changes real and effective group to <name>.
|
\& Changes real and effective group to <name>.
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
|
.Vb 4
|
||||||
|
\& --umask <mask>
|
||||||
|
\& Changes the umask for filepermissions (unix domain sockets, pidfiles).
|
||||||
|
\& Attention: This is umask, not chmod - you have to specify the bits that
|
||||||
|
\& should NOT apply. E.g.: umask 077 equals to chmod 700.
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
.Vb 3
|
.Vb 3
|
||||||
\& -R, --chroot <path>
|
\& -R, --chroot <path>
|
||||||
\& Chroot the process to the specified path.
|
\& Chroot the process to the specified path.
|
||||||
|
@ -1179,14 +1188,15 @@ the '\-I' switch to have your configuration refreshed for every request postfwd
|
||||||
\& id=RBL04 ; action=REJECT combined RBL+RHSBL check ; rbl=bl.spamcop.net ; rhsbl=rhsbl.ahbl.org, rhsbl.sorbs.net
|
\& id=RBL04 ; action=REJECT combined RBL+RHSBL check ; rbl=bl.spamcop.net ; rhsbl=rhsbl.ahbl.org, rhsbl.sorbs.net
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 7
|
.Vb 8
|
||||||
\& ## Message size (requires message_size_limit to be set to 30000000)
|
\& ## Message size (requires message_size_limit to be set to 30000000)
|
||||||
\& # 1. 30MB for systems in *.customer1.tld
|
\& # 1. 30MB for systems in *.customer1.tld
|
||||||
\& # 2. 20MB for SASL user joejob
|
\& # 2. 20MB for SASL user joejob
|
||||||
\& # 3. 10MB default
|
\& # 3. 10MB default
|
||||||
\& id=SZ001; state==END-OF-MESSAGE; action=REJECT message too large; size=30000000 ; client_name=\e.customer1.tld$
|
\& id=SZ001; state==END-OF-MESSAGE; action=DUNNO; size<=30000000 ; client_name=\e.customer1.tld$
|
||||||
\& id=SZ002; state==END-OF-MESSAGE; action=REJECT message too large; size=20000000 ; sasl_username==joejob
|
\& id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=20000000 ; sasl_username==joejob
|
||||||
\& id=SZ003; state==END-OF-MESSAGE; action=REJECT message too large; size=10000000
|
\& id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=10000000
|
||||||
|
\& id=SZ100; state==END-OF-MESSAGE; action=REJECT message too large
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 7
|
.Vb 7
|
||||||
|
@ -1245,9 +1255,9 @@ the '\-I' switch to have your configuration refreshed for every request postfwd
|
||||||
\& # 1. exceeded 30 requests per hour or
|
\& # 1. exceeded 30 requests per hour or
|
||||||
\& # 2. tried to send more than 1.5mb within 10 minutes
|
\& # 2. tried to send more than 1.5mb within 10 minutes
|
||||||
\& id=RATE01 ; client_name==unknown ; state==RCPT ; \e
|
\& id=RATE01 ; client_name==unknown ; state==RCPT ; \e
|
||||||
\& action==rate($$client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
\& action==rate(client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
||||||
\& id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \e
|
\& id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \e
|
||||||
\& action==size($$client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)
|
\& action==size(client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 8
|
.Vb 8
|
||||||
|
|
1671
man/man8/postfwd2.8
Normal file
1671
man/man8/postfwd2.8
Normal file
File diff suppressed because it is too large
Load diff
142
sbin/postfwd
142
sbin/postfwd
|
@ -25,7 +25,7 @@ use vars qw(@ISA);
|
||||||
|
|
||||||
# Program constants
|
# Program constants
|
||||||
our($NAME) = 'postfwd';
|
our($NAME) = 'postfwd';
|
||||||
our($VERSION) = '1.18';
|
our($VERSION) = '1.20';
|
||||||
|
|
||||||
# Networking options (use -i, -p and -R to change)
|
# Networking options (use -i, -p and -R to change)
|
||||||
our($def_net_pid) = "/var/run/".$NAME.".pid";
|
our($def_net_pid) = "/var/run/".$NAME.".pid";
|
||||||
|
@ -33,6 +33,7 @@ our($def_net_chroot) = "";
|
||||||
our($def_net_interface) = "127.0.0.1";
|
our($def_net_interface) = "127.0.0.1";
|
||||||
our($def_net_port) = "10040";
|
our($def_net_port) = "10040";
|
||||||
our($def_net_proto) = "tcp";
|
our($def_net_proto) = "tcp";
|
||||||
|
our($def_net_umask) = "0111";
|
||||||
our($def_net_user) = "nobody";
|
our($def_net_user) = "nobody";
|
||||||
our($def_net_group) = "nobody";
|
our($def_net_group) = "nobody";
|
||||||
our($def_dns_queuesize) = "300";
|
our($def_dns_queuesize) = "300";
|
||||||
|
@ -201,7 +202,7 @@ our($SepReq) = '///';
|
||||||
our($SepLst) = ':::';
|
our($SepLst) = ':::';
|
||||||
our($KeyVal) = qr/^([^=]+)=(.*)$/;
|
our($KeyVal) = qr/^([^=]+)=(.*)$/;
|
||||||
use vars qw(
|
use vars qw(
|
||||||
@Configs @Rules @CacheID @DNSBL_Text @Plugins
|
@Configs @Rules @CacheID @DNSBL_Text @Plugins @Rate_Items
|
||||||
%Config_Cache %DNS_Cache %Request_Cache %Rule_by_ID
|
%Config_Cache %DNS_Cache %Request_Cache %Rule_by_ID
|
||||||
%Matches %opt_scores %ACLs %Rates %Timeouts
|
%Matches %opt_scores %ACLs %Rates %Timeouts
|
||||||
%postfwd_items %postfwd_items_plugin
|
%postfwd_items %postfwd_items_plugin
|
||||||
|
@ -212,7 +213,7 @@ use vars qw(
|
||||||
$Starttime $Startdate $Cleanup_Requests
|
$Starttime $Startdate $Cleanup_Requests
|
||||||
$Cleanup_RBLs $Cleanup_Rates $Cleanup_Timeouts
|
$Cleanup_RBLs $Cleanup_Rates $Cleanup_Timeouts
|
||||||
$opt_daemon $opt_instantconfig $opt_nodns $opt_nodnslog
|
$opt_daemon $opt_instantconfig $opt_nodns $opt_nodnslog
|
||||||
$opt_norulelog $opt_summary $net_interface $net_port
|
$opt_norulelog $opt_summary $net_interface $net_port $net_umask
|
||||||
$net_user $net_group $net_chroot $net_pid $net_proto
|
$net_user $net_group $net_chroot $net_pid $net_proto
|
||||||
$opt_perfmon $opt_test $opt_verbose $opt_noidlestats
|
$opt_perfmon $opt_test $opt_verbose $opt_noidlestats
|
||||||
$opt_cache_rdomain_only $opt_cache_no_size $config_timeout
|
$opt_cache_rdomain_only $opt_cache_no_size $config_timeout
|
||||||
|
@ -576,6 +577,27 @@ sub prepare_item {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#
|
#
|
||||||
|
# compatibility for old "rate"-syntax
|
||||||
|
#
|
||||||
|
sub check_for_old_syntax {
|
||||||
|
my($myindex,$myfile,$mynum,$mykey,$myvalue) = @_;
|
||||||
|
if ($mykey =~ /^action$/) {
|
||||||
|
if ($myvalue =~ /^(\w[\-\w]+)\s*\(\s*(.*?)\s*\)$/) {
|
||||||
|
my($mycmd,$myarg) = ($1, $2);
|
||||||
|
if ($mycmd =~ /^(rate|size|rcpt)$/i) {
|
||||||
|
if ($myarg =~ /^\$\$(.*)$/) {
|
||||||
|
$myarg = $1;
|
||||||
|
$myvalue = "$mycmd($myarg)";
|
||||||
|
mylogs "notice", "notice: Rule $myindex ($myfile line $mynum): "
|
||||||
|
."removing obsolete '\$\$' for $mycmd limit index. See man page for new syntax." if $opt_verbose;
|
||||||
|
};
|
||||||
|
push @Rate_Items, (split '/', $myarg)[0];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return $myvalue;
|
||||||
|
};
|
||||||
|
#
|
||||||
# parses configuration line
|
# parses configuration line
|
||||||
#
|
#
|
||||||
sub parse_config_line {
|
sub parse_config_line {
|
||||||
|
@ -601,6 +623,7 @@ sub parse_config_line {
|
||||||
." overriding $mykey=\"".$myrule{$mykey}."\""
|
." overriding $mykey=\"".$myrule{$mykey}."\""
|
||||||
." with $mykey=\"$myvalue\""
|
." with $mykey=\"$myvalue\""
|
||||||
if (defined $myrule{$mykey});
|
if (defined $myrule{$mykey});
|
||||||
|
$myvalue = check_for_old_syntax($myindex,$myfile,$mynum,$mykey,$myvalue);
|
||||||
$myrule{$mykey} = $myvalue;
|
$myrule{$mykey} = $myvalue;
|
||||||
} elsif ($mykey =~ /^$COMP_CSV$/) {
|
} elsif ($mykey =~ /^$COMP_CSV$/) {
|
||||||
$myvalue =~ s/\s*,\s*/,/g;
|
$myvalue =~ s/\s*,\s*/,/g;
|
||||||
|
@ -663,7 +686,7 @@ sub read_config {
|
||||||
my($mytype,$myitem,$config);
|
my($mytype,$myitem,$config);
|
||||||
|
|
||||||
# init, cleanup cache and config vars
|
# init, cleanup cache and config vars
|
||||||
@Rules = %Rule_by_ID = %Request_Cache = %Rates = ();
|
@Rules = %Rule_by_ID = %Request_Cache = %Rates = @Rate_Items = ();
|
||||||
|
|
||||||
# parse configurations
|
# parse configurations
|
||||||
for $config (@Configs) {
|
for $config (@Configs) {
|
||||||
|
@ -693,6 +716,8 @@ sub read_config {
|
||||||
} else {
|
} else {
|
||||||
# update Rule by ID hash
|
# update Rule by ID hash
|
||||||
map { $Rule_by_ID{$Rules[$_]{$COMP_ID}} = $_ } (0 .. $#Rules);
|
map { $Rule_by_ID{$Rules[$_]{$COMP_ID}} = $_ } (0 .. $#Rules);
|
||||||
|
@Rate_Items = uniq(@Rate_Items) if @Rate_Items;
|
||||||
|
mylogs $syslog_priority, "rate items: ".(join ', ', @Rate_Items) if $opt_verbose;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#
|
#
|
||||||
|
@ -874,6 +899,7 @@ sub rbl_check {
|
||||||
if $opt_verbose;
|
if $opt_verbose;
|
||||||
push @DNSBL_Text, $DNS_Cache{$myquery}{type}.':'.$DNS_Cache{$myquery}{name}.':<'.($DNS_Cache{$myquery}{TXT} || '').'>'
|
push @DNSBL_Text, $DNS_Cache{$myquery}{type}.':'.$DNS_Cache{$myquery}{name}.':<'.($DNS_Cache{$myquery}{TXT} || '').'>'
|
||||||
if (defined $DNS_Cache{$myquery}{type} and defined $DNS_Cache{$myquery}{name});
|
if (defined $DNS_Cache{$myquery}{type} and defined $DNS_Cache{$myquery}{name});
|
||||||
|
last ANSWER;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -885,7 +911,7 @@ sub rbl_check {
|
||||||
sub dns_query {
|
sub dns_query {
|
||||||
my (@queries) = @_; undef my @result;
|
my (@queries) = @_; undef my @result;
|
||||||
eval {
|
eval {
|
||||||
local $SIG{__DIE__} = sub { mylogs 'notice', "dns err: \"$!\", detail: \"@_\""; };
|
local $SIG{__DIE__} = sub { mylogs 'notice', "dns err: \"$!\", detail: \"@_\""; return if $^S; };
|
||||||
@result = dns_query_net_dns(@queries);
|
@result = dns_query_net_dns(@queries);
|
||||||
};
|
};
|
||||||
return @result;
|
return @result;
|
||||||
|
@ -1008,9 +1034,19 @@ sub postfwd_items {
|
||||||
my($myresult) = ($val and $myitem);
|
my($myresult) = ($val and $myitem);
|
||||||
mylogs $syslog_priority, "type cidr : \"$myitem\" \"$cmp\" \"$val\"" if ($opt_verbose > 1);
|
mylogs $syslog_priority, "type cidr : \"$myitem\" \"$cmp\" \"$val\"" if ($opt_verbose > 1);
|
||||||
if ($myresult) {
|
if ($myresult) {
|
||||||
return $myresult if ( ($val eq '0.0.0.0/0') and ($myitem =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) );
|
# always true
|
||||||
|
$myresult = ($val eq '0.0.0.0/0');
|
||||||
|
unless ($myresult) {
|
||||||
|
# v4 addresses only
|
||||||
|
$myresult = ($myitem =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/);
|
||||||
|
if ($myresult) {
|
||||||
$val .= '/32' unless ($val =~ /\/\d{1,2}$/);
|
$val .= '/32' unless ($val =~ /\/\d{1,2}$/);
|
||||||
$myresult = cidr_match((cidr_parse($val)),$myitem);
|
$myresult = cidr_match((cidr_parse($val)),$myitem);
|
||||||
|
} else {
|
||||||
|
mylogs $syslog_priority, "Non IPv4 address. Using type default" if ($opt_verbose > 1);
|
||||||
|
return &{$postfwd_compare{default}}($cmp,$val,$myitem,%request);
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
$myresult = not($myresult) if ($cmp eq '!=');
|
$myresult = not($myresult) if ($cmp eq '!=');
|
||||||
return $myresult;
|
return $myresult;
|
||||||
|
@ -1313,6 +1349,8 @@ sub postfwd_items {
|
||||||
my($myaction) = $default_action; my($stop) = 0;
|
my($myaction) = $default_action; my($stop) = 0;
|
||||||
my($ratetype,$ratecount,$ratetime,$ratecmd) = split "/", $myarg, 4;
|
my($ratetype,$ratecount,$ratetime,$ratecmd) = split "/", $myarg, 4;
|
||||||
if ($ratetype and $ratecount and $ratetime and $ratecmd) {
|
if ($ratetype and $ratecount and $ratetime and $ratecmd) {
|
||||||
|
if ( defined $request{$ratetype} ) {
|
||||||
|
$ratetype .= "=".$request{$ratetype};
|
||||||
unless ( defined $Rates{$ratetype} ) {
|
unless ( defined $Rates{$ratetype} ) {
|
||||||
$Rates{$ratetype} = {
|
$Rates{$ratetype} = {
|
||||||
type => $mycmd,
|
type => $mycmd,
|
||||||
|
@ -1328,6 +1366,9 @@ sub postfwd_items {
|
||||||
." [type: ".$mycmd.", max: ".$ratecount.", time: ".$ratetime."s]"
|
." [type: ".$mycmd.", max: ".$ratecount.", time: ".$ratetime."s]"
|
||||||
if ($opt_verbose > 1);
|
if ($opt_verbose > 1);
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
mylogs $syslog_priority, "[RULES] ".$myline.", ignoring empty index for ".$mycmd." limit '".$ratetype."'" if ($opt_verbose > 1);
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
mylogs "notice", "[RULES] ".$myline.", ignoring unknown ".$mycmd."() attribute \'".$myarg."\'";
|
mylogs "notice", "[RULES] ".$myline.", ignoring unknown ".$mycmd."() attribute \'".$myarg."\'";
|
||||||
};
|
};
|
||||||
|
@ -1558,7 +1599,7 @@ sub compare_rule {
|
||||||
mylogs "notice", "[DNSQUERY] skipping rbls: $timed - too much timeouts" if $timed;
|
mylogs "notice", "[DNSQUERY] skipping rbls: $timed - too much timeouts" if $timed;
|
||||||
|
|
||||||
push @queries, rbl_prepare_lookups ( $COMP_RBL_KEY, $request{reverse_address}, @{$Rules[$index]{$COMP_RBL_KEY}} )
|
push @queries, rbl_prepare_lookups ( $COMP_RBL_KEY, $request{reverse_address}, @{$Rules[$index]{$COMP_RBL_KEY}} )
|
||||||
if ( exists($Rules[$index]{$COMP_RBL_KEY}) );
|
if ( exists($Rules[$index]{$COMP_RBL_KEY}) and not($request{client_address} =~ /:/) );
|
||||||
push @queries, rbl_prepare_lookups ( $COMP_RHSBL_KEY, $request{client_name}, @{$Rules[$index]{$COMP_RHSBL_KEY}} )
|
push @queries, rbl_prepare_lookups ( $COMP_RHSBL_KEY, $request{client_name}, @{$Rules[$index]{$COMP_RHSBL_KEY}} )
|
||||||
if ( exists($Rules[$index]{$COMP_RHSBL_KEY}) and not($request{client_name} eq "unknown") );
|
if ( exists($Rules[$index]{$COMP_RHSBL_KEY}) and not($request{client_name} eq "unknown") );
|
||||||
push @queries, rbl_prepare_lookups ( $COMP_RHSBL_KEY_CLIENT, $request{client_name}, @{$Rules[$index]{$COMP_RHSBL_KEY_CLIENT}} )
|
push @queries, rbl_prepare_lookups ( $COMP_RHSBL_KEY_CLIENT, $request{client_name}, @{$Rules[$index]{$COMP_RHSBL_KEY_CLIENT}} )
|
||||||
|
@ -1818,29 +1859,33 @@ sub smtpd_access_policy {
|
||||||
};
|
};
|
||||||
|
|
||||||
# increase rate limits
|
# increase rate limits
|
||||||
RATES: foreach $checkreq (keys %request) {
|
if (@Rate_Items) {
|
||||||
next RATES unless ( $request{$checkreq} and (defined $Rates{$request{$checkreq}}) );
|
RATES: foreach $checkreq (@Rate_Items) {
|
||||||
if ( ($now - $Rates{$request{$checkreq}}{"time"}) > $Rates{$request{$checkreq}}{ttl} ) {
|
next RATES unless $request{$checkreq};
|
||||||
|
my $checkval = $checkreq."=".$request{$checkreq};
|
||||||
|
next RATES unless ( defined $Rates{$checkval});
|
||||||
|
if ( ($now - $Rates{$checkval}{"time"}) > $Rates{$checkval}{ttl} ) {
|
||||||
# renew rate
|
# renew rate
|
||||||
$Rates{$request{$checkreq}}{count} = ( ($Rates{$request{$checkreq}}{type} eq 'size') ? $request{size} :
|
$Rates{$checkval}{count} = ( ($Rates{$checkval}{type} eq 'size') ? $request{size} :
|
||||||
(($Rates{$request{$checkreq}}{type} eq 'rcpt') ? $request{recipient_count} : 1 ) );
|
(($Rates{$checkval}{type} eq 'rcpt') ? $request{recipient_count} : 1 ) );
|
||||||
$Rates{$request{$checkreq}}{"time"} = $now;
|
$Rates{$checkval}{"time"} = $now;
|
||||||
mylogs $syslog_priority, "[RATE] renewing rate object ".$request{$checkreq}
|
mylogs $syslog_priority, "[RATE] renewing rate object '".$checkval."'"
|
||||||
." [type: ".$Rates{$request{$checkreq}}{type}
|
." [type: ".$Rates{$checkval}{type}
|
||||||
.", max: ".$Rates{$request{$checkreq}}{maxcount}
|
.", max: ".$Rates{$checkval}{maxcount}
|
||||||
.", time: ".$Rates{$request{$checkreq}}{ttl}."s]"
|
.", time: ".$Rates{$checkval}{ttl}."s]"
|
||||||
if ($opt_verbose > 1);
|
if ($opt_verbose > 1);
|
||||||
} else {
|
} else {
|
||||||
# increase rate
|
# increase rate
|
||||||
$Rates{$request{$checkreq}}{count} += ( ($Rates{$request{$checkreq}}{type} eq 'size') ? $request{size} :
|
$Rates{$checkval}{count} += ( ($Rates{$checkval}{type} eq 'size') ? $request{size} :
|
||||||
(($Rates{$request{$checkreq}}{type} eq 'rcpt') ? $request{recipient_count} : 1 ) );
|
(($Rates{$checkval}{type} eq 'rcpt') ? $request{recipient_count} : 1 ) );
|
||||||
mylogs $syslog_priority, "[RATE] increasing rate object ".$request{$checkreq}
|
mylogs $syslog_priority, "[RATE] increasing rate object '".$checkval."'"
|
||||||
." to ".$Rates{$request{$checkreq}}{count}
|
." to ".$Rates{$checkval}{count}
|
||||||
." [type: ".$Rates{$request{$checkreq}}{type}
|
." [type: ".$Rates{$checkval}{type}
|
||||||
.", max: ".$Rates{$request{$checkreq}}{maxcount}
|
.", max: ".$Rates{$checkval}{maxcount}
|
||||||
.", time: ".$Rates{$request{$checkreq}}{ttl}."s]"
|
.", time: ".$Rates{$checkval}{ttl}."s]"
|
||||||
if ($opt_verbose > 1);
|
if ($opt_verbose > 1);
|
||||||
$ratehit = $checkreq if ($Rates{$request{$checkreq}}{count} > $Rates{$request{$checkreq}}{maxcount});
|
};
|
||||||
|
$ratehit = ($Rates{$checkval}{count} > $Rates{$checkval}{maxcount}) ? $checkval : undef;
|
||||||
last RATES if $ratehit;
|
last RATES if $ratehit;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1885,10 +1930,10 @@ sub smtpd_access_policy {
|
||||||
if ( $ratehit ) {
|
if ( $ratehit ) {
|
||||||
|
|
||||||
$Counter_Rates++;
|
$Counter_Rates++;
|
||||||
$Matches{$Rates{$request{$ratehit}}{rule}}++;
|
$Matches{$Rates{$ratehit}{rule}}++;
|
||||||
$myaction = $Rates{$request{$ratehit}}{action};
|
$myaction = $Rates{$ratehit}{action};
|
||||||
mylogs $syslog_priority, "[RATE] rule=".$Rule_by_ID{$Rates{$request{$ratehit}}{rule}}
|
mylogs $syslog_priority, "[RATE] rule=".$Rule_by_ID{$Rates{$ratehit}{rule}}
|
||||||
. ", id=".$Rates{$request{$ratehit}}{rule}
|
. ", id=".$Rates{$ratehit}{rule}
|
||||||
. ", client=".$request{client_name}."[".$request{client_address}."]"
|
. ", client=".$request{client_name}."[".$request{client_address}."]"
|
||||||
. ", sender=<".(($request{sender} eq '<>') ? "" : $request{sender}).">"
|
. ", sender=<".(($request{sender} eq '<>') ? "" : $request{sender}).">"
|
||||||
. ", recipient=<".$request{recipient}.">"
|
. ", recipient=<".$request{recipient}.">"
|
||||||
|
@ -1896,10 +1941,10 @@ sub smtpd_access_policy {
|
||||||
. ", proto=".$request{protocol_name}
|
. ", proto=".$request{protocol_name}
|
||||||
. ", state=".$request{protocol_state}
|
. ", state=".$request{protocol_state}
|
||||||
. ", delay=".(time - $now)."s"
|
. ", delay=".(time - $now)."s"
|
||||||
. ", action=".$myaction." (item: ".$request{$ratehit}
|
. ", action=".$myaction." (item: '".$ratehit."'"
|
||||||
. ", type: ".$Rates{$request{$ratehit}}{type}
|
. ", type: ".$Rates{$ratehit}{type}
|
||||||
. ", count: ".$Rates{$request{$ratehit}}{count}."/".$Rates{$request{$ratehit}}{maxcount}
|
. ", count: ".$Rates{$ratehit}{count}."/".$Rates{$ratehit}{maxcount}
|
||||||
. ", time: ".($now - $Rates{$request{$ratehit}}{"time"})."/".$Rates{$request{$ratehit}}{ttl}."s)"
|
. ", time: ".($now - $Rates{$ratehit}{"time"})."/".$Rates{$ratehit}{ttl}."s)"
|
||||||
unless $opt_norulelog;
|
unless $opt_norulelog;
|
||||||
|
|
||||||
# check cache
|
# check cache
|
||||||
|
@ -2071,6 +2116,7 @@ GetOptions ( "term|kill|stop|k" => \$opt_kill,
|
||||||
'proto=s' => \$net_proto,
|
'proto=s' => \$net_proto,
|
||||||
'R|chroot=s' => \$net_chroot,
|
'R|chroot=s' => \$net_chroot,
|
||||||
'pid|pidfile=s' => \$net_pid,
|
'pid|pidfile=s' => \$net_pid,
|
||||||
|
'umask=s' => \$net_umask,
|
||||||
'u|user=s' => \$net_user,
|
'u|user=s' => \$net_user,
|
||||||
'g|group=s' => \$net_group,
|
'g|group=s' => \$net_group,
|
||||||
'dns_queuesize=s' => \$dns_queuesize,
|
'dns_queuesize=s' => \$dns_queuesize,
|
||||||
|
@ -2102,6 +2148,7 @@ GetOptions ( "term|kill|stop|k" => \$opt_kill,
|
||||||
'r|rule=s' => sub{ my($opt,$value) = @_; push (@Configs, $opt.'::'.$value) },
|
'r|rule=s' => sub{ my($opt,$value) = @_; push (@Configs, $opt.'::'.$value) },
|
||||||
'plugins=s' => \@Plugins,
|
'plugins=s' => \@Plugins,
|
||||||
'V|version' => sub{ print "$NAME $VERSION (Net::DNS ".(Net::DNS->VERSION || '<undef>').", Net::Server ".(Net::Server->VERSION || '<undef>').", Sys::Syslog ".($Sys::Syslog::VERSION || '<undef>').", Perl ".$]." on ".$^O.")\n"; exit 1; },
|
'V|version' => sub{ print "$NAME $VERSION (Net::DNS ".(Net::DNS->VERSION || '<undef>').", Net::Server ".(Net::Server->VERSION || '<undef>').", Sys::Syslog ".($Sys::Syslog::VERSION || '<undef>').", Perl ".$]." on ".$^O.")\n"; exit 1; },
|
||||||
|
'versionshort|shortversion' => sub{ print "$VERSION\n"; exit 1; },
|
||||||
'C|showconfig' => \$opt_showconfig,
|
'C|showconfig' => \$opt_showconfig,
|
||||||
'h|H|?|help|Help|HELP' => sub{ pod2usage (-msg => "\nPlease see \"".$NAME." -m\" for detailed instructions.\n", -verbose => 1); },
|
'h|H|?|help|Help|HELP' => sub{ pod2usage (-msg => "\nPlease see \"".$NAME." -m\" for detailed instructions.\n", -verbose => 1); },
|
||||||
'm|M|manual' => sub{ # contructing command string (de-tainting $0)
|
'm|M|manual' => sub{ # contructing command string (de-tainting $0)
|
||||||
|
@ -2168,6 +2215,7 @@ get_plugins (@Plugins) if @Plugins;
|
||||||
$net_interface ||= $def_net_interface;
|
$net_interface ||= $def_net_interface;
|
||||||
$net_port ||= $def_net_port;
|
$net_port ||= $def_net_port;
|
||||||
$net_proto ||= $def_net_proto;
|
$net_proto ||= $def_net_proto;
|
||||||
|
$net_umask ||= $def_net_umask;
|
||||||
$net_user ||= $def_net_user;
|
$net_user ||= $def_net_user;
|
||||||
$net_group ||= $def_net_group;
|
$net_group ||= $def_net_group;
|
||||||
$net_chroot ||= $def_net_chroot;
|
$net_chroot ||= $def_net_chroot;
|
||||||
|
@ -2180,6 +2228,7 @@ $syslog_name ||= $NAME;
|
||||||
$net_interface = ( $net_interface =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/ ) ? $1 : $def_net_interface;
|
$net_interface = ( $net_interface =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/ ) ? $1 : $def_net_interface;
|
||||||
$net_port = ( $net_port =~ /^(\d+|[-\|\@\/\w. ]+)$/ ) ? $1 : $def_net_port;
|
$net_port = ( $net_port =~ /^(\d+|[-\|\@\/\w. ]+)$/ ) ? $1 : $def_net_port;
|
||||||
$net_proto = ( $net_proto =~ /^(tcp|unix)$/i ) ? $1 : $def_net_proto;
|
$net_proto = ( $net_proto =~ /^(tcp|unix)$/i ) ? $1 : $def_net_proto;
|
||||||
|
$net_umask = ( $net_umask =~ /^([0-7]+)$/ ) ? $1 : $def_net_umask;
|
||||||
$net_user = ( $net_user =~ /^([\w]+)$/ ) ? $1 : $def_net_user;
|
$net_user = ( $net_user =~ /^([\w]+)$/ ) ? $1 : $def_net_user;
|
||||||
$net_group = ( $net_group =~ /^([\w]+)$/ ) ? $1 : $def_net_group;
|
$net_group = ( $net_group =~ /^([\w]+)$/ ) ? $1 : $def_net_group;
|
||||||
$net_chroot = ( $net_chroot =~ /^(.+)$/ ) ? $1 : $def_net_chroot;
|
$net_chroot = ( $net_chroot =~ /^(.+)$/ ) ? $1 : $def_net_chroot;
|
||||||
|
@ -2224,6 +2273,7 @@ if ($opt_daemon) {
|
||||||
}, 'postfwd';
|
}, 'postfwd';
|
||||||
|
|
||||||
## run the servers main loop
|
## run the servers main loop
|
||||||
|
umask oct($net_umask);
|
||||||
$server->run;
|
$server->run;
|
||||||
|
|
||||||
# ignore syslog failures
|
# ignore syslog failures
|
||||||
|
@ -2253,7 +2303,7 @@ if ($opt_daemon) {
|
||||||
mylogs $syslog_priority, "successfully installed signal handlers" if $opt_verbose;
|
mylogs $syslog_priority, "successfully installed signal handlers" if $opt_verbose;
|
||||||
|
|
||||||
# process init
|
# process init
|
||||||
umask 0077;
|
umask oct($net_umask);
|
||||||
setlocale(LC_ALL, 'C');
|
setlocale(LC_ALL, 'C');
|
||||||
$0 = $0." ".join(" ",@CommandArgs);
|
$0 = $0." ".join(" ",@CommandArgs);
|
||||||
chdir "/" or fatal_exit "Could not chdir to /";
|
chdir "/" or fatal_exit "Could not chdir to /";
|
||||||
|
@ -2329,6 +2379,7 @@ postfwd [OPTIONS] [SOURCE1, SOURCE2, ...]
|
||||||
--proto <proto> socket type (tcp or unix)
|
--proto <proto> socket type (tcp or unix)
|
||||||
-u, --user <name> set uid to user <name>
|
-u, --user <name> set uid to user <name>
|
||||||
-g, --group <name> set gid to group <name>
|
-g, --group <name> set gid to group <name>
|
||||||
|
--umask <mask> set umask for file permissions
|
||||||
-R, --chroot <path> chroot the daemon to <path>
|
-R, --chroot <path> chroot the daemon to <path>
|
||||||
--pidfile <path> create pidfile under <path>
|
--pidfile <path> create pidfile under <path>
|
||||||
-l, --logname <label> label for syslog messages
|
-l, --logname <label> label for syslog messages
|
||||||
|
@ -2758,10 +2809,11 @@ postfwd actions control the behaviour of the program. Currently you can specify
|
||||||
this command creates a counter for the given <item>, which will be increased any time a request
|
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.
|
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.
|
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)!
|
||||||
# no more than 3 requests per 5 minutes
|
# no more than 3 requests per 5 minutes
|
||||||
# from the same "unknown" client
|
# from the same "unknown" client
|
||||||
id=RATE01 ; client_name==unknown ; \
|
id=RATE01 ; client_name==unknown ; \
|
||||||
action==rate($$client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)
|
action==rate(client_address/3/300/450 4.7.1 sorry, max 3 requests per 5 minutes)
|
||||||
|
|
||||||
size (<item>/<max>/<time>/<action>)
|
size (<item>/<max>/<time>/<action>)
|
||||||
this command works similar to the rate() command with the difference, that the rate counter is
|
this command works similar to the rate() command with the difference, that the rate counter is
|
||||||
|
@ -2769,7 +2821,7 @@ postfwd actions control the behaviour of the program. Currently you can specify
|
||||||
smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
smtpd_end_of_data_restrictions. if you want to be sure, you could check it within the ruleset:
|
||||||
# size limit 1.5mb per hour per client
|
# size limit 1.5mb per hour per client
|
||||||
id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
id=SIZE01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
||||||
action==size($$client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)
|
action==size(client_address/1572864/3600/450 4.7.1 sorry, max 1.5mb per hour)
|
||||||
|
|
||||||
rcpt (<item>/<max>/<time>/<action>)
|
rcpt (<item>/<max>/<time>/<action>)
|
||||||
this command works similar to the rate() command with the difference, that the rate counter is
|
this command works similar to the rate() command with the difference, that the rate counter is
|
||||||
|
@ -2778,7 +2830,7 @@ postfwd actions control the behaviour of the program. Currently you can specify
|
||||||
check it within the ruleset:
|
check it within the ruleset:
|
||||||
# recipient count limit 3 per hour per client
|
# recipient count limit 3 per hour per client
|
||||||
id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
id=RCPT01 ; state==END_OF_DATA ; client_address==!!(10.1.1.1); \
|
||||||
action==rcpt($$client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)
|
action==rcpt(client_address/3/3600/450 4.7.1 sorry, max 3 recipients per hour)
|
||||||
|
|
||||||
ask (<addr>:<port>[:<ignore>])
|
ask (<addr>:<port>[:<ignore>])
|
||||||
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
||||||
|
@ -2943,6 +2995,11 @@ The following arguments will control it's behaviour in this case.
|
||||||
-g, --group <name>
|
-g, --group <name>
|
||||||
Changes real and effective group to <name>.
|
Changes real and effective group to <name>.
|
||||||
|
|
||||||
|
--umask <mask>
|
||||||
|
Changes the umask for filepermissions (unix domain sockets, pidfiles).
|
||||||
|
Attention: This is umask, not chmod - you have to specify the bits that
|
||||||
|
should NOT apply. E.g.: umask 077 equals to chmod 700.
|
||||||
|
|
||||||
-R, --chroot <path>
|
-R, --chroot <path>
|
||||||
Chroot the process to the specified path.
|
Chroot the process to the specified path.
|
||||||
Test this before using - you might need some libs there.
|
Test this before using - you might need some libs there.
|
||||||
|
@ -3144,9 +3201,10 @@ the '-I' switch to have your configuration refreshed for every request postfwd r
|
||||||
# 1. 30MB for systems in *.customer1.tld
|
# 1. 30MB for systems in *.customer1.tld
|
||||||
# 2. 20MB for SASL user joejob
|
# 2. 20MB for SASL user joejob
|
||||||
# 3. 10MB default
|
# 3. 10MB default
|
||||||
id=SZ001; state==END-OF-MESSAGE; action=REJECT message too large; size=30000000 ; client_name=\.customer1.tld$
|
id=SZ001; state==END-OF-MESSAGE; action=DUNNO; size<=30000000 ; client_name=\.customer1.tld$
|
||||||
id=SZ002; state==END-OF-MESSAGE; action=REJECT message too large; size=20000000 ; sasl_username==joejob
|
id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=20000000 ; sasl_username==joejob
|
||||||
id=SZ003; state==END-OF-MESSAGE; action=REJECT message too large; size=10000000
|
id=SZ002; state==END-OF-MESSAGE; action=DUNNO; size<=10000000
|
||||||
|
id=SZ100; state==END-OF-MESSAGE; action=REJECT message too large
|
||||||
|
|
||||||
## Selective Greylisting
|
## Selective Greylisting
|
||||||
# 1. if listed on zen.spamhaus.org with results 127.0.0.10 or .11, dns cache timeout 1200s
|
# 1. if listed on zen.spamhaus.org with results 127.0.0.10 or .11, dns cache timeout 1200s
|
||||||
|
@ -3195,9 +3253,9 @@ the '-I' switch to have your configuration refreshed for every request postfwd r
|
||||||
# 1. exceeded 30 requests per hour or
|
# 1. exceeded 30 requests per hour or
|
||||||
# 2. tried to send more than 1.5mb within 10 minutes
|
# 2. tried to send more than 1.5mb within 10 minutes
|
||||||
id=RATE01 ; client_name==unknown ; state==RCPT ; \
|
id=RATE01 ; client_name==unknown ; state==RCPT ; \
|
||||||
action==rate($$client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
action==rate(client_address/30/3600/450 4.7.1 sorry, max 30 requests per hour)
|
||||||
id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \
|
id=SIZE01 ; client_name==unknown ; state==END_OF_DATA ; \
|
||||||
action==size($$client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)
|
action==size(client_address/1572864/600/450 4.7.1 sorry, max 1.5mb per 10 minutes)
|
||||||
|
|
||||||
## Macros
|
## Macros
|
||||||
# definition
|
# definition
|
||||||
|
|
4219
sbin/postfwd2
Executable file
4219
sbin/postfwd2
Executable file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue