First cut of new action logging implementation

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@1500 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2004-07-28 02:36:40 +00:00
parent 24981b9624
commit bd6192dc18
4 changed files with 284 additions and 64 deletions

View File

@ -7,9 +7,6 @@
# dropBcast #Silently Drop Broadcast/multicast # dropBcast #Silently Drop Broadcast/multicast
# dropNonSyn #Silently Drop Non-syn TCP packets # dropNonSyn #Silently Drop Non-syn TCP packets
# rejNonSyn #Silently Reject Non-syn TCP packets # rejNonSyn #Silently Reject Non-syn TCP packets
# logNonSyn #Log Non-syn TCP packets with disposition LOG
# dLogNonSyn #Log Non-syn TCP packets with disposition DROP
# rLogNonSyn #Log Non-syn TCP packets with disposition REJECT
# dropInvalid #Silently Drop packets that are in the INVALID # dropInvalid #Silently Drop packets that are in the INVALID
# #conntrack state. # #conntrack state.
# #

View File

@ -2709,6 +2709,15 @@ process_action() # $1 = action
expandv logtag expandv logtag
fi fi
case $loglevel in
none*)
loglevel=
logtag=
[ $target = LOG ] && return
;;
esac
loglevel=${loglevel%\!}
fi fi
logtarget="$target" logtarget="$target"
@ -2776,17 +2785,10 @@ process_action() # $1 = action
} }
# #
# Create an action chain and run it's associated user exit # Create and record a log action chain
# #
createactionchain() # $1 = chain name createlogactionchain() # $1 = Action Name, $2 = Log Level [: Log Tag ]
{
createchain $1 no
CHAIN=$1
run_user_exit $CHAIN
}
createlogactionchain() # $1 = Action Name, $2 = Log Level
{ {
local actchain= action=$1 level=$2 local actchain= action=$1 level=$2
@ -2799,22 +2801,63 @@ createlogactionchain() # $1 = Action Name, $2 = Log Level
CHAIN=$(echo $action | cut -b -10)${actchain} CHAIN=$(echo $action | cut -b -10)${actchain}
;; ;;
*) *)
chain=${action}${actchain} CHAIN=${action}${actchain}
;; ;;
esac esac
eval ${chain}_actchain=$(($actchain + 1)) eval ${action}_actchain=$(($actchain + 1))
createchain $CHAIN if [ $COMMAND != check ]; then
run_user_exit $1 createchain $CHAIN No
run_user_exit $1
fi
eval ${action}_chains=\"\$${action}_chains $2 $CHAIN\" eval ${action}_chains=\"\$${action}_chains $level $CHAIN\"
} }
find_logactionchain() # $1 = Action Name, $2 = Log Level #
# Create an action chain and run it's associated user exit
#
createactionchain() # $1 = Action, including log level and tag if any
{ {
local action=$1 level=$2 chains= case $1 in
*:*:*)
set -- $(split $1)
createlogactionchain $1 $2:$3
;;
*:*)
set -- $(split $1)
createlogactionchain $1 $2
;;
*)
CHAIN=$1
if [ $COMMAND != check ]; then
createchain $CHAIN no
run_user_exit $CHAIN
fi
;;
esac
}
find_logactionchain() # $1 = Action, including log level and tag if any
{
local fullaction=$1 action=${1%%:*} level= chains=
case $fullaction in
*:*)
level=${fullaction#*:}
;;
*)
if [ $COMMAND != check ]; then
havechain $action || createactionchain $action
fi
echo $action
return
;;
esac
eval chains="\$${action}_chains" eval chains="\$${action}_chains"
@ -2825,12 +2868,74 @@ find_logactionchain() # $1 = Action Name, $2 = Log Level
shift;shift shift;shift
done done
createlogactionchain $action $level createlogctionchain $action $level
echo $CHAIN echo $CHAIN
} }
evaluate_levels() # $1=level at which superior action is called, $2=level at which the subordinate rule is called
{
local superior=$1 subordinate=$2
set -- $(split $1)
case $superior in
*:*:*)
case $2 in
'none!')
echo ${subordinate%%:*}:'none!'
return
;;
*'!')
echo ${subordinate%%:*}:$2:$3
return
;;
*)
case $subordinate in
*:*)
echo $subordinate
return
;;
*)
echo ${subordinate%%:*}:$2:$3
return
;;
esac
;;
esac
;;
*:*)
case $2 in
'none!')
echo ${subordinate%%:*}:'none!'
return
;;
*'!')
echo ${subordinate%%:*}:$2
return
;;
*)
case $subordinate in
*:*)
echo $subordinate
return
;;
*)
echo ${subordinate%%:*}:$2
return
;;
esac
;;
esac
;;
*)
echo $subordinate
;;
esac
}
# #
# Read /etc/shorewall/actions and /usr/share/shorewall/actions.std and for each defined <action>, pre-process # Read /etc/shorewall/actions and /usr/share/shorewall/actions.std and for each defined <action>, pre-process
# /etc/shorewall/action.<action> # /etc/shorewall/action.<action>
@ -2838,7 +2943,7 @@ find_logactionchain() # $1 = Action Name, $2 = Log Level
process_actions1() { process_actions1() {
ACTIONS="dropBcast dropNonSyn dropNotSyn rejNotSyn logNotSyn rLogNotSyn dLogNotSyn dropInvalid" ACTIONS="dropBcast dropNonSyn dropNotSyn rejNotSyn dropInvalid"
USEDACTIONS= USEDACTIONS=
strip_file actions strip_file actions
@ -2883,12 +2988,12 @@ process_actions1() {
while read xtarget xclients xservers xprotocol xports xcports xratelimit $xuserspec; do while read xtarget xclients xservers xprotocol xports xcports xratelimit $xuserspec; do
expandv xtarget expandv xtarget
temp="${xtarget%%:*}" temp="${xtarget%%:*}"
case "${temp%<*}" in case "$temp" in
ACCEPT|DROP|REJECT|LOG|QUEUE|CONTINUE) ACCEPT|DROP|REJECT|LOG|QUEUE|CONTINUE)
;; ;;
*) *)
if list_search $temp $ACTIONS; then if list_search $temp $ACTIONS; then
eval requiredby_${xaction}=\"\$requiredby_${xaction} $temp\" eval requiredby_${xaction}=\"\$requiredby_${xaction} $xtarget\"
else else
rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec)" rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec)"
fatal_error "Invalid TARGET in rule \"$rule\"" fatal_error "Invalid TARGET in rule \"$rule\""
@ -2952,13 +3057,18 @@ process_actions2() {
process_action $xaction $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec process_action $xaction $xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec
} }
log_action() {
[ "$COMMAND" != check ] && log_rule ${LOGNEWNOTSYN:-info} $1 $2 "" "" -p tcp ! --syn
}
drop_broadcasts() { drop_broadcasts() {
for address in $(find_broadcasts) 255.255.255.255 224.0.0.0/4 ; do for address in $(find_broadcasts) 255.255.255.255 224.0.0.0/4 ; do
run_iptables -A dropBcast -d $address -j DROP case $xlevel in
none\!)
;;
*)
[ -n "$xlevel" ] && \
log_rule_limit ${xlevel%\!} $xchain dropBcast $2 "" "$xtag" -d $address
;;
esac
run_iptables -A $xchain -d $address -j DROP
done done
} }
@ -2970,11 +3080,13 @@ process_actions2() {
while [ -n "$changed" ]; do while [ -n "$changed" ]; do
changed= changed=
for xaction in $USEDACTIONS; do for xaction in $USEDACTIONS; do
eval required=\"\$requiredby_${xaction}\"
eval required=\"\$requiredby_${xaction#*:}\"
for action in $required; do for action in $required; do
if ! list_search $action $USEDACTIONS; then if ! list_search $action $USEDACTIONS; then
USEDACTIONS="$USEDACTIONS $action" USEDACTIONS="$USEDACTIONS $action"
[ $COMMAND = check ] || createactionchain $action createactionchain $action
changed=Yes changed=Yes
fi fi
done done
@ -2984,51 +3096,76 @@ process_actions2() {
# Now process the relevant action files -- they were already stripped in process_actions1() above. # Now process the relevant action files -- they were already stripped in process_actions1() above.
# #
for xaction in $USEDACTIONS; do for xaction in $USEDACTIONS; do
case $xaction in xchain=$(find_logactionchain $xaction)
set -- $(split $xaction)
xlevel=$2
xtag=$3
case ${xaction%%:*} in
dropBcast) dropBcast)
if [ "$COMMAND" != check ]; then if [ "$COMMAND" != check ]; then
if [ -n "$PKTTYPE" ]; then if [ -n "$PKTTYPE" ]; then
qt iptables -A dropBcast -m pkttype --pkt-type broadcast -j DROP case $xlevel in
if ! qt iptables -A dropBcast -m pkttype --pkt-type multicast -j DROP; then none'!')
# ;;
# No pkttype support -- do it the hard way *)
# if [ -n "$xlevel" ]; then
drop_broadcasts log_rule_limit ${xlevel%\!} $xchain dropBcast $2 "" "$xtag" -m pkttype --pkt-type broadcast
fi log_rule_limit ${xlevel%\!} $xchain dropBcast $2 "" "$xtag" -m pkttype --pkt-type multicast
else fi
drop_broadcasts ;;
esac
run_iptables -A dropBcast -m pkttype --pkt-type broadcast -j DROP
run_iptables -A dropBcast -m pkttype --pkt-type multicast -j DROP
fi fi
else
drop_broadcasts
fi fi
;; ;;
dropNonSyn) dropNonSyn)
error_message "WARNING: \"dropNonSyn\" has been replaced by \"dropNotSyn\"" error_message "WARNING: \"dropNonSyn\" has been replaced by \"dropNotSyn\""
[ "$COMMAND" != check ] && run_iptables -A dropNonSyn -p tcp ! --syn -j DROP
if [ "$COMMAND" != check ]; then
[ -n "$xlevel" ] && \
log_rule_limit ${xlevel%\!} $xchain dropBcast $2 "" "$xtag" -p tcp ! -- syn
run_iptables -A $xchain -p tcp ! --syn -j DROP
fi
;; ;;
dropNotSyn) dropNotSyn)
[ "$COMMAND" != check ] && run_iptables -A dropNotSyn -p tcp ! --syn -j DROP if [ "$COMMAND" != check ]; then
[ -n "$xlevel" ] && \
log_rule_limit ${xlevel%\!} $xchain dropNotSyn $2 "" "$xtag" -p tcp ! -- syn
run_iptables -A dropNotSyn -p tcp ! --syn -j DROP
fi
;; ;;
rejNotSyn) rejNotSyn)
[ "$COMMAND" != check ] && run_iptables -A rejectNotSyn -p tcp ! --syn -j REJECT --reject-with tcp-reset if [ "$COMMAND" != check ]; then
;; [ -n "$xlevel" ] && \
logNotSyn) log_rule_limit ${xlevel%\!} $xchain rejNotSyn $2 "" "$xtag" -p tcp ! -- syn
log_action logNotSyn LOG run_iptables -A rejectNotSyn -p tcp ! --syn -j REJECT --reject-with tcp-reset
;; fi
rLogNotSyn)
log_action rLogNotSyn REJECT
;;
dLogNotSyn)
log_action dLogNotSyn DROP
;; ;;
dropInvalid) dropInvalid)
[ "$COMMAND" != check ] && run_iptables -A dropInvalid -m state --state INVALID -j DROP if [ "$COMMAND" != check ]; then
[ -n "$xlevel" ] && \
log_rule_limit ${xlevel%\!} $xchain dropNotSyn $2 "" "$xtag" -m state --state INVALID
run_iptables -A dropInvalid -m state --state INVALID -j DROP
fi
;; ;;
*) *)
f=action.$xaction f=action.${xaction%%:*}
fn=$(find_file $f) fn=$(find_file $f)
echo "Processing $fn..." echo "Processing $fn..."
while read xtarget xclients xservers xprotocol xports xcports xratelimit $xuserspec; do while read xtarget xclients xservers xprotocol xports xcports xratelimit $xuserspec; do
xtarget=$(evaluate_levels $xaction $xtarget)
xaction=$(find_logactionchain $xaction)
do_it do_it
done < $TMP_DIR/$f done < $TMP_DIR/$f
;; ;;
@ -3828,21 +3965,23 @@ process_rules()
} }
while read xtarget xclients xservers xprotocol xports xcports xaddress xratelimit xuserspec; do while read xtarget xclients xservers xprotocol xports xcports xaddress xratelimit xuserspec; do
temp="${xtarget%%:*}" rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserspec)"
case "${temp%<*}" in expandv xtarget
case "${xtarget%%:*}" in
ACCEPT|ACCEPT+|NONAT|DROP|REJECT|DNAT|DNAT-|REDIRECT|REDIRECT-|LOG|CONTINUE|QUEUE) ACCEPT|ACCEPT+|NONAT|DROP|REJECT|DNAT|DNAT-|REDIRECT|REDIRECT-|LOG|CONTINUE|QUEUE)
do_it do_it
;; ;;
*) *)
if list_search $temp $ACTIONS; then if list_search ${xtarget%%:*} $ACTIONS; then
if ! list_search $temp $USEDACTIONS; then if ! list_search $xtarget $USEDACTIONS; then
[ $COMMAND = check ] || createactionchain $temp createactionchain $xtarget
USEDACTIONS="$USEDACTIONS $temp" USEDACTIONS="$USEDACTIONS $xtarget"
fi fi
xtarget=$(find_logactionchain $xtarget)
do_it do_it
else else
rule="$(echo $xtarget $xclients $xservers $xprotocol $xports $xcports $xaddress $xratelimit $xuserspec)"
fatal_error "Invalid Action in rule \"$rule\"" fatal_error "Invalid Action in rule \"$rule\""
fi fi
;; ;;
@ -4805,6 +4944,15 @@ determine_capabilities() {
qt iptables -F fooX1234 qt iptables -F fooX1234
qt iptables -X fooX1234 qt iptables -X fooX1234
fi fi
if [ -n "$PKTTYPE" ]; then
if qt iptables -N fooX1234 ; then
qt iptables -A fooX1234 -m pkttype --pkt-type broadcast -j ACCEPT || PKTTYPE=
qt iptables -F fooX1234
qt iptables -X fooX1234
fi
fi
} }
report_capability() # $1 = Capability Name, $2 Capability Setting (if any) report_capability() # $1 = Capability Name, $2 Capability Setting (if any)
@ -4822,6 +4970,7 @@ report_capabilities() {
report_capability $MANGLE_ENABLED "Packet Mangling" report_capability $MANGLE_ENABLED "Packet Mangling"
report_capability $MULTIPORT "Multi-port Match" report_capability $MULTIPORT "Multi-port Match"
report_capability $CONNTRACK_MATCH "Connection Tracking Match" report_capability $CONNTRACK_MATCH "Connection Tracking Match"
report_capability $PKTTYPE "Packet Type Match"
} }
# #

