Imported Upstream version 1.14
This commit is contained in:
parent
b5012c41b3
commit
2357dc9ae5
|
@ -36,22 +36,10 @@ case "$1" in
|
||||||
${PFWCMD} ${PFWARG} -vv --daemon --file=${PFWCFG} --interface=${PFWINET} --port=${PFWPORT} --user=${PFWUSER} --group=${PFWGROUP} --pidfile=${PFWPID};
|
${PFWCMD} ${PFWARG} -vv --daemon --file=${PFWCFG} --interface=${PFWINET} --port=${PFWPORT} --user=${PFWUSER} --group=${PFWGROUP} --pidfile=${PFWPID};
|
||||||
;;
|
;;
|
||||||
|
|
||||||
stop*) if [ -f "${PFWPID}" ]; then
|
stop*) ${PFWCMD} --interface=${PFWINET} --port=${PFWPORT} --pidfile=${PFWPID} --kill;
|
||||||
echo "Stopping ${P1}...";
|
|
||||||
kill `cat ${PFWPID}`;
|
|
||||||
else
|
|
||||||
echo "Pidfile \"${PFWPID}\" not found" ;
|
|
||||||
false;
|
|
||||||
fi ;
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
reload*) if [ -f "${PFWPID}" ]; then
|
reload*) ${PFWCMD} --interface=${PFWINET} --port=${PFWPORT} --pidfile=${PFWPID} -- reload;
|
||||||
echo "Stopping ${P1}...";
|
|
||||||
kill -HUP `cat ${PFWPID}`;
|
|
||||||
else
|
|
||||||
echo "Pidfile \"${PFWPID}\" not found" ;
|
|
||||||
false;
|
|
||||||
fi ;
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
restart*) $0 stop;
|
restart*) $0 stop;
|
||||||
|
@ -60,7 +48,7 @@ case "$1" in
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*) echo "Unknown argument \"$1\"" >&2;
|
*) echo "Unknown argument \"$1\"" >&2;
|
||||||
echo "Usage: `basename $0` {start|stop|reload|restart}" >&2;
|
echo "Usage: `basename $0` {start|stop|debug|reload|restart}" >&2;
|
||||||
exit 1;;
|
exit 1;;
|
||||||
esac
|
esac
|
||||||
exit $?
|
exit $?
|
||||||
|
|
|
@ -1,3 +1,57 @@
|
||||||
|
1.14
|
||||||
|
=====
|
||||||
|
- 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 option
|
||||||
|
- 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 postfwd versions 1.12 - 1.13
|
||||||
|
- bugfix: negated pcre items with '~=' operator were parsed incorrectly.
|
||||||
|
this bug affects postfwd version 1.13
|
||||||
|
|
||||||
|
1.13
|
||||||
|
=====
|
||||||
|
- feature: enabled dns cache for sender(ns|mx) and helo address
|
||||||
|
- feature: new options --dns_max_ns_lookups and --dns_max_mx_lookups
|
||||||
|
- bugfix: workaround: Net::Server died if a unix domain socket
|
||||||
|
filename without a dot ('.') was used (B. Frauendienst)
|
||||||
|
|
||||||
|
1.12
|
||||||
|
=====
|
||||||
|
- 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: added --proto switch, to enable the use of unix domain sockets
|
||||||
|
(thanks to Bernhard Frauendienst)
|
||||||
|
- feature: added command-line options --kill and --reload
|
||||||
|
(of course you can still use TERM and HUP signals)
|
||||||
|
- 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: small performance improvement (5-10%) for pcre (~= or =~) items
|
||||||
|
- bugfix: network 0.0.0.0/0 did not work as expected on all platforms
|
||||||
|
- bugfix: postfwd tried to chop() an uninitialized value when sending
|
||||||
|
garbage (non policy delegation protocol requests) to it.
|
||||||
|
|
||||||
|
1.11
|
||||||
|
=====
|
||||||
|
- 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: new options --noidlestats and --norulelog
|
||||||
|
- feature: more informative --version
|
||||||
|
- feature: documentation updates
|
||||||
|
|
||||||
|
|
||||||
**************************************************************************************************
|
**************************************************************************************************
|
||||||
|
@ -6,7 +60,6 @@ ATTENTION: requirements changed - postfwd since v1.10pre8 now uses Net::DNS.
|
||||||
NOTE: please see the docs ('postfwd -m' or 'perldoc postfwd') for more information
|
NOTE: please see the docs ('postfwd -m' or 'perldoc postfwd') for more information
|
||||||
**************************************************************************************************
|
**************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
1.10pre8b
|
1.10pre8b
|
||||||
==========
|
==========
|
||||||
- bugfix: fixed two warnings about logging of undefined values in verbose mode
|
- bugfix: fixed two warnings about logging of undefined values in verbose mode
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
<?xml version="1.0" ?>
|
||||||
<html>
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<title>postfwd - postfix firewall daemon</title>
|
<title>postfwd - postfix firewall daemon</title>
|
||||||
<link rel="stylesheet" type="text/css" href="http://www.jpkessler.de/css/postfwd.css">
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
|
<link rev="made" href="mailto:feedback@suse.de" />
|
||||||
<meta name="description" content="postfwd a postfix firewall policy daemon">
|
|
||||||
<meta name="author" content="jpk">
|
|
||||||
<meta name="keywords" content="postfwd, postfwd usage, postfwd manual, postfix, policy, policy delegation, firewall, postfix acl, postfix acls, pfwpolicy, postfw, restrictions, IT-Security, IT-Consulting, Jan, Peter, Kessler">
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body style="background-color: white">
|
||||||
|
|
||||||
<p><a name="__index__"></a></p>
|
<p><a name="__index__"></a></p>
|
||||||
<!-- INDEX BEGIN -->
|
<!-- INDEX BEGIN -->
|
||||||
|
@ -64,6 +62,7 @@
|
||||||
-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>
|
||||||
-p, --port <port> listen on port <port>
|
-p, --port <port> listen on port <port>
|
||||||
|
--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>
|
||||||
-R, --chroot <path> chroot the daemon to <path>
|
-R, --chroot <path> chroot the daemon to <path>
|
||||||
|
@ -87,12 +86,17 @@
|
||||||
-t, --test testing, always returns "dunno"
|
-t, --test testing, always returns "dunno"
|
||||||
-v, --verbose verbose logging, use twice (-vv) to increase level
|
-v, --verbose verbose logging, use twice (-vv) to increase level
|
||||||
-S, --summary <int> show some usage statistics every <int> seconds
|
-S, --summary <int> show some usage statistics every <int> seconds
|
||||||
--no-rulestats disables per rule statistics
|
--norulelog disbles rule logging
|
||||||
|
--norulestats disables per rule statistics
|
||||||
|
--noidlestats disables statistics when idle
|
||||||
-n, --nodns disable dns
|
-n, --nodns disable dns
|
||||||
--nodnslog disable dns logging
|
--nodnslog disable dns logging
|
||||||
|
--dns_async_txt perform dnsbl A and TXT lookups simultaneously
|
||||||
--dns_timeout timeout in seconds for asynchonous dns queries
|
--dns_timeout timeout in seconds for asynchonous dns queries
|
||||||
--dns_timeout_max maximum of dns timeouts until a dnsbl will be deactivated
|
--dns_timeout_max maximum of dns timeouts until a dnsbl will be deactivated
|
||||||
--dns_timeout_interval interval in seconds for dns timeout maximum counter
|
--dns_timeout_interval interval in seconds for dns timeout maximum counter
|
||||||
|
--dns_max_ns_lookups max names to look up with sender_ns_addrs
|
||||||
|
--dns_max_mx_lookups max names to look up with sender_mx_addrs
|
||||||
-I, --instantcfg re-reads rulefiles for every new request</pre>
|
-I, --instantcfg re-reads rulefiles for every new request</pre>
|
||||||
<pre>
|
<pre>
|
||||||
Informational (use only at command-line!):
|
Informational (use only at command-line!):
|
||||||
|
@ -207,6 +211,15 @@ arguments. Please see the COMMAND LINE section below for more information on thi
|
||||||
<pre>
|
<pre>
|
||||||
recipient_localpart, - the local-/domainpart of the recipient address
|
recipient_localpart, - the local-/domainpart of the recipient address
|
||||||
recipient_domain</pre>
|
recipient_domain</pre>
|
||||||
|
<pre>
|
||||||
|
helo_address - postfwd tries to look up the helo_name. use
|
||||||
|
helo_address=!!(0.0.0.0/0) to check for unknown.</pre>
|
||||||
|
<pre>
|
||||||
|
sender_ns_names, - postfwd tries to look up the names/ip addresses
|
||||||
|
sender_ns_addrs of the nameservers for the sender domain part.</pre>
|
||||||
|
<pre>
|
||||||
|
sender_mx_names, - postfwd tries to look up the names/ip addresses
|
||||||
|
sender_mx_addrs of the mx records for the sender domain part.</pre>
|
||||||
<pre>
|
<pre>
|
||||||
version - postfwd version, contains "postfwd n.nn"
|
version - postfwd version, contains "postfwd n.nn"
|
||||||
this enables version based checks in your rulesets
|
this enables version based checks in your rulesets
|
||||||
|
@ -230,6 +243,11 @@ for details:</p>
|
||||||
score=5.0 mask = maximum floating point value
|
score=5.0 mask = maximum floating point value
|
||||||
rbl=zen.spamhaus.org mask = <name>/<reply>/<maxcache>[,...]
|
rbl=zen.spamhaus.org mask = <name>/<reply>/<maxcache>[,...]
|
||||||
rblcount=2 mask = numeric, will match if rbl hits >= 2
|
rblcount=2 mask = numeric, will match if rbl hits >= 2
|
||||||
|
helo_address=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
|
sender_ns_names=some.domain.tld mask = PCRE
|
||||||
|
sender_mx_names=some.domain.tld mask = PCRE
|
||||||
|
sender_ns_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
|
sender_mx_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Postfix version 2.1 and later:
|
# Postfix version 2.1 and later:
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
@ -352,6 +370,16 @@ rule containing only an action statement:</p>
|
||||||
# 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>
|
||||||
|
ask (<addr>:<port>[:<ignore>])
|
||||||
|
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
||||||
|
and the second argument (address and port) are mandatory. a third optional argument may be
|
||||||
|
specified to tell postfwd to ignore certain answers and go on parsing the ruleset:
|
||||||
|
# example1: query postgrey and return it's answer to postfix
|
||||||
|
id=GREY; client_address==10.1.1.1; ask(127.0.0.1:10031)
|
||||||
|
# example2: query postgrey but ignore it's answer, if it matches 'DUNNO'
|
||||||
|
# and continue parsing postfwd's ruleset
|
||||||
|
id=GREY; client_address==10.1.1.1; ask(127.0.0.1:10031:^dunno$)</pre>
|
||||||
<pre>
|
<pre>
|
||||||
wait (<delay>)
|
wait (<delay>)
|
||||||
pauses the program execution for <delay> seconds. use this for
|
pauses the program execution for <delay> seconds. use this for
|
||||||
|
@ -476,6 +504,11 @@ The following arguments will control it's behaviour in this case.</p>
|
||||||
<pre>
|
<pre>
|
||||||
-p, --port <port>
|
-p, --port <port>
|
||||||
postfwd listens on the specified port (default tcp/10040).</pre>
|
postfwd listens on the specified port (default tcp/10040).</pre>
|
||||||
|
<pre>
|
||||||
|
--proto <type>
|
||||||
|
The protocol type for postfwd's socket. Currently you may use 'tcp' or 'unix' here.
|
||||||
|
To use postfwd with a unix domain socket, run it as follows:
|
||||||
|
postfwd --proto=unix --port=/somewhere/postfwd.socket</pre>
|
||||||
<pre>
|
<pre>
|
||||||
-u, --user <name>
|
-u, --user <name>
|
||||||
Changes real and effective user to <name>.</pre>
|
Changes real and effective user to <name>.</pre>
|
||||||
|
@ -599,6 +632,17 @@ The following arguments will control it's behaviour in this case.</p>
|
||||||
--dns_timeout_interval (default=1200)
|
--dns_timeout_interval (default=1200)
|
||||||
The dnsbl timeout counter will be cleaned after this interval in seconds. Use this
|
The dnsbl timeout counter will be cleaned after this interval in seconds. Use this
|
||||||
in conjunction with the --dns_timeout_max parameter.</pre>
|
in conjunction with the --dns_timeout_max parameter.</pre>
|
||||||
|
<pre>
|
||||||
|
--dns_async_txt
|
||||||
|
Perform dnsbl A and TXT lookups simultaneously (otherwise only for listings with at
|
||||||
|
least one A record). This needs more network bandwidth due to increased queries but
|
||||||
|
might increase throughput because the lookups can be parallelized.</pre>
|
||||||
|
<pre>
|
||||||
|
--dns_max_ns_lookups (default=0)
|
||||||
|
maximum ns names to lookup up with sender_ns_addrs item. use 0 for no maximum.</pre>
|
||||||
|
<pre>
|
||||||
|
--dns_max_mx_lookups (default=0)
|
||||||
|
maximum mx names to lookup up with sender_mx_addrs item. use 0 for no maximum.</pre>
|
||||||
<pre>
|
<pre>
|
||||||
-I, --instantcfg
|
-I, --instantcfg
|
||||||
The config files, specified by -f will be re-read for every request
|
The config files, specified by -f will be re-read for every request
|
||||||
|
@ -854,7 +898,7 @@ The parser stops rule processing and returns the action to postfix. Other rules
|
||||||
The parser evaluates the given action and continues with the next rule (except for the <code>jump()</code> or <code>quit()</code> actions - please see the <a href="#actions">ACTIONS</a> section
|
The parser evaluates the given action and continues with the next rule (except for the <code>jump()</code> or <code>quit()</code> actions - please see the <a href="#actions">ACTIONS</a> section
|
||||||
for more information). Nothing will be sent to postfix.</p>
|
for more information). Nothing will be sent to postfix.</p>
|
||||||
<p>If no rule has matched and the end of the ruleset is reached postfwd will return dunno without logging anything unless in verbose mode. You may
|
<p>If no rule has matched and the end of the ruleset is reached postfwd will return dunno without logging anything unless in verbose mode. You may
|
||||||
simply place a last `catch-all´ rule to change that behaviour:</p>
|
simply place a last `catch-all´ rule to change that behaviour:</p>
|
||||||
<pre>
|
<pre>
|
||||||
... <your rules> ...
|
... <your rules> ...
|
||||||
id=DEFAULT ; action=dunno</pre>
|
id=DEFAULT ; action=dunno</pre>
|
||||||
|
@ -996,17 +1040,8 @@ POSSIBILITY OF SUCH DAMAGE.</p>
|
||||||
</p>
|
</p>
|
||||||
<hr />
|
<hr />
|
||||||
<h1><a name="author">AUTHOR</a></h1>
|
<h1><a name="author">AUTHOR</a></h1>
|
||||||
<p>Jan Peter Kessler <info (AT) postfwd (DOT) org>. Let me know, if you have any suggestions.</p>
|
<p>Jan Peter Kessler <info (AT) postfwd (DOT) org>. Let me know, if you have any suggestions.</p>
|
||||||
|
|
||||||
<p><center>
|
|
||||||
<table border="1" color="black" frame="hsides" rules="none" width="100%">
|
|
||||||
<td width="33%" align="left"><small>http://www.postfwd.org/doc.html</small>
|
|
||||||
<td width="34%" align="center"><small>2007 by <a href="http://www.jpkessler.de/">Jan Peter Kessler</a></small>
|
|
||||||
<td width="33%" align="right"><small>info (AT) postfwd (DOT) org</small>
|
|
||||||
</table>
|
|
||||||
</center></p>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ SYNOPSIS
|
||||||
-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>
|
||||||
-p, --port <port> listen on port <port>
|
-p, --port <port> listen on port <port>
|
||||||
|
--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>
|
||||||
-R, --chroot <path> chroot the daemon to <path>
|
-R, --chroot <path> chroot the daemon to <path>
|
||||||
|
@ -38,12 +39,17 @@ SYNOPSIS
|
||||||
-t, --test testing, always returns "dunno"
|
-t, --test testing, always returns "dunno"
|
||||||
-v, --verbose verbose logging, use twice (-vv) to increase level
|
-v, --verbose verbose logging, use twice (-vv) to increase level
|
||||||
-S, --summary <int> show some usage statistics every <int> seconds
|
-S, --summary <int> show some usage statistics every <int> seconds
|
||||||
--no-rulestats disables per rule statistics
|
--norulelog disbles rule logging
|
||||||
|
--norulestats disables per rule statistics
|
||||||
|
--noidlestats disables statistics when idle
|
||||||
-n, --nodns disable dns
|
-n, --nodns disable dns
|
||||||
--nodnslog disable dns logging
|
--nodnslog disable dns logging
|
||||||
|
--dns_async_txt perform dnsbl A and TXT lookups simultaneously
|
||||||
--dns_timeout timeout in seconds for asynchonous dns queries
|
--dns_timeout timeout in seconds for asynchonous dns queries
|
||||||
--dns_timeout_max maximum of dns timeouts until a dnsbl will be deactivated
|
--dns_timeout_max maximum of dns timeouts until a dnsbl will be deactivated
|
||||||
--dns_timeout_interval interval in seconds for dns timeout maximum counter
|
--dns_timeout_interval interval in seconds for dns timeout maximum counter
|
||||||
|
--dns_max_ns_lookups max names to look up with sender_ns_addrs
|
||||||
|
--dns_max_mx_lookups max names to look up with sender_mx_addrs
|
||||||
-I, --instantcfg re-reads rulefiles for every new request
|
-I, --instantcfg re-reads rulefiles for every new request
|
||||||
|
|
||||||
Informational (use only at command-line!):
|
Informational (use only at command-line!):
|
||||||
|
@ -179,6 +185,15 @@ DESCRIPTION
|
||||||
recipient_localpart, - the local-/domainpart of the recipient address
|
recipient_localpart, - the local-/domainpart of the recipient address
|
||||||
recipient_domain
|
recipient_domain
|
||||||
|
|
||||||
|
helo_address - postfwd tries to look up the helo_name. use
|
||||||
|
helo_address=!!(0.0.0.0/0) to check for unknown.
|
||||||
|
|
||||||
|
sender_ns_names, - postfwd tries to look up the names/ip addresses
|
||||||
|
sender_ns_addrs of the nameservers for the sender domain part.
|
||||||
|
|
||||||
|
sender_mx_names, - postfwd tries to look up the names/ip addresses
|
||||||
|
sender_mx_addrs of the mx records for the sender domain part.
|
||||||
|
|
||||||
version - postfwd version, contains "postfwd n.nn"
|
version - postfwd version, contains "postfwd n.nn"
|
||||||
this enables version based checks in your rulesets
|
this enables version based checks in your rulesets
|
||||||
(e.g. for migration). works with old versions too,
|
(e.g. for migration). works with old versions too,
|
||||||
|
@ -204,6 +219,11 @@ DESCRIPTION
|
||||||
score=5.0 mask = maximum floating point value
|
score=5.0 mask = maximum floating point value
|
||||||
rbl=zen.spamhaus.org mask = <name>/<reply>/<maxcache>[,...]
|
rbl=zen.spamhaus.org mask = <name>/<reply>/<maxcache>[,...]
|
||||||
rblcount=2 mask = numeric, will match if rbl hits >= 2
|
rblcount=2 mask = numeric, will match if rbl hits >= 2
|
||||||
|
helo_address=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
|
sender_ns_names=some.domain.tld mask = PCRE
|
||||||
|
sender_mx_names=some.domain.tld mask = PCRE
|
||||||
|
sender_ns_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
|
sender_mx_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Postfix version 2.1 and later:
|
# Postfix version 2.1 and later:
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
@ -351,6 +371,16 @@ DESCRIPTION
|
||||||
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)
|
||||||
|
|
||||||
|
ask (<addr>:<port>[:<ignore>])
|
||||||
|
allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
||||||
|
and the second argument (address and port) are mandatory. a third optional argument may be
|
||||||
|
specified to tell postfwd to ignore certain answers and go on parsing the ruleset:
|
||||||
|
# example1: query postgrey and return it's answer to postfix
|
||||||
|
id=GREY; client_address==10.1.1.1; ask(127.0.0.1:10031)
|
||||||
|
# example2: query postgrey but ignore it's answer, if it matches 'DUNNO'
|
||||||
|
# and continue parsing postfwd's ruleset
|
||||||
|
id=GREY; client_address==10.1.1.1; ask(127.0.0.1:10031:^dunno$)
|
||||||
|
|
||||||
wait (<delay>)
|
wait (<delay>)
|
||||||
pauses the program execution for <delay> seconds. use this for
|
pauses the program execution for <delay> seconds. use this for
|
||||||
delaying or throtteling connections.
|
delaying or throtteling connections.
|
||||||
|
@ -492,6 +522,11 @@ DESCRIPTION
|
||||||
-p, --port <port>
|
-p, --port <port>
|
||||||
postfwd listens on the specified port (default tcp/10040).
|
postfwd listens on the specified port (default tcp/10040).
|
||||||
|
|
||||||
|
--proto <type>
|
||||||
|
The protocol type for postfwd's socket. Currently you may use 'tcp' or 'unix' here.
|
||||||
|
To use postfwd with a unix domain socket, run it as follows:
|
||||||
|
postfwd --proto=unix --port=/somewhere/postfwd.socket
|
||||||
|
|
||||||
-u, --user <name>
|
-u, --user <name>
|
||||||
Changes real and effective user to <name>.
|
Changes real and effective user to <name>.
|
||||||
|
|
||||||
|
@ -618,6 +653,17 @@ DESCRIPTION
|
||||||
The dnsbl timeout counter will be cleaned after this interval in seconds. Use this
|
The dnsbl timeout counter will be cleaned after this interval in seconds. Use this
|
||||||
in conjunction with the --dns_timeout_max parameter.
|
in conjunction with the --dns_timeout_max parameter.
|
||||||
|
|
||||||
|
--dns_async_txt
|
||||||
|
Perform dnsbl A and TXT lookups simultaneously (otherwise only for listings with at
|
||||||
|
least one A record). This needs more network bandwidth due to increased queries but
|
||||||
|
might increase throughput because the lookups can be parallelized.
|
||||||
|
|
||||||
|
--dns_max_ns_lookups (default=0)
|
||||||
|
maximum ns names to lookup up with sender_ns_addrs item. use 0 for no maximum.
|
||||||
|
|
||||||
|
--dns_max_mx_lookups (default=0)
|
||||||
|
maximum mx names to lookup up with sender_mx_addrs item. use 0 for no maximum.
|
||||||
|
|
||||||
-I, --instantcfg
|
-I, --instantcfg
|
||||||
The config files, specified by -f will be re-read for every request
|
The config files, specified by -f will be re-read for every request
|
||||||
postfwd receives. This enables on-the-fly configuration changes
|
postfwd receives. This enables on-the-fly configuration changes
|
||||||
|
@ -905,7 +951,7 @@ DESCRIPTION
|
||||||
|
|
||||||
If no rule has matched and the end of the ruleset is reached postfwd
|
If no rule has matched and the end of the ruleset is reached postfwd
|
||||||
will return dunno without logging anything unless in verbose mode. You
|
will return dunno without logging anything unless in verbose mode. You
|
||||||
may simply place a last `catch-all´ rule to change that behaviour:
|
may simply place a last `catch-all´ rule to change that behaviour:
|
||||||
|
|
||||||
... <your rules> ...
|
... <your rules> ...
|
||||||
id=DEFAULT ; action=dunno
|
id=DEFAULT ; action=dunno
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
##
|
##
|
||||||
## ATTENTION: This example configuration uses features which require at least postfwd 1.10pre6!
|
## ATTENTION: Do NOT use this configuration without your own customizations!
|
||||||
## Please see the manual ('postfwd -m') for example syntax for prior versions.
|
## Please see the manual ('postfwd -m') for more information.
|
||||||
##
|
##
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
|
@ -12,6 +12,11 @@
|
||||||
## Definitions
|
## Definitions
|
||||||
##
|
##
|
||||||
|
|
||||||
|
# Greylisting with postgrey @ 127.0.0.1:10031
|
||||||
|
&&GREYLIST { \
|
||||||
|
action=ask(127.0.0.1:10031); \
|
||||||
|
};
|
||||||
|
|
||||||
# Maintenance times
|
# Maintenance times
|
||||||
&&MAINTENANCE { \
|
&&MAINTENANCE { \
|
||||||
date=15.01.2007 - 15.01.2007 ; \
|
date=15.01.2007 - 15.01.2007 ; \
|
||||||
|
@ -124,10 +129,10 @@ id=RATE_002 ; &&DYNAMIC ; \
|
||||||
id=GREY_001 ; action=dunno ; &&STATIC
|
id=GREY_001 ; action=dunno ; &&STATIC
|
||||||
id=GREY_002 ; action=dunno ; $$client_name~=$$(sender_domain)$
|
id=GREY_002 ; action=dunno ; $$client_name~=$$(sender_domain)$
|
||||||
id=GREY_003 ; action=dunno ; HIT_dnswls>=1
|
id=GREY_003 ; action=dunno ; HIT_dnswls>=1
|
||||||
id=GREY_004 ; action=greylisting ; &&DYNAMIC
|
id=GREY_004 ; action=&&GREYLIST ; &&DYNAMIC
|
||||||
id=GREY_005 ; action=greylisting ; HIT_dnsbls>=1
|
id=GREY_005 ; action=&&GREYLIST ; HIT_dnsbls>=1
|
||||||
|
|
||||||
# Greylisting should be safe during out-of-office times
|
# Greylisting should be safe during out-of-office times
|
||||||
id=GREY_006 ; action=greylisting ; days=Sat-Sun
|
id=GREY_006 ; action=&&GREYLIST ; days=Sat-Sun
|
||||||
id=GREY_007 ; action=greylisting ; days=Mon-Fri ; time=!!06:00:00-20:00:00
|
id=GREY_007 ; action=&&GREYLIST ; days=Mon-Fri ; time=!!06:00:00-20:00:00
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
|
.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
|
||||||
.\"
|
.\"
|
||||||
.\" Standard preamble:
|
.\" Standard preamble:
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
|
@ -128,8 +128,8 @@
|
||||||
.rm #[ #] #H #V #F C
|
.rm #[ #] #H #V #F C
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "POSTFWD 8"
|
.IX Title "MANUAL1 8"
|
||||||
.TH POSTFWD 8 "2008-09-14" "perl v5.8.5" "User Contributed Perl Documentation"
|
.TH MANUAL1 8 "2009-06-27" "perl v5.8.8" "User Contributed Perl Documentation"
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
postfwd \- postfix firewall daemon
|
postfwd \- postfix firewall daemon
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
|
@ -147,11 +147,12 @@ 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 10
|
.Vb 11
|
||||||
\& 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>
|
||||||
\& -p, --port <port> listen on port <port>
|
\& -p, --port <port> listen on port <port>
|
||||||
|
\& --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>
|
||||||
\& -R, --chroot <path> chroot the daemon to <path>
|
\& -R, --chroot <path> chroot the daemon to <path>
|
||||||
|
@ -174,17 +175,22 @@ postfwd [\s-1OPTIONS\s0] [\s-1SOURCE1\s0, \s-1SOURCE2\s0, ...]
|
||||||
\& --cleanup-rates cleanup interval in seconds for rate cache
|
\& --cleanup-rates cleanup interval in seconds for rate cache
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
.Vb 11
|
.Vb 16
|
||||||
\& Optional:
|
\& Optional:
|
||||||
\& -t, --test testing, always returns "dunno"
|
\& -t, --test testing, always returns "dunno"
|
||||||
\& -v, --verbose verbose logging, use twice (-vv) to increase level
|
\& -v, --verbose verbose logging, use twice (-vv) to increase level
|
||||||
\& -S, --summary <int> show some usage statistics every <int> seconds
|
\& -S, --summary <int> show some usage statistics every <int> seconds
|
||||||
\& --no-rulestats disables per rule statistics
|
\& --norulelog disbles rule logging
|
||||||
|
\& --norulestats disables per rule statistics
|
||||||
|
\& --noidlestats disables statistics when idle
|
||||||
\& -n, --nodns disable dns
|
\& -n, --nodns disable dns
|
||||||
\& --nodnslog disable dns logging
|
\& --nodnslog disable dns logging
|
||||||
|
\& --dns_async_txt perform dnsbl A and TXT lookups simultaneously
|
||||||
\& --dns_timeout timeout in seconds for asynchonous dns queries
|
\& --dns_timeout timeout in seconds for asynchonous dns queries
|
||||||
\& --dns_timeout_max maximum of dns timeouts until a dnsbl will be deactivated
|
\& --dns_timeout_max maximum of dns timeouts until a dnsbl will be deactivated
|
||||||
\& --dns_timeout_interval interval in seconds for dns timeout maximum counter
|
\& --dns_timeout_interval interval in seconds for dns timeout maximum counter
|
||||||
|
\& --dns_max_ns_lookups max names to look up with sender_ns_addrs
|
||||||
|
\& --dns_max_mx_lookups max names to look up with sender_mx_addrs
|
||||||
\& -I, --instantcfg re-reads rulefiles for every new request
|
\& -I, --instantcfg re-reads rulefiles for every new request
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
|
@ -346,6 +352,21 @@ Rules can span multiple lines by adding a trailing backslash \*(L"\e\*(R" charac
|
||||||
\& recipient_domain
|
\& recipient_domain
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
|
.Vb 2
|
||||||
|
\& helo_address - postfwd tries to look up the helo_name. use
|
||||||
|
\& helo_address=!!(0.0.0.0/0) to check for unknown.
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
|
.Vb 2
|
||||||
|
\& sender_ns_names, - postfwd tries to look up the names/ip addresses
|
||||||
|
\& sender_ns_addrs of the nameservers for the sender domain part.
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
|
.Vb 2
|
||||||
|
\& sender_mx_names, - postfwd tries to look up the names/ip addresses
|
||||||
|
\& sender_mx_addrs of the mx records for the sender domain part.
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
.Vb 6
|
.Vb 6
|
||||||
\& version - postfwd version, contains "postfwd n.nn"
|
\& version - postfwd version, contains "postfwd n.nn"
|
||||||
\& this enables version based checks in your rulesets
|
\& this enables version based checks in your rulesets
|
||||||
|
@ -361,7 +382,7 @@ Feel free to combine them the way you need it (have a look at the \s-1EXAMPLES\s
|
||||||
Most values can be specified as regular expressions (\s-1PCRE\s0). Please see the table below
|
Most values can be specified as regular expressions (\s-1PCRE\s0). Please see the table below
|
||||||
for details:
|
for details:
|
||||||
.PP
|
.PP
|
||||||
.Vb 38
|
.Vb 43
|
||||||
\& # ==========================================================
|
\& # ==========================================================
|
||||||
\& # ITEM=VALUE TYPE
|
\& # ITEM=VALUE TYPE
|
||||||
\& # ==========================================================
|
\& # ==========================================================
|
||||||
|
@ -373,6 +394,11 @@ for details:
|
||||||
\& score=5.0 mask = maximum floating point value
|
\& score=5.0 mask = maximum floating point value
|
||||||
\& rbl=zen.spamhaus.org mask = <name>/<reply>/<maxcache>[,...]
|
\& rbl=zen.spamhaus.org mask = <name>/<reply>/<maxcache>[,...]
|
||||||
\& rblcount=2 mask = numeric, will match if rbl hits >= 2
|
\& rblcount=2 mask = numeric, will match if rbl hits >= 2
|
||||||
|
\& helo_address=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
|
\& sender_ns_names=some.domain.tld mask = PCRE
|
||||||
|
\& sender_mx_names=some.domain.tld mask = PCRE
|
||||||
|
\& sender_ns_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
|
\& sender_mx_addrs=<a.b.c.d/nn> mask = CIDR[,CIDR,...]
|
||||||
\& # ------------------------------
|
\& # ------------------------------
|
||||||
\& # Postfix version 2.1 and later:
|
\& # Postfix version 2.1 and later:
|
||||||
\& # ------------------------------
|
\& # ------------------------------
|
||||||
|
@ -536,6 +562,18 @@ postfwd actions control the behaviour of the program. Currently you can specify
|
||||||
\& 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 9
|
||||||
|
\& ask (<addr>:<port>[:<ignore>])
|
||||||
|
\& allows to delegate the policy decision to another policy service (e.g. postgrey). the first
|
||||||
|
\& and the second argument (address and port) are mandatory. a third optional argument may be
|
||||||
|
\& specified to tell postfwd to ignore certain answers and go on parsing the ruleset:
|
||||||
|
\& # example1: query postgrey and return it's answer to postfix
|
||||||
|
\& id=GREY; client_address==10.1.1.1; ask(127.0.0.1:10031)
|
||||||
|
\& # example2: query postgrey but ignore it's answer, if it matches 'DUNNO'
|
||||||
|
\& # and continue parsing postfwd's ruleset
|
||||||
|
\& id=GREY; client_address==10.1.1.1; ask(127.0.0.1:10031:^dunno$)
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
.Vb 3
|
.Vb 3
|
||||||
\& wait (<delay>)
|
\& wait (<delay>)
|
||||||
\& pauses the program execution for <delay> seconds. use this for
|
\& pauses the program execution for <delay> seconds. use this for
|
||||||
|
@ -712,6 +750,13 @@ The following arguments will control it's behaviour in this case.
|
||||||
\& postfwd listens on the specified port (default tcp/10040).
|
\& postfwd listens on the specified port (default tcp/10040).
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
|
.Vb 4
|
||||||
|
\& --proto <type>
|
||||||
|
\& The protocol type for postfwd's socket. Currently you may use 'tcp' or 'unix' here.
|
||||||
|
\& To use postfwd with a unix domain socket, run it as follows:
|
||||||
|
\& postfwd --proto=unix --port=/somewhere/postfwd.socket
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
.Vb 2
|
.Vb 2
|
||||||
\& -u, --user <name>
|
\& -u, --user <name>
|
||||||
\& Changes real and effective user to <name>.
|
\& Changes real and effective user to <name>.
|
||||||
|
@ -891,6 +936,23 @@ These parameters influence the way postfwd is working. Any of them can be combin
|
||||||
\& in conjunction with the --dns_timeout_max parameter.
|
\& in conjunction with the --dns_timeout_max parameter.
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
|
.Vb 4
|
||||||
|
\& --dns_async_txt
|
||||||
|
\& Perform dnsbl A and TXT lookups simultaneously (otherwise only for listings with at
|
||||||
|
\& least one A record). This needs more network bandwidth due to increased queries but
|
||||||
|
\& might increase throughput because the lookups can be parallelized.
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
|
.Vb 2
|
||||||
|
\& --dns_max_ns_lookups (default=0)
|
||||||
|
\& maximum ns names to lookup up with sender_ns_addrs item. use 0 for no maximum.
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
|
.Vb 2
|
||||||
|
\& --dns_max_mx_lookups (default=0)
|
||||||
|
\& maximum mx names to lookup up with sender_mx_addrs item. use 0 for no maximum.
|
||||||
|
.Ve
|
||||||
|
.PP
|
||||||
.Vb 6
|
.Vb 6
|
||||||
\& -I, --instantcfg
|
\& -I, --instantcfg
|
||||||
\& The config files, specified by -f will be re-read for every request
|
\& The config files, specified by -f will be re-read for every request
|
||||||
|
@ -1225,7 +1287,7 @@ The parser evaluates the given action and continues with the next rule (except f
|
||||||
for more information). Nothing will be sent to postfix.
|
for more information). Nothing will be sent to postfix.
|
||||||
.PP
|
.PP
|
||||||
If no rule has matched and the end of the ruleset is reached postfwd will return dunno without logging anything unless in verbose mode. You may
|
If no rule has matched and the end of the ruleset is reached postfwd will return dunno without logging anything unless in verbose mode. You may
|
||||||
simply place a last `catch\-all´ rule to change that behaviour:
|
simply place a last `catch\-all´ rule to change that behaviour:
|
||||||
.PP
|
.PP
|
||||||
.Vb 2
|
.Vb 2
|
||||||
\& ... <your rules> ...
|
\& ... <your rules> ...
|
||||||
|
|
586
sbin/postfwd
586
sbin/postfwd
File diff suppressed because it is too large
Load diff
160
tools/postfwd-client.pl
Executable file
160
tools/postfwd-client.pl
Executable file
|
@ -0,0 +1,160 @@
|
||||||
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
|
## MODULES
|
||||||
|
#use strict;
|
||||||
|
use warnings;
|
||||||
|
use IO::Socket;
|
||||||
|
use IO::Pipe;
|
||||||
|
use Getopt::Long 2.25 qw(:config no_ignore_case bundling);
|
||||||
|
BEGIN {
|
||||||
|
eval { require Time::HiRes };
|
||||||
|
if ($@) {
|
||||||
|
warn "$@";
|
||||||
|
warn "Failed to include optional module Time::HiRes.";
|
||||||
|
} else {
|
||||||
|
Time::HiRes->import( qw(time) );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
## PARAMETERS
|
||||||
|
my $syntax = "USAGE: client.pl [ OPTIONS ] <addr>:<port>";
|
||||||
|
my $sendstr = 'ccert_fingerprint=
|
||||||
|
size=64063
|
||||||
|
helo_name=english-breakfast.cloud9.net
|
||||||
|
reverse_client_name=english-breakfast.cloud9.net
|
||||||
|
queue_id=
|
||||||
|
encryption_cipher=
|
||||||
|
encryption_protocol=
|
||||||
|
etrn_domain=
|
||||||
|
ccert_subject=
|
||||||
|
request=smtpd_access_policy
|
||||||
|
protocol_state=RCPT
|
||||||
|
recipient=someone@domain.local
|
||||||
|
instance=6748.46adf3f8.62156.0
|
||||||
|
protocol_name=ESMTP
|
||||||
|
encryption_keysize=0
|
||||||
|
recipient_count=0
|
||||||
|
ccert_issuer=
|
||||||
|
sender=owner-postfix-users@postfix.org
|
||||||
|
client_name=english-breakfast.cloud9.net
|
||||||
|
client_address=168.100.1.7
|
||||||
|
|
||||||
|
';
|
||||||
|
my $delay = 0.5;
|
||||||
|
our $pipe = new IO::Pipe;
|
||||||
|
use vars qw( %options %kinder $kind $wait );
|
||||||
|
|
||||||
|
## COMMAND LINE
|
||||||
|
GetOptions( \%options,
|
||||||
|
'verbose|v+',
|
||||||
|
'quiet|q+',
|
||||||
|
'process|p=i',
|
||||||
|
'count|c=i',
|
||||||
|
'timeout|t=i',
|
||||||
|
'file|f=s',
|
||||||
|
) or die "$syntax\n";
|
||||||
|
die "$syntax\n" unless $ARGV[0];
|
||||||
|
map { $options{$_} ||= 1 } qw(count process);
|
||||||
|
$options{verbose} ||= 0;
|
||||||
|
$options{timeout} ||= 3;
|
||||||
|
if (defined $options{file}) {
|
||||||
|
(-f $options{file}) || die "can not find file '".$options{file}."'\n";
|
||||||
|
open (REQUEST, "<".$options{file}) || die "can not open file '".$options{file}."'\n";
|
||||||
|
$sendstr = join "", <REQUEST>;
|
||||||
|
close (REQUEST);
|
||||||
|
};
|
||||||
|
|
||||||
|
## FORK
|
||||||
|
$| = 1;
|
||||||
|
my $starttime = time();
|
||||||
|
FORK: for (my $i=0;$i<$options{process};$i++) {
|
||||||
|
$kind = fork();
|
||||||
|
last FORK unless $kind;
|
||||||
|
$kinder{$kind} = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
## WHO AM I?
|
||||||
|
($kind) ? parent_process() : child_process() ;
|
||||||
|
die "should never see me\n";
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
## PARENT CODE
|
||||||
|
sub parent_process {
|
||||||
|
$pipe->reader();
|
||||||
|
use POSIX ":sys_wait_h";
|
||||||
|
undef my @status;
|
||||||
|
# wait until children have finished
|
||||||
|
print ("parent process waiting for ".(scalar keys %kinder)." pids ".(join ' ', (keys %kinder))."\n") unless $options{quiet};
|
||||||
|
PARENT: do {
|
||||||
|
# check pipe for finished children
|
||||||
|
push @status, <$pipe>;
|
||||||
|
# check children
|
||||||
|
CHILD: foreach (keys %kinder) {
|
||||||
|
$wait = waitpid($_,&WNOHANG);
|
||||||
|
last CHILD unless ($wait == -1);
|
||||||
|
delete $kinder{$_};
|
||||||
|
};
|
||||||
|
# sleep a while to reduce cpu usage
|
||||||
|
select(undef, undef, undef, $delay);
|
||||||
|
print ("parent process waiting for ".(scalar keys %kinder)." pids ".(join ' ', (keys %kinder))."\n") if ($options{verbose} > 1);
|
||||||
|
} until (($wait == -1) or (($#status + 1) >= $options{process}));
|
||||||
|
printf ("parent process finished after %.2f seconds.\n", (time() - $starttime)) unless $options{quiet};
|
||||||
|
# display results
|
||||||
|
my $parent_requests = my $parent_errors = my $parent_valid = my $parent_invalid = my $parent_time = 0;
|
||||||
|
foreach (@status) {
|
||||||
|
my($child_requests,$child_errors,$child_valid,$child_invalid,$child_time) = split ';', $_;
|
||||||
|
$parent_requests += $child_requests;
|
||||||
|
$parent_errors += $child_errors;
|
||||||
|
$parent_valid += $child_valid;
|
||||||
|
$parent_invalid += $child_invalid;
|
||||||
|
$parent_time = $child_time if ($child_time > $parent_time);
|
||||||
|
};
|
||||||
|
$parent_time = $parent_time - $starttime;
|
||||||
|
my $parent_rps = ($parent_time) ? ($parent_requests / $parent_time) : 0;
|
||||||
|
printf "%d requests, %d errors, %d valid, %d invalid, %.2fs total time, %.2f requests per second\n",
|
||||||
|
$parent_requests,$parent_errors,$parent_valid,$parent_invalid,$parent_time,$parent_rps;
|
||||||
|
exit (0);
|
||||||
|
};
|
||||||
|
|
||||||
|
## CHILD CODE
|
||||||
|
sub child_process {
|
||||||
|
$pipe->writer();
|
||||||
|
my $ok = my $nok = 0;
|
||||||
|
undef my $getstr;
|
||||||
|
# open socket
|
||||||
|
my($addr,$port) = split ':', $ARGV[0];
|
||||||
|
if ( ($addr and $port) and my $socket = new IO::Socket::INET (
|
||||||
|
PeerAddr => $addr,
|
||||||
|
PeerPort => $port,
|
||||||
|
Proto => 'tcp',
|
||||||
|
Timeout => $options{timeout},
|
||||||
|
Type => SOCK_STREAM ) ) {
|
||||||
|
# submit requests
|
||||||
|
for (my $i=0; $i<$options{count}; $i++) {
|
||||||
|
printf ("CHILD-$$: asking service $addr:$port\n") if $options{verbose};
|
||||||
|
print $socket "$sendstr";
|
||||||
|
$getstr = <$socket>; <$socket>;
|
||||||
|
chomp($getstr);
|
||||||
|
printf ("CHILD-$$: answer from $addr:$port -> '$getstr'\n") if $options{verbose};
|
||||||
|
$getstr =~ s/^(action=)//;
|
||||||
|
# check answer
|
||||||
|
if ($1 and $getstr) {
|
||||||
|
$ok++;
|
||||||
|
printf ("CHILD-$$: OK: answer from $addr:$port -> '$getstr'\n") unless ( $options{quiet} or (($options{count} * $options{process}) > 50) );
|
||||||
|
} else {
|
||||||
|
$nok++;
|
||||||
|
warn ("CHILD-$$: FAIL: invalid answer from $addr:$port -> '$getstr'\n");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
warn ("CHILD-$$: can not open socket to $addr:$port\n");
|
||||||
|
};
|
||||||
|
# create summary
|
||||||
|
my $summary = $options{count}.';'.($options{count} - ($ok + $nok)).';'.$ok.';'.$nok.';'.time()."\n";
|
||||||
|
print ("CHILD-$$: child summary: $summary") if ($options{verbose} > 1);
|
||||||
|
# send summary to parent
|
||||||
|
print $pipe "$summary";
|
||||||
|
exit (0);
|
||||||
|
};
|
||||||
|
|
297
tools/rblcheck.pl
Executable file
297
tools/rblcheck.pl
Executable file
|
@ -0,0 +1,297 @@
|
||||||
|
#!/usr/bin/perl -T -w
|
||||||
|
|
||||||
|
# includes
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Getopt::Long 2.25 qw(:config no_ignore_case bundling);
|
||||||
|
use Net::DNS;
|
||||||
|
# include Time::HiRes if available
|
||||||
|
BEGIN {
|
||||||
|
eval { require Time::HiRes };
|
||||||
|
Time::HiRes->import( qw(time) ) unless $@;
|
||||||
|
};
|
||||||
|
|
||||||
|
# RBLs (ip based)
|
||||||
|
our @rbls = qw(
|
||||||
|
zz.countries.nerd.dk
|
||||||
|
query.bondedsender.org
|
||||||
|
exemptions.ahbl.org
|
||||||
|
spf.trusted-forwarder.org
|
||||||
|
list.dnswl.org
|
||||||
|
zen.spamhaus.org
|
||||||
|
b.barracudacentral.org
|
||||||
|
bl.spamcop.net
|
||||||
|
list.dsbl.org
|
||||||
|
multihop.dsbl.org
|
||||||
|
unconfirmed.dsbl.org
|
||||||
|
combined.njabl.org
|
||||||
|
dnsbl.sorbs.net
|
||||||
|
dnsbl.ahbl.org
|
||||||
|
ix.dnsbl.manitu.net
|
||||||
|
dnsbl-1.uceprotect.net
|
||||||
|
dnsbl-2.uceprotect.net
|
||||||
|
dnsbl-3.uceprotect.net
|
||||||
|
ips.backscatterer.org
|
||||||
|
sorbs.dnsbl.net.au
|
||||||
|
t1.dnsbl.net.au
|
||||||
|
korea.services.net
|
||||||
|
blackholes.five-ten-sg.com
|
||||||
|
cbl.anti-spam.org.cn
|
||||||
|
cblplus.anti-spam.org.cn
|
||||||
|
cblless.anti-spam.org.cn
|
||||||
|
bogons.cymru.com
|
||||||
|
dynamic.tqmrbl.com
|
||||||
|
relays.tqmrbl.com
|
||||||
|
clients.tqmrbl.com
|
||||||
|
hostkarma.junkemailfilter.com
|
||||||
|
sip.invaluement.com
|
||||||
|
);
|
||||||
|
|
||||||
|
# RHSBLs (domain based)
|
||||||
|
our @rhsbls = qw(
|
||||||
|
rhsbl.sorbs.net
|
||||||
|
rhsbl.ahbl.org
|
||||||
|
multi.surbl.org
|
||||||
|
dsn.rfc-ignorant.org
|
||||||
|
abuse.rfc-ignorant.org
|
||||||
|
whois.rfc-ignorant.org
|
||||||
|
bogusmx.rfc-ignorant.org
|
||||||
|
blackhole.securitysage.com
|
||||||
|
ex.dnsbl.org
|
||||||
|
rddn.dnsbl.net.au
|
||||||
|
block.rhs.mailpolice.com
|
||||||
|
dynamic.rhs.mailpolice.com
|
||||||
|
dnsbl.cyberlogic.net
|
||||||
|
hostkarma.junkemailfilter.com
|
||||||
|
);
|
||||||
|
|
||||||
|
# commandline syntax
|
||||||
|
our $syntax = <<__SYNTAX__;
|
||||||
|
Usage: rblcheck3.pl [OPTIONS] <objects>
|
||||||
|
|
||||||
|
-h, --help manual
|
||||||
|
-s, --short short output
|
||||||
|
-v, --verbose show dns nxdomain answers (not listed)
|
||||||
|
-n, --noerror do not show dns query timeouts
|
||||||
|
-t, --timeout=10 dns query timeout setting in seconds
|
||||||
|
--dnsstats show dns statistics
|
||||||
|
--rbls=<list> override builtin rbls with <list>
|
||||||
|
--rhsbls=<list> override builtin rhsbls with <list>
|
||||||
|
|
||||||
|
<objects> list of ips, hostnames and e-mail addresses
|
||||||
|
__SYNTAX__
|
||||||
|
|
||||||
|
# manual
|
||||||
|
our $examples = <<__EXAMPLES__;
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
# check builtin rbls for 192.168.0.1 and rhsbls for host.example.com
|
||||||
|
rblcheck3.pl 192.168.0.1 host.example.com
|
||||||
|
|
||||||
|
# same as above
|
||||||
|
rblcheck3.pl host.example.com[192.168.0.1]
|
||||||
|
|
||||||
|
# check builtin rhsbls for the domain part "example.com",
|
||||||
|
# set dns timeout to 15 seconds
|
||||||
|
rblcheck3.pl -t 15 john.doe\@example.com
|
||||||
|
|
||||||
|
# check spamhaus and spamcop for 192.168.0.1
|
||||||
|
# short output without dns timeout information
|
||||||
|
rblcheck3.pl -ns --rbls=zen.spamhaus.org,bl.spamcop.net 192.168.0.1
|
||||||
|
__EXAMPLES__
|
||||||
|
|
||||||
|
# save current time
|
||||||
|
our $starttime = time();
|
||||||
|
|
||||||
|
# variables
|
||||||
|
use vars qw(
|
||||||
|
%dnshits %dnscache %options
|
||||||
|
@queries @lookups @timedout
|
||||||
|
);
|
||||||
|
|
||||||
|
# parse commandline switches
|
||||||
|
GetOptions( \%options,
|
||||||
|
"timeout|t=i",
|
||||||
|
"noerror|n",
|
||||||
|
"verbose|v",
|
||||||
|
"short|s+",
|
||||||
|
"dnsstats",
|
||||||
|
"rbls|rbl=s" => sub { push @{$options{rbls}}, (split /[,\s]+/, $_[1]) },
|
||||||
|
"rhsbls|rhsbl=s" => sub { push @{$options{rhsbls}}, (split /[,\s]+/, $_[1]) },
|
||||||
|
"help|h" => sub { print "\n$syntax\n$examples\n"; exit(1) },
|
||||||
|
) or die "\n$syntax\n";
|
||||||
|
|
||||||
|
# unbuffered output
|
||||||
|
#select STDERR; $| = 1;
|
||||||
|
#select STDOUT; $| = 1;
|
||||||
|
|
||||||
|
# optional: override dnsbl lists
|
||||||
|
@rbls = @{$options{rbls}} if defined $options{rbls};
|
||||||
|
@rhsbls = @{$options{rhsbls}} if defined $options{rhsbls};
|
||||||
|
|
||||||
|
# split client[ip] in two queries
|
||||||
|
map { push @queries, (/^([^\]]+)\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]$/) ? ($1, $2) : $_ } @ARGV;
|
||||||
|
|
||||||
|
# parse queries and create lookup list
|
||||||
|
foreach my $query (@queries) {
|
||||||
|
undef my $addr;
|
||||||
|
|
||||||
|
# prepare rbls
|
||||||
|
if ($query =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
|
||||||
|
$addr = join ".", reverse split /\./, $query;
|
||||||
|
foreach my $rbl (@rbls) {
|
||||||
|
$dnscache{$addr.".".$rbl}{type} = 'RBL';
|
||||||
|
$dnscache{$addr.".".$rbl}{query} = $query;
|
||||||
|
$dnscache{$addr.".".$rbl}{list} = $rbl;
|
||||||
|
push @lookups, $addr.".".$rbl;
|
||||||
|
};
|
||||||
|
# prepare rhsbls
|
||||||
|
} else {
|
||||||
|
# remove localpart if email address
|
||||||
|
$addr = ($query =~ /@([^@]+)$/) ? $1 : $query;
|
||||||
|
foreach my $rbl (@rhsbls) {
|
||||||
|
$dnscache{$addr.".".$rbl}{type} = 'RHSBL';
|
||||||
|
$dnscache{$addr.".".$rbl}{query} = $query;
|
||||||
|
$dnscache{$addr.".".$rbl}{list} = $rbl;
|
||||||
|
push @lookups, $addr.".".$rbl;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# main: process lookups
|
||||||
|
if ( @lookups ) {
|
||||||
|
my $ownres = Net::DNS::Resolver->new;
|
||||||
|
my $ownsel = IO::Select->new;
|
||||||
|
my %ownsock = ();
|
||||||
|
my @ownready = ();
|
||||||
|
my $bgsock = undef;
|
||||||
|
|
||||||
|
# send queries
|
||||||
|
QUERY: foreach my $query (@lookups) {
|
||||||
|
next QUERY unless $query;
|
||||||
|
# send A query
|
||||||
|
$dnscache{$query}{start} = time();
|
||||||
|
$bgsock = $ownres->bgsend($query, 'A');
|
||||||
|
$ownsel->add($bgsock);
|
||||||
|
$ownsock{$bgsock} = 'A:'.$query;
|
||||||
|
# send TXT query
|
||||||
|
$bgsock = $ownres->bgsend($query, 'TXT');
|
||||||
|
$ownsel->add($bgsock);
|
||||||
|
$ownsock{$bgsock} = 'TXT:'.$query;
|
||||||
|
};
|
||||||
|
|
||||||
|
# get answers
|
||||||
|
while ((scalar keys %ownsock) and (@ownready = $ownsel->can_read($options{timeout} || 10))) {
|
||||||
|
foreach my $sock (@ownready) {
|
||||||
|
if (defined $ownsock{$sock}) {
|
||||||
|
my $packet = $ownres->bgread($sock);
|
||||||
|
rbl_read_dns ($packet);
|
||||||
|
delete $ownsock{$sock};
|
||||||
|
} else {
|
||||||
|
$ownsel->remove($sock);
|
||||||
|
$sock = undef;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# timeout handling
|
||||||
|
my $now = time();
|
||||||
|
map { push @timedout, (split ':', $ownsock{$_})[1] } (keys %ownsock);
|
||||||
|
map { @{$dnscache{$_}{A}} = '**timeout**'; $dnscache{$_}{end} = $now; delete $dnscache{$_}{log} } (sort @timedout) if @timedout;
|
||||||
|
|
||||||
|
# print results
|
||||||
|
map { # timeout
|
||||||
|
unless (defined $dnscache{$_}{log}) {
|
||||||
|
$dnshits{timeouts}{$dnscache{$_}{list}}++;
|
||||||
|
show_dns ($_) unless $options{noerror};
|
||||||
|
# a-record
|
||||||
|
} elsif ($dnscache{$_}{log}) {
|
||||||
|
$dnshits{hits}{$dnscache{$_}{list}}++;
|
||||||
|
show_dns ($_);
|
||||||
|
# nxdomain
|
||||||
|
} else {
|
||||||
|
$dnshits{nxdomain}{$dnscache{$_}{list}}++;
|
||||||
|
show_dns ($_) if $options{verbose};
|
||||||
|
};
|
||||||
|
} @lookups;
|
||||||
|
printf STDOUT "\n # Finished %d lookups (%d items, %d rbls, %d rhsbls, %.1f%% timeouts) after %.2f seconds\n",
|
||||||
|
($#lookups + 1),
|
||||||
|
($#queries + 1),
|
||||||
|
($#rbls + 1), ($#rhsbls + 1),
|
||||||
|
(($#timedout + 1) / (($#lookups + 1) * 2)) * 100,
|
||||||
|
(time() - $starttime) unless defined $options{short};
|
||||||
|
if ($options{verbose} or $options{dnsstats}) {
|
||||||
|
printf "\n # DNS statistics\n";
|
||||||
|
if (defined $dnshits{hits}) {
|
||||||
|
print " #\n";
|
||||||
|
map { printf STDOUT " # ".$dnshits{hits}{$_}." hits for $_\n" } (sort {($dnshits{hits}{$b} || 0) <=> ($dnshits{hits}{$a} || 0)} keys %{$dnshits{hits}});
|
||||||
|
};
|
||||||
|
if (defined $dnshits{timeouts}) {
|
||||||
|
print " #\n";
|
||||||
|
map { printf STDOUT " # ".$dnshits{timeouts}{$_}." timeouts for $_\n" } (sort {($dnshits{timeouts}{$b} || 0) <=> ($dnshits{timeouts}{$a} || 0)} keys %{$dnshits{timeouts}});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
print "\n";
|
||||||
|
};
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
# prints DNS result
|
||||||
|
sub show_dns {
|
||||||
|
my $que = shift;
|
||||||
|
my $out = "";
|
||||||
|
if (defined $options{short}) {
|
||||||
|
$out .= $dnscache{$que}{query}
|
||||||
|
."; ".$dnscache{$que}{list}
|
||||||
|
."; ".(join ', ', @{$dnscache{$que}{A}});
|
||||||
|
$out .= "; ".(join '. ', @{$dnscache{$que}{TXT}}) if defined $dnscache{$que}{TXT} and ($options{verbose} or ($options{short} < 2));
|
||||||
|
} else {
|
||||||
|
$out .= "\n ".sprintf ("%15s", $dnscache{$que}{query})." ".$dnscache{$que}{type}.": ".$dnscache{$que}{list};
|
||||||
|
$out .= " (cname: ".(join ', ', (keys %{$dnscache{$que}{CNAME}})).")" if defined $dnscache{$que}{CNAME};
|
||||||
|
$out .= "\n ".sprintf ("%15s", $dnscache{$que}{query})." ".(join ', ', @{$dnscache{$que}{A}});
|
||||||
|
$out .= " (time: ".sprintf ("%.1fs)", ($dnscache{$que}{end} - $dnscache{$que}{start}));
|
||||||
|
$out .= " (ttl: ".$dnscache{$que}{ttl}."s)" if defined $dnscache{$que}{ttl};
|
||||||
|
$out .= "\n ".sprintf ("%15s", $dnscache{$que}{query})." ".(join '. ', @{$dnscache{$que}{TXT}}) if defined $dnscache{$que}{TXT};
|
||||||
|
};
|
||||||
|
print STDOUT "$out\n";
|
||||||
|
};
|
||||||
|
|
||||||
|
# reads DNS answer
|
||||||
|
sub rbl_read_dns {
|
||||||
|
my($myresult) = shift;
|
||||||
|
my($now) = time();
|
||||||
|
my($que,$typ) = undef;
|
||||||
|
|
||||||
|
if ( defined $myresult ) {
|
||||||
|
# read question, for dns cache id
|
||||||
|
foreach ($myresult->question) {
|
||||||
|
$typ = ($_->qtype || '') unless $typ;
|
||||||
|
$que = ($_->qname || '') unless $que;
|
||||||
|
};
|
||||||
|
# not listed
|
||||||
|
unless ($myresult->answer) {
|
||||||
|
@{$dnscache{$que}{A}} = '<nxdomain>';
|
||||||
|
$dnscache{$que}{end} = $now;
|
||||||
|
$dnscache{$que}{log} = 0;
|
||||||
|
# parse answers
|
||||||
|
} else {
|
||||||
|
foreach ($myresult->answer) {
|
||||||
|
if ($_->type =~ /^(A|CNAME|TXT)$/) {
|
||||||
|
if ($_->type eq 'A') {
|
||||||
|
push @{$dnscache{$que}{A}}, ($_->address || '');
|
||||||
|
} elsif ($_->type eq 'TXT') {
|
||||||
|
my $res = (join(' ', $_->char_str_list()) || '');
|
||||||
|
push @{$dnscache{$que}{TXT}}, $res if $res;
|
||||||
|
} elsif ($_->type eq 'CNAME') {
|
||||||
|
$dnscache{$que}{CNAME}{$_->cname} = 1 if $_->cname;
|
||||||
|
};
|
||||||
|
$dnscache{$que}{ttl} = ($_->ttl || 0) unless defined $dnscache{$que}{ttl};
|
||||||
|
$dnscache{$que}{end} = $now;
|
||||||
|
$dnscache{$que}{log} = 1;
|
||||||
|
} else {
|
||||||
|
print STDERR "IGNORING query: $que, TYPE: '".($_->type || '')."'\n";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue