From 32c15decea6774ba67711f63a865abd63a5df431 Mon Sep 17 00:00:00 2001 From: teastep Date: Wed, 30 Aug 2006 00:48:24 +0000 Subject: [PATCH] First cut at default macros git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@4479 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall/compiler | 208 +++++++++++++++++++++++++++++++++++++------- Shorewall/functions | 1 + Shorewall/policy | 13 ++- 3 files changed, 187 insertions(+), 35 deletions(-) diff --git a/Shorewall/compiler b/Shorewall/compiler index 1cf93970f..040da3172 100755 --- a/Shorewall/compiler +++ b/Shorewall/compiler @@ -495,18 +495,31 @@ validate_policy() esac case $policy in - ACCEPT|REJECT|DROP|CONTINUE|QUEUE) - ;; - NONE) - [ "$client" = "$FW" -o "$server" = "$FW" ] && \ - fatal_error " $client $server $policy $loglevel $synparams: NONE policy not allowed to/from the $FW zone" + *:*) + macro=${policy#*:} + if ! list_search $macro $DEFAULT_MACROS; + [ -f find_file macro.${macro} ] || fatal_error "$client $server $policy $loglevel $synparams: Default Macro $macro not found" + DEFAULT_MACROS="$DEFAULT_MACROS $macro" + fi + ;; + *) + macro= + ;; + esac - [ -n "$clientwild" -o -n "$serverwild" ] && \ - fatal_error " $client $server $policy $loglevel $synparams: NONE policy not allowed with \"all\"" - ;; - *) - fatal_error "Invalid policy $policy" - ;; + case ${policy%:*} in + ACCEPT|REJECT|DROP|CONTINUE|QUEUE) + ;; + NONE) + [ "$client" = "$FW" -o "$server" = "$FW" ] && \ + fatal_error " $client $server $policy $loglevel $synparams: NONE policy not allowed to/from the $FW zone" + + [ -n "$clientwild" -o -n "$serverwild" ] && \ + fatal_error " $client $server $policy $loglevel $synparams: NONE policy not allowed with \"all\"" + ;; + *) + fatal_error "Invalid policy $policy" + ;; esac chain=${client}2${server} @@ -522,12 +535,15 @@ validate_policy() [ "x$loglevel" = "x-" ] && loglevel= [ "x$synparams" = "x-" ] && synparams= + policy=${policy%:*} + [ $policy = NONE ] || ALL_POLICY_CHAINS="$ALL_POLICY_CHAINS $chain" eval ${chain}_is_policy=Yes eval ${chain}_policy=$policy eval ${chain}_loglevel=$loglevel eval ${chain}_synparams=$synparams + eval ${chain}_macro=$macro if [ -n "${clientwild}" ]; then if [ -n "${serverwild}" ]; then @@ -2706,6 +2722,120 @@ process_rules() SECTION=DONE } +# +# Expand an entry in a default macro +# +expand_macro() { + local chain=$1 + local target=$2 + local protocol=$3 + local port=$4 + local cport=$5 + local rule= + + if [ "x$protocol" != x- -a -n "$protocol" ]; then + rule="-p $protocol" + + case $protocol in + 6|tcp|TCP|17|udp|UDP) + if [ "x$port" != x- -a -n "$port" ]; then + rule="$rule -m multiport --dports $port" + [ "x$cport" != x- -a -n "$cport" ] && rule="$rule --sports $cport" + else + [ "x$cport" != x- -a -n "$cport" ] && rule="$rule -m multiport --sports $cport" + fi + ;; + icmp|ICMP|0) + [ "x$port" != x- -a -n "$port" ] && rule="$rule --icmp-type $port" + ;; + ;; + *) + [ "x$port" != x- -a -n "$port" ] && fatal_error "DEST PORT(S) not allowed with protocol $protocol" + [ "x$cport" != x- -a -n "$cport" ] && fatal_error "SOURCE PORT(S) not allowed with protocol $protocol" + ;; + esac + fi + + run_iptables -A $chain $rule -j $target +} + +# +# Process a default macro +# +process_default_macro() # $1 = macro name +{ + local macro=$1 + + havechain $macro && fatal_error "Illegal duplicate default macro name: $macro" + + createchain $macro + strip_file macro.${macro} + progress_message "..Expanding Macro $(find_file macro.${macro})..." + + while read mtarget mclients mservers mprotocol mports mcports mratelimit muserspec; do + expandv mtarget mclients mservers mprotocol mports mcports mratelimit muserspec + + case $mtarget in + PARAM|PARAM:*) + fatal_error "Invalid target ($mtarget) in default macro $macro" + ;; + esac + + case ${mtarget} in + ACCEPT|DROP|REJECT) + ;; + *) + if list_search ${mtarget%%:*} $ACTIONS; then + if ! list_search $mtarget $USEDACTIONS; then + createactionchain $mtarget + USEDACTIONS="$USEDACTIONS $mtarget" + fi + + mtarget=$(find_logactionchain $mtarget) + else + fatal_error "Invalid Action in rule \"$mtarget ${mclients:--} ${mservers:--} ${mprotocol:--} ${mports:--} ${mcports:--} ${xaddress:--} ${mratelimit:--} ${muserspec:--}\"" + fi + ;; + esac + + if [ -n "$mclients" ]; then + case $mclients in + -|SOURCE) + ;; + *) + fatal_error "Invalid SOURCE ($mclients) in default macro $macro" + ;; + esac + fi + + if [ -n "$mservers" ]; then + case $mservers in + -|DEST) + ;; + *) + fatal_error "Invalid DEST ($mservers) in default macro $macro" + ;; + esac + fi + + case ${mports}${mcports} in + *,*) + fatal_error "Port lists not allowed in default macro" + ;; + esac + + [ "x$mratelimit" != "x-" -a -n "$mratelimit" ] && fatal_error "Invalid Rate Limit ($mratelimit) in default macro $macro" + [ "x$muserspec" != "x-" -a -n "$muserspec" ] && fatal_error "Invalid USER/GROUP ($muserspec) in default macro $macro" + + expand_macro $1 $target $mprotocol $mports $mcports $mratelimit $muserspec + progress_message "Rule \"$target $mprotocol $mports $mcports $mratelimit $muserspec\" $DONE" + + done < $TMP_DIR/macro.${itarget%%:*} + + progress_message "..End Macro" + +} + # # Process a record from the tos file # @@ -2913,28 +3043,35 @@ policy_rules() # $1 = chain to add rules to # $3 = loglevel { local target="$2" + local macro - case "$target" in - ACCEPT) - [ -n "$ACCEPT_default" ] && run_iptables -A $1 -j $ACCEPT_default - ;; - DROP) - [ -n "$DROP_default" ] && run_iptables -A $1 -j $DROP_default - ;; - REJECT) - [ -n "$REJECT_default" ] && run_iptables -A $1 -j $REJECT_default - target=reject - ;; - QUEUE) - [ -n "$QUEUE_default" ] && run_iptables -A $1 -j $QUEUE_default - ;; - CONTINUE) - target= - ;; - *) - fatal_error "Invalid policy ($policy) for $1" - ;; - esac + eval macro=\$${1}_macro + + if [ -n "$macro" ]; then + run_iptables -A $1 -j $macro + else + case "$target" in + ACCEPT) + [ -n "$ACCEPT_default" ] && run_iptables -A $1 -j $ACCEPT_default + ;; + DROP) + [ -n "$DROP_default" ] && run_iptables -A $1 -j $DROP_default + ;; + REJECT) + [ -n "$REJECT_default" ] && run_iptables -A $1 -j $REJECT_default + target=reject + ;; + QUEUE) + [ -n "$QUEUE_default" ] && run_iptables -A $1 -j $QUEUE_default + ;; + CONTINUE) + target= + ;; + *) + fatal_error "Invalid policy ($policy) for $1" + ;; + esac + fi if [ $# -eq 3 -a "x${3}" != "x-" ]; then log_rule $3 $1 $2 @@ -5035,6 +5172,13 @@ __EOF__ setup_tunnels $tunnels fi + if [ -n "$DEFAULT_MACROS" ]; then + progress_message2 "$DOING default macros..." + for macro in $DEFAULT_MACROS; do + process_default_macro $macro + done + fi + if [ -n "$USEDACTIONS" ]; then save_progress_message "Setting up Actions..." diff --git a/Shorewall/functions b/Shorewall/functions index 66404f75e..42bf61bbc 100644 --- a/Shorewall/functions +++ b/Shorewall/functions @@ -2933,6 +2933,7 @@ do_initialize() { SECTION=ESTABLISHED SECTIONS= ALL_PORTS= + DEFAULT_MACROS= TMP_DIR=$(mktempdir) diff --git a/Shorewall/policy b/Shorewall/policy index 3a417960d..abdd42814 100644 --- a/Shorewall/policy +++ b/Shorewall/policy @@ -59,13 +59,20 @@ # contain the firewall zone ($FW) or # "all". # -# If this column contains ACCEPT, DROP or REJECT and a -# corresponding common action is defined in -# /etc/shorewall/actions (or +# If USE_ACTIONS=Yes in shorewall.conf (or if that +# option is not set) then if this column contains ACCEPT, +# DROP, or REJECT and a corresponding default action +# is defined in /etc/shorewall/actions (or # /usr/share/shorewall/actions.std) then that action # will be invoked before the policy named in this column # is enforced. # +# If USE_ACTIONS=No in shorewall.conf then ACCEPT,DROP +# REJECT may be optionally followed by ":" and the name +# of a macro. The rules in the macro will be expanded +# and packets will pass through the rules prior to +# the policy being applied. +# # LOG LEVEL If supplied, each connection handled under the default # POLICY is logged at that level. If not supplied, no # log message is generated. See syslog.conf(5) for a