forked from extern/shorewall_code
Allow policy-level specification of default action or macro
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@4481 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
1ec8b73540
commit
8c4eef48c4
@ -2,4 +2,7 @@ Changes in 3.3.1
|
||||
|
||||
1) Load the proxyarp lib when 'proxyarp' option is specified.
|
||||
|
||||
2) Implement default action/macros at the individual policy level.
|
||||
|
||||
|
||||
|
||||
|
@ -426,6 +426,7 @@ validate_policy()
|
||||
local loglevel
|
||||
local synparams
|
||||
local parents
|
||||
local default
|
||||
|
||||
print_policy() # $1 = source zone, $2 = destination zone
|
||||
{
|
||||
@ -494,16 +495,24 @@ validate_policy()
|
||||
fi
|
||||
esac
|
||||
|
||||
default=
|
||||
|
||||
case $policy in
|
||||
*:None|*:none)
|
||||
default=none
|
||||
;;
|
||||
*:*)
|
||||
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"
|
||||
default=${policy#*:}
|
||||
if list_search $default $ACTIONS; then
|
||||
if ! list_search $default $USEDACTIONS; then
|
||||
USEDACTIONS="$USEDACTIONS $default"
|
||||
fi
|
||||
elif ! list_search $default $DEFAULT_MACROS; then
|
||||
[ -f $(find_file macro.${default}) ] || fatal_error "$client $server $policy $loglevel $synparams: Default Macro $default not found"
|
||||
DEFAULT_MACROS="$DEFAULT_MACROS $default"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
macro=
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -543,7 +552,7 @@ validate_policy()
|
||||
eval ${chain}_policy=$policy
|
||||
eval ${chain}_loglevel=$loglevel
|
||||
eval ${chain}_synparams=$synparams
|
||||
eval ${chain}_macro=$macro
|
||||
eval ${chain}_default=$default
|
||||
|
||||
if [ -n "${clientwild}" ]; then
|
||||
if [ -n "${serverwild}" ]; then
|
||||
@ -1300,8 +1309,8 @@ substitute_action() # $1 = parameter, $2 = action
|
||||
esac
|
||||
}
|
||||
|
||||
process_actions3() {
|
||||
|
||||
process_actions3()
|
||||
{
|
||||
for xaction in $USEDACTIONS; do
|
||||
#
|
||||
# Find the chain associated with this action:level:tag
|
||||
@ -1664,54 +1673,27 @@ __EOF__
|
||||
}
|
||||
|
||||
#
|
||||
# Process a record from the rules file
|
||||
# Add one Filter Rule
|
||||
#
|
||||
process_rule() # $1 = target
|
||||
# $2 = clients
|
||||
# $3 = servers
|
||||
# $4 = protocol
|
||||
# $5 = ports
|
||||
# $6 = cports
|
||||
# $7 = address
|
||||
# $8 = ratelimit
|
||||
# $9 = userspec
|
||||
{
|
||||
local target="$1"
|
||||
local clients="$2"
|
||||
local servers="$3"
|
||||
local protocol="$4"
|
||||
local ports="$5"
|
||||
local cports="$6"
|
||||
local address="$7"
|
||||
local ratelimit="$8"
|
||||
local userspec="$9"
|
||||
local userandgroup=
|
||||
local logtag=
|
||||
local nonat=
|
||||
#
|
||||
# Add one Filter Rule
|
||||
#
|
||||
# The caller has established the following variables:
|
||||
# COMMAND = current command.
|
||||
# which only goes through the motions.
|
||||
# client = SOURCE IP or MAC
|
||||
# server = DESTINATION IP or interface
|
||||
# protocol = Protocol
|
||||
# address = Original Destination Address
|
||||
# port = Destination Port
|
||||
# cport = Source Port
|
||||
# multioption = String to invoke multiport match if appropriate
|
||||
# servport = Port the server listens on
|
||||
# chain = The canonical chain for this rule
|
||||
# logchain = The chain that should be mentioned in log messages
|
||||
# ratelimit = Optional rate limiting clause
|
||||
# userandgroup = -m owner clause
|
||||
# userspec = User name
|
||||
# logtag = Log tag
|
||||
# policy = Applicable Policy
|
||||
#
|
||||
add_a_rule()
|
||||
{
|
||||
# The caller has established the following variables:
|
||||
# COMMAND = current command.
|
||||
# client = SOURCE IP or MAC
|
||||
# server = DESTINATION IP or interface
|
||||
# protocol = Protocol
|
||||
# address = Original Destination Address
|
||||
# port = Destination Port
|
||||
# cport = Source Port
|
||||
# multioption = String to invoke multiport match if appropriate
|
||||
# servport = Port the server listens on
|
||||
# chain = The canonical chain for this rule
|
||||
# logchain = The chain that should be mentioned in log messages
|
||||
# ratelimit = Optional rate limiting clause
|
||||
# userandgroup = -m owner clause
|
||||
# userspec = User name
|
||||
# logtag = Log tag
|
||||
# policy = Applicable Policy
|
||||
#
|
||||
add_a_rule() {
|
||||
local natrule=
|
||||
|
||||
do_ports() {
|
||||
@ -1754,7 +1736,7 @@ process_rule() # $1 = target
|
||||
done
|
||||
addr=
|
||||
else
|
||||
run_iptables -A $state $logchain $(fix_bang $cli $proto $sports $multiport $dports) $user -j $chain
|
||||
run_iptables -A $logchain $state $(fix_bang $cli $proto $sports $multiport $dports) $user -j $chain
|
||||
fi
|
||||
|
||||
cli=
|
||||
@ -1891,10 +1873,12 @@ process_rule() # $1 = target
|
||||
|
||||
case "$logtarget" in
|
||||
ACCEPT|DROP|REJECT|CONTINUE)
|
||||
if [ "$SECTION" != DONE ]; then
|
||||
if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" -a -z "$user" -a -z "$excludesource" -a -z "$excludedest" ] ; then
|
||||
error_message "WARNING -- Rule \"$rule\" is a POLICY"
|
||||
error_message " -- and should be moved to the policy file"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
REDIRECT)
|
||||
[ -n "$excludedest" ] && fatal_error "Invalid DEST for this ACTION; rule \"$rule\""
|
||||
@ -2043,7 +2027,32 @@ __EOF__
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
}
|
||||
#
|
||||
# Process a record from the rules file
|
||||
#
|
||||
process_rule() # $1 = target
|
||||
# $2 = clients
|
||||
# $3 = servers
|
||||
# $4 = protocol
|
||||
# $5 = ports
|
||||
# $6 = cports
|
||||
# $7 = address
|
||||
# $8 = ratelimit
|
||||
# $9 = userspec
|
||||
{
|
||||
local target="$1"
|
||||
local clients="$2"
|
||||
local servers="$3"
|
||||
local protocol="$4"
|
||||
local ports="$5"
|
||||
local cports="$6"
|
||||
local address="$7"
|
||||
local ratelimit="$8"
|
||||
local userspec="$9"
|
||||
local userandgroup=
|
||||
local logtag=
|
||||
local nonat=
|
||||
|
||||
# # # # # F u n c t i o n B o d y # # # # #
|
||||
|
||||
@ -2722,115 +2731,142 @@ 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
|
||||
local address=
|
||||
local multioption=
|
||||
local servport=
|
||||
local chain=$1
|
||||
local logchain=$1
|
||||
local userandgroup=
|
||||
local logtag=
|
||||
local excludesource=
|
||||
local target client server protocol port cport ratelimit userspec rule
|
||||
|
||||
havechain $macro && fatal_error "Illegal duplicate default macro name: $macro"
|
||||
|
||||
createchain $macro
|
||||
strip_file macro.${macro}
|
||||
progress_message "..Expanding Macro $(find_file macro.${macro})..."
|
||||
createchain $macro no
|
||||
strip_file macro.$macro
|
||||
progress_message "..Expanding Default Macro $(find_file macro.${macro}) into chain $macro..."
|
||||
|
||||
while read mtarget mclients mservers mprotocol mports mcports mratelimit muserspec; do
|
||||
expandv mtarget mclients mservers mprotocol mports mcports mratelimit muserspec
|
||||
while read target client server protocol port cport ratelimit userspec; do
|
||||
expandv target client server protocol port cport ratelimit userspec
|
||||
rule="$target ${client:--} ${server:--} ${protocol:--} ${port:--} ${cport:--} ${ratelimit:--} ${userspec:--}"
|
||||
|
||||
case $mtarget in
|
||||
case $target in
|
||||
PARAM|PARAM:*)
|
||||
fatal_error "Invalid target ($mtarget) in default macro $macro"
|
||||
fatal_error "Invalid target ($target) in default macro $macro"
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${mtarget} in
|
||||
case ${target} in
|
||||
ACCEPT|DROP|REJECT)
|
||||
;;
|
||||
*)
|
||||
if list_search ${mtarget%%:*} $ACTIONS; then
|
||||
if ! list_search $mtarget $USEDACTIONS; then
|
||||
createactionchain $mtarget
|
||||
USEDACTIONS="$USEDACTIONS $mtarget"
|
||||
if list_search $target $ACTIONS; then
|
||||
if ! list_search $target $USEDACTIONS; then
|
||||
createactionchain $target
|
||||
USEDACTIONS="$USEDACTIONS $target"
|
||||
fi
|
||||
|
||||
mtarget=$(find_logactionchain $mtarget)
|
||||
else
|
||||
fatal_error "Invalid Action in rule \"$mtarget ${mclients:--} ${mservers:--} ${mprotocol:--} ${mports:--} ${mcports:--} ${xaddress:--} ${mratelimit:--} ${muserspec:--}\""
|
||||
fatal_error "Invalid target ($target) in default macro $macro"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "$mclients" ]; then
|
||||
case $mclients in
|
||||
if [ $(list_count ${port}${cport}) -gt 1 ]; then
|
||||
multioption="-m multiport"
|
||||
fi
|
||||
|
||||
if [ -n "$client" ]; then
|
||||
case $client in
|
||||
-|SOURCE)
|
||||
;;
|
||||
*)
|
||||
fatal_error "Invalid SOURCE ($mclients) in default macro $macro"
|
||||
client=
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ -n "$mservers" ]; then
|
||||
case $mservers in
|
||||
if [ -n "$server" ]; then
|
||||
case $server in
|
||||
-|DEST)
|
||||
server=
|
||||
;;
|
||||
*)
|
||||
fatal_error "Invalid DEST ($mservers) in default macro $macro"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case ${mports}${mcports} in
|
||||
*,*)
|
||||
fatal_error "Port lists not allowed in default macro"
|
||||
[ "x$userspec" = "x-" ] && userspec=
|
||||
|
||||
if [ -n "$userspec" ]; then
|
||||
|
||||
userandgroup="-m owner"
|
||||
|
||||
case "$userspec" in
|
||||
!*+*)
|
||||
if [ -n "${userspec#*+}" ]; then
|
||||
userandgroup="$userandgroup ! --cmd-owner ${userspec#*+}"
|
||||
fi
|
||||
userspec=${userspec%+*}
|
||||
;;
|
||||
*+*)
|
||||
if [ -n "${userspec#*+}" ]; then
|
||||
userandgroup="$userandgroup --cmd-owner ${userspec#*+}"
|
||||
fi
|
||||
userspec=${userspec%+*}
|
||||
;;
|
||||
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"
|
||||
case "$userspec" in
|
||||
!*:*)
|
||||
if [ "$userspec" != "!:" ]; then
|
||||
temp="${userspec#!}"
|
||||
temp="${temp%:*}"
|
||||
[ -n "$temp" ] && userandgroup="$userandgroup ! --uid-owner $temp"
|
||||
temp="${userspec#*:}"
|
||||
[ -n "$temp" ] && userandgroup="$userandgroup ! --gid-owner $temp"
|
||||
fi
|
||||
;;
|
||||
*:*)
|
||||
if [ "$userspec" != ":" ]; then
|
||||
temp="${userspec%:*}"
|
||||
[ -n "$temp" ] && userandgroup="$userandgroup --uid-owner $temp"
|
||||
temp="${userspec#*:}"
|
||||
[ -n "$temp" ] && userandgroup="$userandgroup --gid-owner $temp"
|
||||
fi
|
||||
;;
|
||||
!*)
|
||||
[ "$userspec" != "!" ] && userandgroup="$userandgroup ! --uid-owner ${userspec#!}"
|
||||
;;
|
||||
*)
|
||||
[ -n "$userspec" ] && userandgroup="$userandgroup --uid-owner $userspec"
|
||||
;;
|
||||
esac
|
||||
|
||||
expand_macro $1 $target $mprotocol $mports $mcports $mratelimit $muserspec
|
||||
progress_message "Rule \"$target $mprotocol $mports $mcports $mratelimit $muserspec\" $DONE"
|
||||
[ "$userandgroup" = "-m owner" ] && userandgroup=
|
||||
fi
|
||||
|
||||
done < $TMP_DIR/macro.${itarget%%:*}
|
||||
[ "x$ratelimit" = "x-" ] && ratelimit=
|
||||
|
||||
if [ -n "$ratelimit" ]; then
|
||||
case $ratelimit in
|
||||
*:*)
|
||||
ratelimit="-m limit --limit ${ratelimit%:*} --limit-burst ${ratelimit#*:}"
|
||||
;;
|
||||
*)
|
||||
ratelimit="-m limit --limit $ratelimit"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
add_a_rule
|
||||
progress_message "Rule \"$target $protocol $port $cport $ratelimit $userspec\" $DONE"
|
||||
|
||||
done < $TMP_DIR/macro.$macro
|
||||
|
||||
progress_message "..End Macro"
|
||||
|
||||
@ -3043,12 +3079,12 @@ policy_rules() # $1 = chain to add rules to
|
||||
# $3 = loglevel
|
||||
{
|
||||
local target="$2"
|
||||
local macro
|
||||
local default
|
||||
|
||||
eval macro=\$${1}_macro
|
||||
eval default=\$${1}_default
|
||||
|
||||
if [ -n "$macro" ]; then
|
||||
run_iptables -A $1 -j $macro
|
||||
if [ -n "$default" ]; then
|
||||
[ "$default" = none ] || run_iptables -A $1 -j $default
|
||||
else
|
||||
case "$target" in
|
||||
ACCEPT)
|
||||
@ -3484,6 +3520,13 @@ initialize_netfilter () {
|
||||
|
||||
validate_hosts_file
|
||||
|
||||
define_builtin_actions
|
||||
|
||||
if [ -n "$USE_ACTIONS" ]; then
|
||||
progress_message2 "Pre-processing Actions..."
|
||||
process_actions1
|
||||
fi
|
||||
|
||||
progress_message2 "Validating Policy file..."
|
||||
|
||||
validate_policy
|
||||
@ -3495,22 +3538,9 @@ initialize_netfilter () {
|
||||
|
||||
append_file init
|
||||
|
||||
#
|
||||
# Some files might be large so strip them while the firewall is still running
|
||||
# (restart command). This reduces the length of time that the firewall isn't
|
||||
# accepting new connections.
|
||||
#
|
||||
|
||||
strip_file rules
|
||||
strip_file maclist
|
||||
|
||||
define_builtin_actions
|
||||
|
||||
if [ -n "$USE_ACTIONS" ]; then
|
||||
progress_message2 "Pre-processing Actions..."
|
||||
process_actions1
|
||||
fi
|
||||
|
||||
TERMINATOR=fatal_error
|
||||
|
||||
deletechain shorewall
|
||||
@ -5174,6 +5204,7 @@ __EOF__
|
||||
|
||||
if [ -n "$DEFAULT_MACROS" ]; then
|
||||
progress_message2 "$DOING default macros..."
|
||||
save_progress_message "Creating default macro chains..."
|
||||
for macro in $DEFAULT_MACROS; do
|
||||
process_default_macro $macro
|
||||
done
|
||||
|
@ -59,19 +59,20 @@
|
||||
# contain the firewall zone ($FW) or
|
||||
# "all".
|
||||
#
|
||||
# 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 the policy is ACCEPT, DROP, REJECT or QUEUE then
|
||||
# the policy may be followed by ":" and one of the
|
||||
# following:
|
||||
#
|
||||
# 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.
|
||||
# a) The word "None" or "none". This causes any default
|
||||
# action define in /etc/shorewall/actions.std or
|
||||
# /etc/shorewall/actions to be omitted for this
|
||||
# policy.
|
||||
# b) The name of an action (requires that USE_ACTIONS=Yes
|
||||
# in shorewall.conf). That action will be invoked
|
||||
# before the policy is enforced.
|
||||
# c) The name of a macro. The rules in that macro will
|
||||
# be applied before the policy is enforced. This
|
||||
# does not require USE_ACTIONS=Yes.
|
||||
#
|
||||
# LOG LEVEL If supplied, each connection handled under the default
|
||||
# POLICY is logged at that level. If not supplied, no
|
||||
|
@ -112,4 +112,50 @@ New Features:
|
||||
The macros macro.Drop and macro.Reject are supplied to help you do
|
||||
that.
|
||||
|
||||
3) Prior to Shorewall 3.3, default actions were specified in
|
||||
/usr/share/shorewall/actions.std or in /etc/shorewall/actions.
|
||||
|
||||
This approach has two drawbacks:
|
||||
|
||||
a) All DROP policies must use the same default action and all
|
||||
REJECT policies must use the same default action.
|
||||
|
||||
b) Now that we have modularized action processing, we need a way to
|
||||
define default rules for a policy.
|
||||
|
||||
The solution is to extend the POLICY column in
|
||||
/etc/shorewall/policy.
|
||||
|
||||
When the POLICY is ACCEPT, DROP, REJECT or QUEUE then the policy
|
||||
may be followed by ":" and one of the following:
|
||||
|
||||
a) The word "None" or "none". This causes any default
|
||||
action define in /etc/shorewall/actions.std or
|
||||
/etc/shorewall/actions to be omitted for this
|
||||
policy.
|
||||
b) The name of an action (requires that USE_ACTIONS=Yes
|
||||
in shorewall.conf). That action will be invoked
|
||||
before the policy is enforced.
|
||||
c) The name of a macro. The rules in that macro will
|
||||
be applied before the policy is enforced. This
|
||||
does not require USE_ACTIONS=Yes.
|
||||
|
||||
Example:
|
||||
|
||||
#SOURCE DEST POLICY LOG
|
||||
# LEVEL
|
||||
loc net ACCEPT
|
||||
net all DROP:Drop info
|
||||
#
|
||||
# THE FOLLOWING POLICY MUST BE LAST
|
||||
#
|
||||
all all REJECT:Reject info
|
||||
|
||||
With USE_ACTIONS=Yes, the above will work the same way that the
|
||||
pre-3.3 setup did. The 'Drop' and 'Reject' actions will be invoked
|
||||
before the DROP and REJECT policies are enforced.
|
||||
|
||||
With USE_ACTION=No, there will be no Drop or Reject actions so
|
||||
Shorewall will look for macros by that name; as described in item
|
||||
2) above, these macros are provided as part of the Shorewall 3.3
|
||||
release.
|
||||
|
Loading…
Reference in New Issue
Block a user