Allow exclusion in /etc/shorewall/hosts

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@4698 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2006-10-18 19:56:22 +00:00
parent 14aee65dd2
commit 8d5ffcf048
4 changed files with 162 additions and 29 deletions

View File

@ -16,6 +16,8 @@ Changes in 3.3.3
8) Rename SUBNET column in the masq file. 8) Rename SUBNET column in the masq file.
9) Allow exclusion in /etc/shorewall/hosts.
Changes in 3.3.1 Changes in 3.3.1
1) Load the proxyarp lib when 'proxyarp' option is specified. 1) Load the proxyarp lib when 'proxyarp' option is specified.

View File

@ -4109,6 +4109,29 @@ activate_rules()
frwd_chain=${zone}_frwd frwd_chain=${zone}_frwd
createchain $frwd_chain No createchain $frwd_chain No
eval exclusions=\"\$${zone}_exclusions\"
if [ -n "$exclusions" ]; then
local num=1
in_chain=${zone}_in
out_chain=${zone}_out
createchain $in_chain No
createchain $out_chain No
if [ "$(rules_chain $zone $zone)" = ACCEPT ]; then
createchain ${zone}2${zone} yes
run_iptables -A ${zone}2${zone} -j ACCEPT
fi
for host in $exclusions; do
interface=${host%%:*}
address=${host#*:}
run_iptables -A $frwd_chain -i $interface -s $address -j RETURN
run_iptables -A $in_chain -i $interface -s $address -j RETURN
run_iptables -A $out_chain -i $interface -s $address -j RETURN
done
fi
if [ -n "$POLICY_MATCH" ]; then if [ -n "$POLICY_MATCH" ]; then
# #
# Because policy match only matches an 'in' or an 'out' policy (but not both), we have to place the # Because policy match only matches an 'in' or an 'out' policy (but not both), we have to place the
@ -4143,8 +4166,7 @@ activate_rules()
eval complex=\$${zone}_is_complex eval complex=\$${zone}_is_complex
eval type=\$${zone}_type eval type=\$${zone}_type
eval exclusions=\"\$${zone}_exclusions\"
[ -n "$complex" ] && frwd_chain=${zone}_frwd
echo $zone $type $source_hosts >> $STATEDIR/zones echo $zone $type $source_hosts >> $STATEDIR/zones
@ -4155,18 +4177,46 @@ activate_rules()
need_broadcast= need_broadcast=
if [ -n "$complex" ]; then
frwd_chain=${zone}_frwd
chain=$(dnat_chain $zone)
if havenatchain $chain; then
local num=0
for host in $exclusions; do
interface=${host%%:*}
networks=${host#*:}
num=$(($num + 1))
run_iptables -t nat -I $chain $num -i $interface -s $networks -j RETURN
done
fi
fi
for host in $source_hosts; do for host in $source_hosts; do
interface=${host%%:*} interface=${host%%:*}
networks=${host#*:} networks=${host#*:}
[ -n "$chain1" ] && run_iptables2 -A OUTPUT -o $interface $(match_dest_hosts $networks) $(match_ipsec_out $zone $host) -j $chain1 if [ -n "$chain1" ]; then
if [ -n "$exclusions" ]; then
run_iptables2 -A OUTPUT -o $interface $(match_dest_hosts $networks) $(match_ipsec_out $zone $host) -j ${zone}_out
run_iptables -A ${zone}_out -j $chain1
else
run_iptables2 -A OUTPUT -o $interface $(match_dest_hosts $networks) $(match_ipsec_out $zone $host) -j $chain1
fi
fi
# #
# Add jumps from the builtin chain for DNAT rules # Add jumps from the builtin chain for DNAT rules
# #
addrulejump PREROUTING $(dnat_chain $zone) -i $interface $(match_source_hosts $networks) $(match_ipsec_in $zone $host) addrulejump PREROUTING $(dnat_chain $zone) -i $interface $(match_source_hosts $networks) $(match_ipsec_in $zone $host)
[ -n "$chain2" ] && run_iptables2 -A $(input_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j $chain2 if [ -n "$chain2" ]; then
if [ -n "$exclusions" ]; then
run_iptables2 -A $(input_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j ${zone}_in
run_iptables -A ${zone}_in -j $chain2
else
run_iptables2 -A $(input_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j $chain2
fi
fi
if [ -n "$complex" ] && ! is_ipsec_host $zone $host ; then if [ -n "$complex" ] && ! is_ipsec_host $zone $host ; then
run_iptables2 -A $(forward_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j $frwd_chain run_iptables2 -A $(forward_chain $interface) $(match_source_hosts $networks) $(match_ipsec_in $zone $host) -j $frwd_chain
@ -4197,6 +4247,7 @@ activate_rules()
[ "$policy" = NONE ] && continue [ "$policy" = NONE ] && continue
eval dest_hosts=\$${zone1}_hosts eval dest_hosts=\$${zone1}_hosts
eval exclusions1=\"\$${zone1}_exclusions\"
chain="$(rules_chain $zone $zone1)" chain="$(rules_chain $zone $zone1)"
@ -4221,7 +4272,7 @@ activate_rules()
# If we don't need to route back and if we have only one interface or one port to # If we don't need to route back and if we have only one interface or one port to
# the zone then assume that hosts in the zone can communicate directly. # the zone then assume that hosts in the zone can communicate directly.
# #
if [ $num_ifaces -lt 2 -a -z "$routeback" ] ; then if [ $num_ifaces -lt 2 -a -z "$routeback" -a -z "$exclusions" ] ; then
continue continue
fi fi
else else
@ -4258,6 +4309,16 @@ activate_rules()
done done
done done
fi fi
if [ -n "$exclusions1" ]; then
local num=0
for host1 in $exclusions1; do
interface1=${host1%%:*}
networks1=${host1#*:}
num=$(($num + 1))
run_iptables -I $chain $num -o $interface1 -d $networks1 -j RETURN
done
fi
done done
done done
@ -4779,7 +4840,7 @@ run_iptables()
\$IPTABLES \$@ \$IPTABLES \$@
fi fi
if [ $? -ne 0 ]; then if [ \$? -ne 0 ]; then
error_message "ERROR: Command \"\$IPTABLES \$@\" Failed" error_message "ERROR: Command \"\$IPTABLES \$@\" Failed"
stop_firewall stop_firewall
exit 2 exit 2

View File

@ -581,6 +581,22 @@ validate_hosts_file() {
eval zports=\$${z}_ports eval zports=\$${z}_ports
if [ -z "$BRIDGING" ]; then
case $hosts in
*!*!*)
startup_error "Invalid hosts file entry: \"$r\""
;;
!*)
hosts=0.0.0.0/0
eval ${z}_is_complex=Yes
;;
*!*)
hosts=${hosts%%!*}
eval ${z}_is_complex=Yes
;;
esac
fi
for host in $(separate_list $hosts); do for host in $(separate_list $hosts); do
if [ -n "$BRIDGING" ]; then if [ -n "$BRIDGING" ]; then
case $host in case $host in
@ -601,26 +617,26 @@ validate_hosts_file() {
;; ;;
esac esac
else else
case $host in case $host in
*.*.*) *.*.*)
;; ;;
*+|*!*) *+)
eval ${z}_is_complex=Yes eval ${z}_is_complex=Yes
;; ;;
*) *)
startup_error "BRIDGING=Yes is needed for this zone definition: $r" startup_error "BRIDGING=Yes is needed for this zone definition: $r"
;; ;;
esac esac
fi fi
for option in $(separate_list $options) ; do for option in $(separate_list $options) ; do
case $option in case $option in
norfc1918|blacklist|tcpflags|nosmurfs|-) norfc1918|blacklist|tcpflags|nosmurfs|-)
;; ;;
maclist) maclist)
lib_load maclist "The 'maclist' option" lib_load maclist "The 'maclist' option"
;; ;;
ipsec) ipsec)
[ -n "$POLICY_MATCH" ] || \ [ -n "$POLICY_MATCH" ] || \
startup_error "Your kernel and/or iptables does not support policy match: ipsec" startup_error "Your kernel and/or iptables does not support policy match: ipsec"
eval ${z}_ipsec_hosts=\"\$${z}_ipsec_hosts $interface:$host\" eval ${z}_ipsec_hosts=\"\$${z}_ipsec_hosts $interface:$host\"
@ -1121,9 +1137,43 @@ find_hosts() # $1 = host zone
expandv hosts expandv hosts
interface=${hosts%%:*} interface=${hosts%%:*}
addresses=${hosts#*:} addresses=${hosts#*:}
for address in $(separate_list $addresses); do case $addresses in
echo $interface:$address !*)
done echo $interface:0.0.0.0/0
;;
*)
for address in $(separate_list ${addresses%%!*}); do
echo $interface:$address
done
;;
esac
fi
done < $TMP_DIR/hosts
}
#
#
# Find exclusions in a given zone
#
# Read hosts file and for each record matching the passed ZONE,
# echo any exclusions
#
find_exclusions() # $1 = host zone
{
local hosts interface address addresses
while read z hosts options; do
if [ "x$(expand $z)" = "x$1" ]; then
expandv hosts
interface=${hosts%%:*}
addresses=${hosts#*:}
case $addresses in
*!*)
for address in $(separate_list ${addresses#*!}); do
echo $interface:$address
done
;;
esac
fi fi
done < $TMP_DIR/hosts done < $TMP_DIR/hosts
} }
@ -1161,6 +1211,8 @@ determine_hosts() {
for zone in $ZONES; do for zone in $ZONES; do
hosts=$(find_hosts $zone) hosts=$(find_hosts $zone)
hosts=$(echo $hosts) # Remove extra trash hosts=$(echo $hosts) # Remove extra trash
exclusions=$(find_exclusions $zone)
exclusions=$(echo $exclusions) # Remove extra trash
eval interfaces=\$${zone}_interfaces eval interfaces=\$${zone}_interfaces
@ -1203,11 +1255,14 @@ determine_hosts() {
fi fi
done done
eval ${zone}_exclusions="\$exclusions"
eval ${zone}_interfaces="\$interfaces" eval ${zone}_interfaces="\$interfaces"
eval ${zone}_hosts="\$hosts" eval ${zone}_hosts="\$hosts"
if [ -n "$hosts" ]; then if [ -n "$hosts" ]; then
[ $VERBOSE -ge 1 ] && display_list "$zone Zone:" $hosts if [ $VERBOSE -ge 1 ]; then
[ -n "$exclusions" ] && display_list "$zone Zone:" $hosts minus "($exclusions)" || display_list "$zone Zone:" $hosts
fi
else else
error_message "WARNING: Zone $zone is empty" error_message "WARNING: Zone $zone is empty"
fi fi

View File

@ -127,6 +127,21 @@ Other changes in 3.3.3
6) The SUBNET column in /etc/shorewall/masq has been renamed SOURCE to 6) The SUBNET column in /etc/shorewall/masq has been renamed SOURCE to
more accurately describe the contents of the column. more accurately describe the contents of the column.
7) Previously, it was not possible to use exclusion in
/etc/shorewall/hosts. Beginning with this release, you may now use
exclusion lists in entries in this file. Exclusion lists are
discussed at:
http://www.shorewall.net/configuration_file_basics.htm#Exclusion.
Example:
loc eth0:192.168.1.0/24!192.168.1.4,192.168.1.16/28
In that example, the 'loc' zone is defined to be the subnet
192.168.1.0/24 interfacing via eth0 *except* for host 192.168.1.4
and hosts in the sub-network 192.168.1.16/28.
Migration Considerations: Migration Considerations:
1) Shorewall supports the notion of "default actions". A default 1) Shorewall supports the notion of "default actions". A default