Merge tag 'upstream/1.20'
Upstream version 1.20
This commit is contained in:
		
						commit
						19ceeb5e37
					
				
					 11 changed files with 8688 additions and 73 deletions
				
			
		| 
						 | 
					@ -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
											
										
									
								
							
							
								
								
									
										148
									
								
								sbin/postfwd
									
										
									
									
									
								
							
							
						
						
									
										148
									
								
								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
 | 
				
			||||||
			$val .= '/32' unless ($val =~ /\/\d{1,2}$/);
 | 
								$myresult = ($val eq '0.0.0.0/0');
 | 
				
			||||||
			$myresult = cidr_match((cidr_parse($val)),$myitem);
 | 
								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}$/);
 | 
				
			||||||
 | 
										$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,31 +1859,35 @@ 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});
 | 
					 | 
				
			||||||
		last RATES if $ratehit;
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
						$ratehit = ($Rates{$checkval}{count} > $Rates{$checkval}{maxcount}) ? $checkval : undef;
 | 
				
			||||||
 | 
						last RATES if $ratehit;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Request cache enabled?
 | 
					    # Request cache enabled?
 | 
				
			||||||
| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue