mirror of
https://gitlab.com/shorewall/code.git
synced 2025-02-04 11:59:27 +01:00
First implementation of dynamic zones
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@275 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
36fe894006
commit
129cedbe8f
@ -1142,7 +1142,7 @@ setup_tunnels() # $1 = name of tunnels file
|
||||
local inchain
|
||||
local outchain
|
||||
|
||||
setup_one_ipsec() # $1 = gateway $2 = gateway zone
|
||||
setup_one_ipsec() # $1 = gateway $2 = gateway zones
|
||||
{
|
||||
options="-m state --state NEW -j ACCEPT"
|
||||
addrule $inchain -p 50 -s $1 -j ACCEPT
|
||||
@ -1152,14 +1152,14 @@ setup_tunnels() # $1 = name of tunnels file
|
||||
run_iptables -A $inchain -p udp -s $1 --sport 500 --dport 500 $options
|
||||
run_iptables -A $outchain -p udp -d $1 --dport 500 --sport 500 $options
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
if validate_zone $2; then
|
||||
addrule ${FW}2${2} -p udp --sport 500 --dport 500 $options
|
||||
for z in `separate_list $2`; do
|
||||
if validate_zone $z; then
|
||||
addrule ${FW}2${z} -p udp --sport 500 --dport 500 $options
|
||||
else
|
||||
error_message "Warning: Invalid gateway zone ($2)" \
|
||||
error_message "Warning: Invalid gateway zone ($z)" \
|
||||
" -- Tunnel \"$tunnel\" may encounter keying problems"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo " IPSEC tunnel to $gateway defined."
|
||||
}
|
||||
@ -3183,23 +3183,34 @@ activate_rules()
|
||||
|
||||
multi_interfaces=`find_interfaces_by_option multi`
|
||||
|
||||
> ${STATEDIR}/chains
|
||||
> ${STATEDIR}/zones
|
||||
|
||||
for zone in $zones; do
|
||||
eval source_hosts=\$${zone}_hosts
|
||||
|
||||
echo $zone $source_hosts >> ${STATEDIR}/zones
|
||||
|
||||
chain1=`rules_chain $FW $zone`
|
||||
chain2=`rules_chain $zone $FW`
|
||||
|
||||
echo "$FW $zone $chain1" >> ${STATEDIR}/chains
|
||||
echo "$zone $FW $chain2" >> ${STATEDIR}/chains
|
||||
|
||||
for host in $source_hosts; do
|
||||
interface=${host%:*}
|
||||
subnet=${host#*:}
|
||||
|
||||
run_iptables -A OUTPUT -o \
|
||||
$interface -d $subnet -j `rules_chain $FW $zone`
|
||||
run_iptables -A OUTPUT -o $interface -d $subnet -j $chain1
|
||||
|
||||
#
|
||||
# Add jumps from the builtin chains for DNAT and SNAT rules
|
||||
#
|
||||
addrulejump PREROUTING `dnat_chain $zone` -i $interface -s $subnet
|
||||
addrulejump POSTROUTING `snat_chain $zone` -o $interface -d $subnet
|
||||
|
||||
run_iptables -A `input_chain $interface` -s $subnet \
|
||||
-j `rules_chain $zone $FW`
|
||||
run_iptables -A `input_chain $interface` -s $subnet -j $chain2
|
||||
|
||||
done
|
||||
|
||||
for zone1 in $zones; do
|
||||
@ -3207,6 +3218,8 @@ activate_rules()
|
||||
|
||||
chain="`rules_chain $zone $zone1`"
|
||||
|
||||
echo "$zone $zone1 $chain" >> ${STATEDIR}/chains
|
||||
|
||||
if havechain ${zone}2${zone1} || havechain ${zone1}2${zone}; then
|
||||
have_canonical=Yes
|
||||
else
|
||||
@ -3438,6 +3451,215 @@ refresh_firewall()
|
||||
rm -rf $TMP_DIR
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Add a host or subnet to a zone #
|
||||
################################################################################
|
||||
add_to_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
||||
{
|
||||
chain_exists() # $1 = chain name
|
||||
{
|
||||
qt iptables -L $1 -n
|
||||
}
|
||||
|
||||
nat_chain_exists() # $1 = chain name
|
||||
{
|
||||
qt iptables -t nat -L $1 -n
|
||||
}
|
||||
|
||||
do_iptables() # $@ = command
|
||||
{
|
||||
if ! iptables $@ ; then
|
||||
startup_error "Error: can't add $1 to zone $2"
|
||||
fi
|
||||
}
|
||||
|
||||
output_rule_num() {
|
||||
local num=`iptables -L OUTPUT -n --line-numbers | grep common | cut -d' ' -f1 | tail -n1`
|
||||
|
||||
[ -z "$num" ] && num=`iptables -L OUTPUT -n --line-numbers | grep ACCEPT | cut -d' ' -f1 | tail -n1`
|
||||
|
||||
echo $num
|
||||
}
|
||||
|
||||
interface=${1%:*}
|
||||
host=${1#*:}
|
||||
|
||||
[ -z "$host" ] && host="0.0.0.0/0"
|
||||
|
||||
determine_zones
|
||||
|
||||
zone=$2
|
||||
|
||||
validate_zone $zone || startup_error "Error: Unknown zone: $zone"
|
||||
|
||||
[ "$zone" = $FW ] && startup_error "Error: Can't add $1 to firewall zone"
|
||||
|
||||
[ -f ${STATEDIR}/chains ] || startup_error "Error: ${STATEDIR}/chains -- file not found"
|
||||
[ -f ${STATEDIR}/zones ] || startup_error "Error: ${STATEDIR}/zones -- file not found"
|
||||
|
||||
if ! chain_exists `input_chain $interface` ; then
|
||||
startup_error "Error: Unknown interface $interface"
|
||||
fi
|
||||
|
||||
newhost="$interface:$host"
|
||||
|
||||
> ${STATEDIR}/zones_$$
|
||||
|
||||
while read z hosts; do
|
||||
if [ "$z" = "$zone" ]; then
|
||||
for h in $hosts; do
|
||||
if [ "$h" = "$newhost" ]; then
|
||||
rm -f ${STATEDIR}/zones_$$
|
||||
startup_error "Error: $1 already in zone $zone"
|
||||
fi
|
||||
done
|
||||
|
||||
[ -z "$hosts" ] && hosts=$newhost || hosts="$hosts $newhost"
|
||||
fi
|
||||
|
||||
eval ${z}_hosts=$hosts
|
||||
|
||||
echo "$z $hosts" >> ${STATEDIR}/zones_$$
|
||||
done < ${STATEDIR}/zones
|
||||
|
||||
mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones
|
||||
|
||||
chain=${zone}_dnat
|
||||
|
||||
if nat_chain_exists $chain; then
|
||||
do_iptables -t nat -A PREROUTING -i $interface -s $host -j $chain
|
||||
fi
|
||||
|
||||
while read z1 z2 chain; do
|
||||
if [ "$z1" = "$zone" ]; then
|
||||
if [ "$z2" = "$FW" ]; then
|
||||
do_iptables -A `input_chain $interface` -i $interface -s $host -j $chain
|
||||
else
|
||||
source_chain=`forward_chain $interface`
|
||||
eval dest_hosts=\$${z2}_hosts
|
||||
|
||||
for h in $dest_hosts; do
|
||||
do_iptables -A $source_chain -s $host -o ${h%:*} -d ${h#*:} -j $chain
|
||||
done
|
||||
fi
|
||||
elif [ "$z2" = "$zone" ]; then
|
||||
if [ "$z1" = "$FW" ]; then
|
||||
do_iptables -I OUTPUT `output_rule_num` $num -o $interface -d $host -j $chain
|
||||
else
|
||||
eval source_hosts=\$${z1}_hosts
|
||||
|
||||
for h in $source_hosts; do
|
||||
iface=${h%:*}
|
||||
hosts=${h#*:}
|
||||
|
||||
if [ "$iface" != "$interface" ]; then
|
||||
do_iptables -A `forward_chain $iface` -s $hosts -o $interface -d $host -j $chain
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done < ${STATEDIR}/chains
|
||||
|
||||
echo "$1 added to zone $2"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Delete a host or subnet from a zone #
|
||||
################################################################################
|
||||
delete_from_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
||||
{
|
||||
chain_exists() # $1 = chain name
|
||||
{
|
||||
qt iptables -L $1 -n
|
||||
}
|
||||
|
||||
delete_from_zones_file()
|
||||
{
|
||||
> ${STATEDIR}/zones_$$
|
||||
|
||||
while read z hosts; do
|
||||
if [ "$z" = "$zone" ]; then
|
||||
temp=$hosts
|
||||
hosts=
|
||||
|
||||
for h in $temp; do
|
||||
if [ "$h" = "$temp" ]; then
|
||||
echo Yes
|
||||
else
|
||||
hosts="$hosts $h"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo "$z $hosts" >> ${STATEDIR}/zones_$$
|
||||
done < ${STATEDIR}/zones
|
||||
|
||||
mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones
|
||||
}
|
||||
|
||||
interface=${1%:*}
|
||||
host=${1#*:}
|
||||
|
||||
[ -z "$host" ] && host="0.0.0.0/0"
|
||||
|
||||
determine_zones
|
||||
|
||||
zone=$2
|
||||
|
||||
validate_zone $zone || startup_error "Error: Unknown zone: $zone"
|
||||
|
||||
[ "$zone" = $FW ] && startup_error "Error: Can't remove $1 to firewall zone"
|
||||
|
||||
[ -f ${STATEDIR}/chains ] || startup_error "Error: ${STATEDIR}/chains -- file not found"
|
||||
[ -f ${STATEDIR}/zones ] || startup_error "Error: ${STATEDIR}/zones -- file not found"
|
||||
|
||||
if ! chain_exists `input_chain $interface` ; then
|
||||
startup_error "Error: Unknown interface $interface"
|
||||
fi
|
||||
|
||||
newhost="$interface:$host"
|
||||
|
||||
[ -z "`delete_from_zones_file`" ] && startup_error "Error: $1 not in zone $2"
|
||||
|
||||
while read z hosts; do
|
||||
eval ${z}_hosts=$hosts
|
||||
done < ${STATEDIR}/zones
|
||||
|
||||
qt iptables -t nat -D PREROUTING -i $interface -s $host -j ${zone}_dnat
|
||||
|
||||
while read z1 z2 chain; do
|
||||
if [ "$z1" = "$zone" ]; then
|
||||
if [ "$z2" = "$FW" ]; then
|
||||
qt iptables -D `input_chain $interface` -i $interface -s $host -j $chain
|
||||
else
|
||||
source_chain=`forward_chain $interface`
|
||||
eval dest_hosts=\$${z2}_hosts
|
||||
|
||||
for h in $dest_hosts; do
|
||||
qt iptables -D $source_chain -s $host -o ${h%:*} -d ${h#*:} -j $chain
|
||||
done
|
||||
fi
|
||||
elif [ "$z2" = "$zone" ]; then
|
||||
if [ "$z1" = "$FW" ]; then
|
||||
qt iptables -D OUTPUT -o $interface -d $host -j $chain
|
||||
else
|
||||
eval source_hosts=\$${z1}_hosts
|
||||
|
||||
for h in $source_hosts; do
|
||||
iface=${h%:*}
|
||||
hosts=${h#*:}
|
||||
|
||||
if [ "$iface" != "$interface" ]; then
|
||||
qt iptables -D `forward_chain $iface` -s $hosts -o $interface -d $host -j $chain
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done < ${STATEDIR}/chains
|
||||
|
||||
echo "$1 removed from zone $2"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Determine the value for a parameter that defaults to Yes #
|
||||
################################################################################
|
||||
@ -3609,7 +3831,7 @@ do_initialize() {
|
||||
# Give Usage Information #
|
||||
################################################################################
|
||||
usage() {
|
||||
echo "Usage: $0 [debug] {start|stop|reset|restart|status|refresh|clear]}"
|
||||
echo "Usage: $0 [debug] {start|stop|reset|restart|status|refresh|clear|{add|delete} <interface>[:hosts] zone}}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@ -3625,14 +3847,13 @@ nolock=
|
||||
|
||||
[ $# -gt 1 ] && [ "$1" = "nolock" ] && { nolock=Yes; shift ; }
|
||||
|
||||
[ $# -ne 1 ] && usage
|
||||
|
||||
trap "my_mutex_off; exit 2" 1 2 3 4 5 6 9
|
||||
|
||||
command="$1"
|
||||
|
||||
case "$command" in
|
||||
stop)
|
||||
[ $# -ne 1 ] && usage
|
||||
do_initialize
|
||||
my_mutex_on
|
||||
echo -n "Stopping Shorewall..."
|
||||
@ -3644,6 +3865,7 @@ case "$command" in
|
||||
;;
|
||||
|
||||
start)
|
||||
[ $# -ne 1 ] && usage
|
||||
do_initialize
|
||||
my_mutex_on
|
||||
if qt iptables -L shorewall -n ; then
|
||||
@ -3658,6 +3880,7 @@ case "$command" in
|
||||
;;
|
||||
|
||||
restart)
|
||||
[ $# -ne 1 ] && usage
|
||||
do_initialize
|
||||
my_mutex_on
|
||||
if qt iptables -L shorewall -n ; then
|
||||
@ -3672,17 +3895,20 @@ case "$command" in
|
||||
;;
|
||||
|
||||
status)
|
||||
[ $# -ne 1 ] && usage
|
||||
echo -e "Shorewall-$version Status at $HOSTNAME - `date`\\n"
|
||||
iptables -L -n -v
|
||||
;;
|
||||
|
||||
reset)
|
||||
[ $# -ne 1 ] && usage
|
||||
iptables -L -n -Z -v
|
||||
report "Shorewall Counters Reset"
|
||||
date > $STATEDIR/restarted
|
||||
;;
|
||||
|
||||
refresh)
|
||||
[ $# -ne 1 ] && usage
|
||||
do_initialize
|
||||
my_mutex_on
|
||||
if ! qt iptables -L shorewall -n ; then
|
||||
@ -3696,6 +3922,7 @@ case "$command" in
|
||||
;;
|
||||
|
||||
clear)
|
||||
[ $# -ne 1 ] && usage
|
||||
do_initialize
|
||||
my_mutex_on
|
||||
echo -n "Clearing Shorewall..."
|
||||
@ -3707,10 +3934,36 @@ case "$command" in
|
||||
;;
|
||||
|
||||
check)
|
||||
[ $# -ne 1 ] && usage
|
||||
do_initialize
|
||||
check_config
|
||||
;;
|
||||
|
||||
add)
|
||||
[ $# -ne 3 ] && usage
|
||||
do_initialize
|
||||
my_mutex_on
|
||||
if ! qt iptables -L shorewall -n ; then
|
||||
echo "Shorewall Not Started"
|
||||
[ -n "$TMP_DIR" ] && rm -rf $TMP_DIR
|
||||
my_mutex_off
|
||||
exit 2;
|
||||
fi
|
||||
add_to_zone $2 $3
|
||||
my_mutex_off
|
||||
;;
|
||||
delete)
|
||||
[ $# -ne 3 ] && usage
|
||||
do_initialize
|
||||
my_mutex_on
|
||||
if ! qt iptables -L shorewall -n ; then
|
||||
echo "Shorewall Not Started"
|
||||
[ -n "$TMP_DIR" ] && rm -rf $TMP_DIR
|
||||
my_mutex_off
|
||||
exit 2;
|
||||
fi
|
||||
delete_from_zone $2 $3
|
||||
my_mutex_off
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
|
@ -32,6 +32,8 @@
|
||||
#
|
||||
# Commands are:
|
||||
#
|
||||
# shorewall add <iface>[:<host>] zone Adds a host or subnet to a zone
|
||||
# shorewall delete <iface>[:<host>] zone Deletes a host or subnet from a zone
|
||||
# shorewall start Starts the firewall
|
||||
# shorewall restart Restarts the firewall
|
||||
# shorewall stop Stops the firewall
|
||||
@ -416,6 +418,8 @@ usage() # $1 = exit status
|
||||
{
|
||||
echo "Usage: `basename $0` [debug] [nolock] [-c <directory>] <command>"
|
||||
echo "where <command> is one of:"
|
||||
echo " add <interface>[:<host>] <zone>"
|
||||
echo " delete <interface>[:<host>] <zone>"
|
||||
echo " show [<chain>|connections|log|nat|tc|tos]"
|
||||
echo " start"
|
||||
echo " stop"
|
||||
@ -537,6 +541,10 @@ case "$1" in
|
||||
[ $# -ne 1 ] && usage 1
|
||||
exec $firewall $debugging $nolock $1
|
||||
;;
|
||||
add|delete)
|
||||
[ $# -ne 3 ] && usage 1
|
||||
exec $firewall $debugging $nolock $1 $2 $3
|
||||
;;
|
||||
show)
|
||||
[ $# -gt 2 ] && usage 1
|
||||
case "$2" in
|
||||
|
@ -19,10 +19,10 @@
|
||||
# remote getway has no fixed address (Road Warrior)
|
||||
# then specify the gateway as 0.0.0.0/0.
|
||||
#
|
||||
# GATEWAY ZONE-- Optional. If the gateway system specified in the third
|
||||
# GATEWAY ZONES -- Optional. If the gateway system specified in the third
|
||||
# column is a standalone host then this column should
|
||||
# contain the name of the zone that the host is in. This
|
||||
# column only applies to IPSEC tunnels.
|
||||
# contain a comma-separated list of the names of the zones that
|
||||
# the host might be in. This column only applies to IPSEC tunnels.
|
||||
#
|
||||
# Example 1:
|
||||
#
|
||||
@ -47,5 +47,15 @@
|
||||
#
|
||||
# ipsec net 4.33.99.124 gw
|
||||
#
|
||||
# Example 4:
|
||||
#
|
||||
# Road Warriors that may belong to zones vpn1, vpn2 or
|
||||
# vpn3. The FreeS/Wan _updown script will add the
|
||||
# host to the appropriate zone using the "shorewall add"
|
||||
# command on connect and will remove the host from the
|
||||
# zone at disconnect time.
|
||||
#
|
||||
# ipsec net 0.0.0.0/0 vpn1,vpn2,vpn3
|
||||
#
|
||||
# TYPE ZONE GATEWAY GATEWAY ZONE
|
||||
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
|
||||
|
Loading…
Reference in New Issue
Block a user