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.
9) Allow exclusion in /etc/shorewall/hosts.
Changes in 3.3.1
1) Load the proxyarp lib when 'proxyarp' option is specified.

View File

@ -4109,6 +4109,29 @@ activate_rules()
frwd_chain=${zone}_frwd
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
#
# 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 type=\$${zone}_type
[ -n "$complex" ] && frwd_chain=${zone}_frwd
eval exclusions=\"\$${zone}_exclusions\"
echo $zone $type $source_hosts >> $STATEDIR/zones
@ -4155,18 +4177,46 @@ activate_rules()
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
interface=${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
#
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
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
eval dest_hosts=\$${zone1}_hosts
eval exclusions1=\"\$${zone1}_exclusions\"
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
# 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
fi
else
@ -4258,6 +4309,16 @@ activate_rules()
done
done
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
@ -4779,7 +4840,7 @@ run_iptables()
\$IPTABLES \$@
fi
if [ $? -ne 0 ]; then
if [ \$? -ne 0 ]; then
error_message "ERROR: Command \"\$IPTABLES \$@\" Failed"
stop_firewall
exit 2

View File

@ -581,6 +581,22 @@ validate_hosts_file() {
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
if [ -n "$BRIDGING" ]; then
case $host in
@ -601,26 +617,26 @@ validate_hosts_file() {
;;
esac
else
case $host in
*.*.*)
;;
*+|*!*)
eval ${z}_is_complex=Yes
;;
*)
startup_error "BRIDGING=Yes is needed for this zone definition: $r"
;;
esac
fi
for option in $(separate_list $options) ; do
case $option in
norfc1918|blacklist|tcpflags|nosmurfs|-)
;;
maclist)
case $host in
*.*.*)
;;
*+)
eval ${z}_is_complex=Yes
;;
*)
startup_error "BRIDGING=Yes is needed for this zone definition: $r"
;;
esac
fi
for option in $(separate_list $options) ; do
case $option in
norfc1918|blacklist|tcpflags|nosmurfs|-)
;;
maclist)
lib_load maclist "The 'maclist' option"
;;
ipsec)
ipsec)
[ -n "$POLICY_MATCH" ] || \
startup_error "Your kernel and/or iptables does not support policy match: ipsec"
eval ${z}_ipsec_hosts=\"\$${z}_ipsec_hosts $interface:$host\"
@ -1121,9 +1137,43 @@ find_hosts() # $1 = host zone
expandv hosts
interface=${hosts%%:*}
addresses=${hosts#*:}
for address in $(separate_list $addresses); do
echo $interface:$address
done
case $addresses in
!*)
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
done < $TMP_DIR/hosts
}
@ -1161,6 +1211,8 @@ determine_hosts() {
for zone in $ZONES; do
hosts=$(find_hosts $zone)
hosts=$(echo $hosts) # Remove extra trash
exclusions=$(find_exclusions $zone)
exclusions=$(echo $exclusions) # Remove extra trash
eval interfaces=\$${zone}_interfaces
@ -1203,11 +1255,14 @@ determine_hosts() {
fi
done
eval ${zone}_exclusions="\$exclusions"
eval ${zone}_interfaces="\$interfaces"
eval ${zone}_hosts="\$hosts"
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
error_message "WARNING: Zone $zone is empty"
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
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:
1) Shorewall supports the notion of "default actions". A default