View File

@ -2,6 +2,30 @@
# #
# Shorewall 2.1 -- /usr/share/shorewall/functions # Shorewall 2.1 -- /usr/share/shorewall/functions
#
# Split a colon-separated list into a space-separated list
#
split() {
local ifs=$IFS
IFS=:
set -- $1
IFS=$ifs
echo $*
}
#
# Combine a space-separated list into a colon-separated list
#
combine() {
local result=$1
while [ $# -gt 1 ]; do
shift
result=$result:$1
done
echo $result
}
# #
# Search a list looking for a match -- returns zero if a match found # Search a list looking for a match -- returns zero if a match found
# 1 otherwise # 1 otherwise

View File

@ -78,3 +78,53 @@ New Features:
questions on the support and development lists regarding why the questions on the support and development lists regarding why the
default entries are the way they are. default entries are the way they are.
5) Previously, specifying a log level (and optionally a log tag) on a
rule that specified a user-defined (or Shorewall-defined) action
would log all traffic passed to the action. Beginning with this
release, specifying a log level in a rule that specifies a user-
or Shorewall-defined action will cause each rule in the action to
be logged with the specified level (and tag).
The extent to which logging of action rules occurs is goverend by
the following:
a) When you invoke an action and specify a log level, only those
rules in the action that have no log level will be changed to log
at the level specified at the action invocation.
Example:
/etc/shorewall/action.foo:
ACCEPT - - tcp 22
bar:info
/etc/shorewall/rules:
foo:debug fw net
Logging in the invoke 'foo' action will be:
ACCEPT:debug - - tcp 22
bar:info
b) If you follow the log level with "!" then logging will
be at that level for all rules recursively invoked by the action
Example:
/etc/shorewall/action.foo:
ACCEPT - - tcp 22
bar:info
/etc/shorewall/rules:
foo:debug! fw net
Logging in the invoke 'foo' action will be:
ACCEPT:debug - - tcp 22
bar:debug!