Finally implement exclude lists in rules

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@2493 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2005-08-15 17:35:45 +00:00
parent 5df7bc0538
commit 42ee8d0c19
3 changed files with 330 additions and 288 deletions

View File

@ -17,6 +17,8 @@ Changes in 2.5.1
8) Generate error for 'norfc1918' on an interface with an RFC 1918 IP 8) Generate error for 'norfc1918' on an interface with an RFC 1918 IP
address. address.
9) Finally implement exclude lists in rules.
Changes in 2.5.1ex/2.5.0 Changes in 2.5.1ex/2.5.0
1) Clean up handling of zones 1) Clean up handling of zones

View File

@ -4645,6 +4645,7 @@ process_actions3() {
# ratelimit = Optional rate limiting clause # ratelimit = Optional rate limiting clause
# userandgroup = -m owner match to limit the rule to a particular user and/or group # userandgroup = -m owner match to limit the rule to a particular user and/or group
# logtag = Log tag # logtag = Log tag
# excludesource = Source Exclusion List
# #
add_nat_rule() { add_nat_rule() {
local chain local chain
@ -4711,8 +4712,8 @@ add_nat_rule() {
if [ $COMMAND != check ]; then if [ $COMMAND != check ]; then
if [ "$source" = "$FW" ]; then if [ "$source" = "$FW" ]; then
if [ -n "$excludedests" ]; then if [ -n "${excludesource}${excludedests}" ]; then
build_exclusion_chain chain nat "" $excludedests build_exclusion_chain chain nat "$excludesource" $excludedests
for adr in $(separate_list $addr); do for adr in $(separate_list $addr); do
run_iptables2 -t nat -A OUTPUT $cli $proto $userandgroup $multiport $sports $dports $(dest_ip_range $adr) -j $chain run_iptables2 -t nat -A OUTPUT $cli $proto $userandgroup $multiport $sports $dports $(dest_ip_range $adr) -j $chain
@ -4734,8 +4735,8 @@ add_nat_rule() {
done done
fi fi
else else
if [ -n "${excludedests}" ]; then if [ -n "${excludesource}${excludedests}" ]; then
build_exclusion_chain chain nat "" $excludedests build_exclusion_chain chain nat "$excludesource" $excludedests
for adr in $(separate_list $addr); do for adr in $(separate_list $addr); do
addnatrule $(dnat_chain $source) $cli $proto $multiport $sports $dports $(dest_ip_range $adr) -j $chain addnatrule $(dnat_chain $source) $cli $proto $multiport $sports $dports $(dest_ip_range $adr) -j $chain
@ -4777,29 +4778,54 @@ add_nat_rule() {
} }
# #
# Add one Filter Rule -- Helper function for the rules file processor # Process a record from the rules file for the 'start', 'restart' or 'check' commands
# #
# The caller has established the following variables: process_rule() # $1 = target
# COMMAND = current command. If 'check', we're executing a 'check' # $2 = clients
# which only goes through the motions. # $3 = servers
# client = SOURCE IP or MAC # $4 = protocol
# server = DESTINATION IP or interface # $5 = ports
# protocol = Protocol # $6 = cports
# address = Original Destination Address # $7 = address
# port = Destination Port # $8 = ratelimit
# cport = Source Port # $9 = userspec
# 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 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. If 'check', we're executing a 'check'
# 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 or an exclusion chain
# 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= local natrule=
do_ports() { do_ports() {
@ -4920,18 +4946,22 @@ add_a_rule()
case "$logtarget" in case "$logtarget" in
ACCEPT|DROP|REJECT|CONTINUE) ACCEPT|DROP|REJECT|CONTINUE)
if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" -a -z "$userandgroup" ] ; then if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" -a -z "$userandgroup" -a -z "$excludesource" -a -z "$excludedest" ] ; then
error_message "Warning -- Rule \"$rule\" is a POLICY" error_message "Warning -- Rule \"$rule\" is a POLICY"
error_message " -- and should be moved to the policy file" error_message " -- and should be moved to the policy file"
fi fi
;; ;;
REDIRECT) REDIRECT)
[ -n "$excludedest" ] && fatal_error "Invalid DEST for this ACTION; rule \"$rule\""
[ -n "$serv" ] && \ [ -n "$serv" ] && \
fatal_error "REDIRECT rules cannot specify a server IP; rule: \"$rule\"" fatal_error "REDIRECT rules cannot specify a server IP; rule: \"$rule\""
servport=${servport:=$port} servport=${servport:=$port}
natrule=Yes natrule=Yes
;; ;;
DNAT|SAME) DNAT|SAME)
[ -n "$excludedest" ] && fatal_error "Invalid DEST for this ACTION; rule \"$rule\""
[ -n "$serv" ] || \ [ -n "$serv" ] || \
fatal_error "$logtarget rules require a server address; rule: \"$rule\"" fatal_error "$logtarget rules require a server address; rule: \"$rule\""
natrule=Yes natrule=Yes
@ -5046,35 +5076,9 @@ add_a_rule()
fi fi
fi fi
fi fi
} }
# # # # # # F u n c t i o n B o d y # # # # #
# Process a record from the rules file for the 'start', 'restart' or 'check' commands
#
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=
# Function Body - isolate rate limit
[ "x$ratelimit" = "x-" ] && ratelimit= [ "x$ratelimit" = "x-" ] && ratelimit=
@ -5222,14 +5226,18 @@ process_rule() # $1 = target
clients="${clients#*:}" clients="${clients#*:}"
[ -z "$clientzone" -o -z "$clients" ] && \ [ -z "$clientzone" -o -z "$clients" ] && \
fatal_error "Empty source zone or qualifier: rule \"$rule\"" fatal_error "Empty source zone or qualifier: rule \"$rule\""
if [ $(list_count $clients) -gt 1 ]; then fi
excludesource=
case $clients in case $clients in
!*) !*)
fatal_error "Exclude lists not supported in the SOURCE column" if [ $(list_count $clients) -gt 1 ]; then
excludesource=${clients#!}
clients=
fi
;; ;;
esac esac
fi
fi
validate_zone $clientzone || fatal_error "Undefined Client Zone in rule \"$rule\"" validate_zone $clientzone || fatal_error "Undefined Client Zone in rule \"$rule\""
@ -5271,6 +5279,17 @@ process_rule() # $1 = target
fi fi
fi fi
excludedest=
case $servers in
!*)
if [ $(list_count $servers) -gt 1 ]; then
excludedest=${servers#*!}
servers=
fi
;;
esac
if ! validate_zone $serverzone; then if ! validate_zone $serverzone; then
fatal_error "Undefined Server Zone in rule \"$rule\"" fatal_error "Undefined Server Zone in rule \"$rule\""
fi fi
@ -5290,16 +5309,25 @@ process_rule() # $1 = target
[ $policy = NONE ] && \ [ $policy = NONE ] && \
fatal_error "Rules may not override a NONE policy: rule \"$rule\"" fatal_error "Rules may not override a NONE policy: rule \"$rule\""
# Create the canonical chain if it doesn't already exist [ "x$protocol" = "x-" ] && protocol=all || protocol=${protocol:=all}
[ $COMMAND = check ] || ensurechain $chain if [ $COMMAND != check ]; then
ensurechain $chain
if [ -n "${excludesource}${excludedest}" ]; then
build_exclusion_chain newchain filter "$excludesource" "$excludedest"
run_iptables -A $chain -p $protocol -j $newchain
chain=$newchain
fi
fi
# Generate Netfilter rule(s) # Generate Netfilter rule(s)
protocol=${protocol:=all}
case $logtarget in case $logtarget in
DNAT*|SAME) DNAT*|SAME)
if [ -n "$XMULTIPORT" ] && \ if [ -n "$XMULTIPORT" ] && \
! list_search $protocol "icmp" "ICMP" "1" && \ ! list_search $protocol "icmp" "ICMP" "1" && \
[ $(( $(list_count $ports) + $(list_count1 $(split $ports ) ) )) -le 16 -a \ [ $(( $(list_count $ports) + $(list_count1 $(split $ports ) ) )) -le 16 -a \

View File

@ -331,3 +331,15 @@ New Features in Shorewall 2.5.*
9) Shorewall not generates an error if the 'norfc1918' option is 9) Shorewall not generates an error if the 'norfc1918' option is
specified for an interface with an RFC 1918 address. specified for an interface with an RFC 1918 address.
10) You may now specify "!" followed by a list of addresses in the
SOURCE and DEST columns of entries in /etc/shorewall/rules and
Shorewall will generate the rule that you expect.
Example:
#ACTION SOURCE DEST PROTO DEST PORT(S)
ACCEPT loc:!192.168.1.0/24,10.0.0.0/8 net tcp 80
That rule would allow loc->net HTTP access except for the local
networks 192.168.1.0/24 and 10.0.0.0/8.