|
|
|
@ -3609,7 +3609,7 @@ process_actions3() {
|
|
|
|
|
dropInvalid)
|
|
|
|
|
if [ "$COMMAND" != check ]; then
|
|
|
|
|
[ -n "$xlevel" ] && \
|
|
|
|
|
log_rule_limit ${xlevel%\!} $xchain dropNotSyn $2 "" "$xtag" -A -m state --state INVALID
|
|
|
|
|
log_rule_limit ${xlevel%\!} $xchain dropInvalid $2 "" "$xtag" -A -m state --state INVALID
|
|
|
|
|
run_iptables -A $xchain -m state --state INVALID -j DROP
|
|
|
|
|
fi
|
|
|
|
|
;;
|
|
|
|
@ -5622,12 +5622,13 @@ initialize_netfilter () {
|
|
|
|
|
[ -f $accounting_file ] && setup_accounting $accounting_file
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Allow DNS lookups during startup for FQDNs and deep-six INVALID packets
|
|
|
|
|
# Allow DNS lookups during startup for FQDNs
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
for chain in INPUT OUTPUT FORWARD; do
|
|
|
|
|
run_iptables -A $chain -p udp --dport 53 -j ACCEPT
|
|
|
|
|
run_iptables -A $chain -p ! icmp -m state --state INVALID -j DROP
|
|
|
|
|
[ -n "$DROPINVALID" ] && \
|
|
|
|
|
run_iptables -A $chain -p ! icmp -m state --state INVALID -j DROP
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
if [ -n "$CLAMPMSS" ]; then
|
|
|
|
@ -5785,7 +5786,7 @@ add_common_rules() {
|
|
|
|
|
network=${host#*:}
|
|
|
|
|
|
|
|
|
|
for chain in $(first_chains $interface); do
|
|
|
|
|
run_iptables -A $chain -m state --state NEW $(match_source_hosts $network) $policy -j smurfs
|
|
|
|
|
run_iptables -A $chain -m state --state NEW,INVALID $(match_source_hosts $network) $policy -j smurfs
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
@ -6276,8 +6277,16 @@ activate_rules()
|
|
|
|
|
if [ -n "$POLICY_MATCH" ]; then
|
|
|
|
|
eval is_ipsec=\$${zone}_is_ipsec
|
|
|
|
|
|
|
|
|
|
[ -n "$is_ipsec" ] && eval source_hosts=\$${zone}_hosts || eval source_hosts=\$${zone}_ipsec_hosts
|
|
|
|
|
|
|
|
|
|
if [ -n "$is_ipsec" ]; then
|
|
|
|
|
eval source_hosts=\$${zone}_hosts
|
|
|
|
|
if [ -n "$DYNAMIC_ZONES" ]; then
|
|
|
|
|
createchain ${zone}_dyn No
|
|
|
|
|
run_iptables -A $frwd_chain -j ${zone}_dyn
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
eval source_hosts=\$${zone}_ipsec_hosts
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
for host in $source_hosts; do
|
|
|
|
|
interface=${host%%:*}
|
|
|
|
|
networks=${host#*:}
|
|
|
|
@ -6636,11 +6645,11 @@ refresh_firewall()
|
|
|
|
|
#
|
|
|
|
|
# Add a host or networks to a zone
|
|
|
|
|
#
|
|
|
|
|
add_to_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
|
|
|
|
add_to_zone() # $1...${n-1} = <interface>[:<hosts>] $n = zone
|
|
|
|
|
{
|
|
|
|
|
local base interface host newhost zone z h z1 z2 chain terminator
|
|
|
|
|
local interface host zone z h z1 z2 chain
|
|
|
|
|
local dhcp_interfaces blacklist_interfaces maclist_interfaces tcpflags_interfaces
|
|
|
|
|
local rulenum source_chain dest_hosts iface hosts is_ipsec policyin= policyout=
|
|
|
|
|
local rulenum source_chain dest_hosts iface hosts hostlist=
|
|
|
|
|
|
|
|
|
|
nat_chain_exists() # $1 = chain name
|
|
|
|
|
{
|
|
|
|
@ -6653,17 +6662,10 @@ add_to_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
|
|
|
|
[ -n "$IPRANGE_MATCH" ] && [ -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange
|
|
|
|
|
|
|
|
|
|
if ! $IPTABLES $@ ; then
|
|
|
|
|
startup_error "Can't add $1 to zone $2"
|
|
|
|
|
error_message "Can't add $newhost to zone $zone"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Isolate interface and host parts
|
|
|
|
|
#
|
|
|
|
|
interface=${1%%:*}
|
|
|
|
|
host=${1#*:}
|
|
|
|
|
|
|
|
|
|
[ -z "$host" ] && host="0.0.0.0/0"
|
|
|
|
|
#
|
|
|
|
|
# Load $zones
|
|
|
|
|
#
|
|
|
|
@ -6673,74 +6675,260 @@ add_to_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
|
|
|
|
#
|
|
|
|
|
validate_interfaces_file
|
|
|
|
|
#
|
|
|
|
|
# Validate Hosts File
|
|
|
|
|
#
|
|
|
|
|
validate_hosts_file
|
|
|
|
|
#
|
|
|
|
|
# Validate IPSec File
|
|
|
|
|
#
|
|
|
|
|
f=$(find_file ipsec)
|
|
|
|
|
|
|
|
|
|
if [ -f $f ]; then
|
|
|
|
|
progress_message "Processing $f..."
|
|
|
|
|
setup_ipsec $f
|
|
|
|
|
fi
|
|
|
|
|
[ -f $f ] && setup_ipsec $f
|
|
|
|
|
#
|
|
|
|
|
# Normalize host list
|
|
|
|
|
#
|
|
|
|
|
while [ $# -gt 1 ]; do
|
|
|
|
|
interface=${1%%:*}
|
|
|
|
|
host=${1#*:}
|
|
|
|
|
#
|
|
|
|
|
# Be sure that the interface was dynamic at last [re]start
|
|
|
|
|
#
|
|
|
|
|
if ! chain_exists $(input_chain $interface) ; then
|
|
|
|
|
startup_error "Unknown interface $interface"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! chain_exists $(dynamic_in $interface) ; then
|
|
|
|
|
startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ -z "$host" ]; then
|
|
|
|
|
hostlist="$hostlist $interface:0.0.0.0/0"
|
|
|
|
|
else
|
|
|
|
|
for h in $(separate_list $host); do
|
|
|
|
|
hostlist="$hostlist $interface:$h"
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
shift
|
|
|
|
|
done
|
|
|
|
|
#
|
|
|
|
|
# Validate Zone
|
|
|
|
|
#
|
|
|
|
|
zone=$2
|
|
|
|
|
zone=$1
|
|
|
|
|
|
|
|
|
|
validate_zone $zone || startup_error "Unknown zone: $zone"
|
|
|
|
|
|
|
|
|
|
[ "$zone" = $FW ] && startup_error "Can't add $1 to firewall zone"
|
|
|
|
|
|
|
|
|
|
eval is_ipsec=\$${zone}_is_ipsec
|
|
|
|
|
eval options=\"\$${zone}_ipsec_options\"
|
|
|
|
|
eval in_options=\"\$${zone}_ipsec_in_options\"
|
|
|
|
|
eval out_options=\"\$${zone}_ipsec_out_options\"
|
|
|
|
|
|
|
|
|
|
if [ -n "$is_ipsec" ]; then
|
|
|
|
|
[ -n "$POLICY_MATCH" ] || startup_error "Your kernel and/or iptables lacks policy match support"
|
|
|
|
|
policyin="-m policy --pol ipsec --dir in $options $in_options"
|
|
|
|
|
policyout="-m policy --pol ipsec --dir out $options $out_options"
|
|
|
|
|
elif [ -n "$POLICY_MATCH" ]; then
|
|
|
|
|
policyin="-m policy --pol none --dir in"
|
|
|
|
|
policyout="-m policy --pol none --dir out"
|
|
|
|
|
fi
|
|
|
|
|
#
|
|
|
|
|
# Be sure that Shorewall has been restarted using a DZ-aware version of the code
|
|
|
|
|
#
|
|
|
|
|
[ -f ${STATEDIR}/chains ] || startup_error "${STATEDIR}/chains -- file not found"
|
|
|
|
|
[ -f ${STATEDIR}/zones ] || startup_error "${STATEDIR}/zones -- file not found"
|
|
|
|
|
#
|
|
|
|
|
# Be sure that the interface was dynamic at last [re]start
|
|
|
|
|
# Check for duplicates and create a new zone state file
|
|
|
|
|
#
|
|
|
|
|
if ! chain_exists $(input_chain $interface) ; then
|
|
|
|
|
startup_error "Unknown interface $interface"
|
|
|
|
|
fi
|
|
|
|
|
> ${STATEDIR}/zones_$$
|
|
|
|
|
|
|
|
|
|
if ! chain_exists $(dynamic_in $interface) ; then
|
|
|
|
|
startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf"
|
|
|
|
|
fi
|
|
|
|
|
#
|
|
|
|
|
# Normalize the first argument to this function
|
|
|
|
|
#
|
|
|
|
|
newhost="$interface:$host"
|
|
|
|
|
while read z hosts; do
|
|
|
|
|
if [ "$z" = "$zone" ]; then
|
|
|
|
|
for h in $hosts; do
|
|
|
|
|
for host in $hostlist; do
|
|
|
|
|
if [ "$h" = "$host" ]; then
|
|
|
|
|
rm -f ${STATEDIR}/zones_$$
|
|
|
|
|
startup_error "$host already in zone $zone"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
[ -z "$hosts" ] && hosts=$hostlist || hosts="$hosts $hostlist"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
eval ${z}_hosts=\"$hosts\"
|
|
|
|
|
|
|
|
|
|
echo "$z $hosts" >> ${STATEDIR}/zones_$$
|
|
|
|
|
done < ${STATEDIR}/zones
|
|
|
|
|
|
|
|
|
|
mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones
|
|
|
|
|
|
|
|
|
|
terminator=fatal_error
|
|
|
|
|
#
|
|
|
|
|
# Create a new Zone state file
|
|
|
|
|
#
|
|
|
|
|
for newhost in $hostlist; do
|
|
|
|
|
#
|
|
|
|
|
# Isolate interface and host parts
|
|
|
|
|
#
|
|
|
|
|
interface=${newhost%%:*}
|
|
|
|
|
host=${newhost#*:}
|
|
|
|
|
#
|
|
|
|
|
# If the zone passed in the command has a dnat chain then insert a rule in
|
|
|
|
|
# the nat table PREROUTING chain to jump to that chain when the source
|
|
|
|
|
# matches the new host(s)#
|
|
|
|
|
#
|
|
|
|
|
chain=${zone}_dnat
|
|
|
|
|
|
|
|
|
|
if nat_chain_exists $chain; then
|
|
|
|
|
do_iptables -t nat -A $(dynamic_in $interface) $(source_ip_range $host) $(match_ipsec_in $zone $newhost) -j $chain
|
|
|
|
|
fi
|
|
|
|
|
#
|
|
|
|
|
# Insert new rules into the filter table for the passed interface
|
|
|
|
|
#
|
|
|
|
|
while read z1 z2 chain; do
|
|
|
|
|
if [ "$z1" = "$zone" ]; then
|
|
|
|
|
if [ "$z2" = "$FW" ]; then
|
|
|
|
|
do_iptables -A $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j $chain
|
|
|
|
|
else
|
|
|
|
|
source_chain=$(dynamic_fwd $interface)
|
|
|
|
|
if is_ipsec_host $z1 $newhost ; then
|
|
|
|
|
do_iptables -A $source_chain $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j ${z1}_frwd
|
|
|
|
|
else
|
|
|
|
|
eval dest_hosts=\"\$${z2}_hosts\"
|
|
|
|
|
|
|
|
|
|
for h in $dest_hosts; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
do_iptables -A $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $(match_ipsec_out $z2 $h) -j $chain
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
elif [ "$z2" = "$zone" ]; then
|
|
|
|
|
if [ "$z1" = "$FW" ]; then
|
|
|
|
|
#
|
|
|
|
|
# Add a rule to the dynamic out chain for the interface
|
|
|
|
|
#
|
|
|
|
|
do_iptables -A $(dynamic_out $interface) $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain
|
|
|
|
|
else
|
|
|
|
|
eval source_hosts=\"\$${z1}_hosts\"
|
|
|
|
|
|
|
|
|
|
for h in $source_hosts; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
if is_ipsec_host $z1 $h; then
|
|
|
|
|
do_iptables -A ${z1}_dyn -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain
|
|
|
|
|
else
|
|
|
|
|
do_iptables -A $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
done < ${STATEDIR}/chains
|
|
|
|
|
|
|
|
|
|
progress_message "$newhost added to zone $zone"
|
|
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
rm -rf $TMP_DIR
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Delete a host or networks from a zone
|
|
|
|
|
#
|
|
|
|
|
delete_from_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
|
|
|
|
{
|
|
|
|
|
local interface host zone z h z1 z2 chain delhost
|
|
|
|
|
local dhcp_interfaces blacklist_interfaces maclist_interfaces tcpflags_interfaces
|
|
|
|
|
local rulenum source_chain dest_hosts iface hosts hostlist=
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Load $zones
|
|
|
|
|
#
|
|
|
|
|
determine_zones
|
|
|
|
|
#
|
|
|
|
|
# Validate Interfaces File
|
|
|
|
|
#
|
|
|
|
|
validate_interfaces_file
|
|
|
|
|
#
|
|
|
|
|
# Validate Hosts File
|
|
|
|
|
#
|
|
|
|
|
validate_hosts_file
|
|
|
|
|
#
|
|
|
|
|
# Validate IPSec File
|
|
|
|
|
#
|
|
|
|
|
f=$(find_file ipsec)
|
|
|
|
|
|
|
|
|
|
[ -f $f ] && setup_ipsec $f
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Normalize host list
|
|
|
|
|
#
|
|
|
|
|
while [ $# -gt 1 ]; do
|
|
|
|
|
interface=${1%%:*}
|
|
|
|
|
host=${1#*:}
|
|
|
|
|
#
|
|
|
|
|
# Be sure that the interface was dynamic at last [re]start
|
|
|
|
|
#
|
|
|
|
|
if ! chain_exists $(input_chain $interface) ; then
|
|
|
|
|
startup_error "Unknown interface $interface"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! chain_exists $(dynamic_in $interface) ; then
|
|
|
|
|
startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ -z "$host" ]; then
|
|
|
|
|
hostlist="$hostlist $interface:0.0.0.0/0"
|
|
|
|
|
else
|
|
|
|
|
for h in $(separate_list $host); do
|
|
|
|
|
hostlist="$hostlist $interface:$h"
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
shift
|
|
|
|
|
done
|
|
|
|
|
#
|
|
|
|
|
# Validate Zone
|
|
|
|
|
#
|
|
|
|
|
zone=$1
|
|
|
|
|
|
|
|
|
|
validate_zone $zone || startup_error "Unknown zone: $zone"
|
|
|
|
|
|
|
|
|
|
[ "$zone" = $FW ] && startup_error "Can't delete from the firewall zone"
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Be sure that Shorewall has been restarted using a DZ-aware version of the code
|
|
|
|
|
#
|
|
|
|
|
[ -f ${STATEDIR}/chains ] || startup_error "${STATEDIR}/chains -- file not found"
|
|
|
|
|
[ -f ${STATEDIR}/zones ] || startup_error "${STATEDIR}/zones -- file not found"
|
|
|
|
|
#
|
|
|
|
|
# Delete the passed hosts from the zone state file
|
|
|
|
|
#
|
|
|
|
|
> ${STATEDIR}/zones_$$
|
|
|
|
|
#
|
|
|
|
|
# Add $1 to the Zone state file
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
while read z hosts; do
|
|
|
|
|
if [ "$z" = "$zone" ]; then
|
|
|
|
|
for h in $hosts; do
|
|
|
|
|
if [ "$h" = "$newhost" ]; then
|
|
|
|
|
rm -f ${STATEDIR}/zones_$$
|
|
|
|
|
startup_error "$1 already in zone $zone"
|
|
|
|
|
fi
|
|
|
|
|
temp=$hosts
|
|
|
|
|
hosts=
|
|
|
|
|
|
|
|
|
|
for host in $hostlist; do
|
|
|
|
|
found=
|
|
|
|
|
for h in $temp; do
|
|
|
|
|
if [ "$h" = "$host" ]; then
|
|
|
|
|
found=Yes
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
[ -n "$found" ] || error_message "Warning: $1 does not appear to be in zone $2"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
[ -z "$hosts" ] && hosts=$newhost || hosts="$hosts $newhost"
|
|
|
|
|
for h in $temp; do
|
|
|
|
|
found=
|
|
|
|
|
for host in $hostlist; do
|
|
|
|
|
if [ "$h" = "$host" ]; then
|
|
|
|
|
found=Yes
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
[ -n "$found" ] || hosts="$hosts $h"
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
eval ${z}_hosts=\"$hosts\"
|
|
|
|
@ -6749,207 +6937,69 @@ add_to_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
|
|
|
|
done < ${STATEDIR}/zones
|
|
|
|
|
|
|
|
|
|
mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones
|
|
|
|
|
#
|
|
|
|
|
# If the zone passed in the command has a dnat chain then insert a rule in
|
|
|
|
|
# the nat table PREROUTING chain to jump to that chain when the source
|
|
|
|
|
# matches the new host(s)#
|
|
|
|
|
#
|
|
|
|
|
chain=${zone}_dnat
|
|
|
|
|
|
|
|
|
|
if nat_chain_exists $chain; then
|
|
|
|
|
do_iptables -t nat -A $(dynamic_in $interface) $(source_ip_range $host) $policyin -j $chain
|
|
|
|
|
fi
|
|
|
|
|
#
|
|
|
|
|
# Insert new rules into the filter table for the passed interface
|
|
|
|
|
#
|
|
|
|
|
while read z1 z2 chain; do
|
|
|
|
|
if [ "$z1" = "$zone" ]; then
|
|
|
|
|
if [ "$z2" = "$FW" ]; then
|
|
|
|
|
do_iptables -A $(dynamic_in $interface) $(match_source_hosts $host) $policyin -j $chain
|
|
|
|
|
else
|
|
|
|
|
source_chain=$(dynamic_fwd $interface)
|
|
|
|
|
eval dest_hosts=\"\$${z2}_hosts\"
|
|
|
|
|
|
|
|
|
|
for h in $dest_hosts; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
do_iptables -A $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $policyout -j $chain
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
elif [ "$z2" = "$zone" ]; then
|
|
|
|
|
if [ "$z1" = "$FW" ]; then
|
|
|
|
|
#
|
|
|
|
|
# Add a rule to the dynamic out chain for the interface
|
|
|
|
|
#
|
|
|
|
|
do_iptables -A $(dynamic_out $interface) $(match_dest_hosts $host) $policyout -j $chain
|
|
|
|
|
else
|
|
|
|
|
eval source_hosts=\"\$${z1}_hosts\"
|
|
|
|
|
|
|
|
|
|
for h in $source_hosts; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
do_iptables -A $(dynamic_fwd $iface) $rulenum $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $policyout -j $chain
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
done < ${STATEDIR}/chains
|
|
|
|
|
|
|
|
|
|
rm -rf $TMP_DIR
|
|
|
|
|
|
|
|
|
|
progress_message "$1 added to zone $2"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Delete a host or networks from a zone
|
|
|
|
|
#
|
|
|
|
|
delete_from_zone() # $1 = <interface>[:<hosts>] $2 = zone
|
|
|
|
|
{
|
|
|
|
|
#
|
|
|
|
|
# Delete the subject host(s) from the zone state file
|
|
|
|
|
#
|
|
|
|
|
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" = "$delhost" ]; then
|
|
|
|
|
echo Yes
|
|
|
|
|
else
|
|
|
|
|
hosts="$hosts $h"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "$z $hosts" >> ${STATEDIR}/zones_$$
|
|
|
|
|
done < ${STATEDIR}/zones
|
|
|
|
|
|
|
|
|
|
mv -f ${STATEDIR}/zones_$$ ${STATEDIR}/zones
|
|
|
|
|
}
|
|
|
|
|
#
|
|
|
|
|
# Isolate interface and host parts
|
|
|
|
|
#
|
|
|
|
|
interface=${1%%:*}
|
|
|
|
|
host=${1#*:}
|
|
|
|
|
|
|
|
|
|
[ -z "$host" ] && host="0.0.0.0/0"
|
|
|
|
|
#
|
|
|
|
|
# Load $zones
|
|
|
|
|
#
|
|
|
|
|
determine_zones
|
|
|
|
|
|
|
|
|
|
f=$(find_file ipsec)
|
|
|
|
|
if [ -f $f ]; then
|
|
|
|
|
progress_message "Processing $f..."
|
|
|
|
|
setup_ipsec $f
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
zone=$2
|
|
|
|
|
|
|
|
|
|
validate_zone $zone || startup_error "Unknown zone: $zone"
|
|
|
|
|
|
|
|
|
|
[ "$zone" = $FW ] && startup_error "Can't remove $1 from firewall zone"
|
|
|
|
|
|
|
|
|
|
eval is_ipsec=\$${zone}_is_ipsec
|
|
|
|
|
eval options=\"\$${zone}_ipsec_options\"
|
|
|
|
|
eval in_options=\"\$${zone}_ipsec_in_options\"
|
|
|
|
|
eval out_options=\"\$${zone}_ipsec_out_options\"
|
|
|
|
|
|
|
|
|
|
if [ -n "$is_ipsec" ]; then
|
|
|
|
|
[ -n "$POLICY_MATCH" ] || startup_error "Your kernel and/or iptables lacks policy match support"
|
|
|
|
|
policyin="-m policy --pol ipsec --dir in $options $in_options"
|
|
|
|
|
policyout="-m policy --pol ipsec --dir out $options $out_options"
|
|
|
|
|
elif [ -n "$POLICY_MATCH" ]; then
|
|
|
|
|
policyin="-m policy --pol none --dir in"
|
|
|
|
|
policyout="-m policy --pol none --dir out"
|
|
|
|
|
fi
|
|
|
|
|
#
|
|
|
|
|
# Be sure that Shorewall has been restarted using a DZ-aware version of the code
|
|
|
|
|
#
|
|
|
|
|
[ -f ${STATEDIR}/chains ] || startup_error "${STATEDIR}/chains -- file not found"
|
|
|
|
|
[ -f ${STATEDIR}/zones ] || startup_error "${STATEDIR}/zones -- file not found"
|
|
|
|
|
#
|
|
|
|
|
# Be sure that the interface was present at last [re]start
|
|
|
|
|
#
|
|
|
|
|
if ! chain_exists $(input_chain $interface) ; then
|
|
|
|
|
startup_error "Unknown interface $interface"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! chain_exists $(dynamic_in $interface) ; then
|
|
|
|
|
startup_error "Interface $interface is not dynamic"
|
|
|
|
|
fi
|
|
|
|
|
#
|
|
|
|
|
# Normalize the first argument to this function
|
|
|
|
|
#
|
|
|
|
|
delhost="$interface:$host"
|
|
|
|
|
#
|
|
|
|
|
# Delete the passed hosts from the zone state file
|
|
|
|
|
#
|
|
|
|
|
[ -z "$(delete_from_zones_file)" ] && \
|
|
|
|
|
error_message "Warning: $1 does not appear to be in zone $2"
|
|
|
|
|
#
|
|
|
|
|
# Construct the zone host maps
|
|
|
|
|
#
|
|
|
|
|
while read z hosts; do
|
|
|
|
|
eval ${z}_hosts=\"$hosts\"
|
|
|
|
|
done < ${STATEDIR}/zones
|
|
|
|
|
|
|
|
|
|
terminator=fatal_error
|
|
|
|
|
#
|
|
|
|
|
# Delete any nat table entries for the host(s)
|
|
|
|
|
#
|
|
|
|
|
qt_iptables -t nat -D $(dynamic_in $interface) $(match_source_hosts $host) $policyin -j ${zone}_dnat
|
|
|
|
|
#
|
|
|
|
|
# Delete rules rules the input chains for the passed interface
|
|
|
|
|
#
|
|
|
|
|
while read z1 z2 chain; do
|
|
|
|
|
if [ "$z1" = "$zone" ]; then
|
|
|
|
|
if [ "$z2" = "$FW" ]; then
|
|
|
|
|
qt_iptables -D $(dynamic_in $interface) $(match_source_hosts $host) $policyin -j $chain
|
|
|
|
|
else
|
|
|
|
|
source_chain=$(dynamic_fwd $interface)
|
|
|
|
|
eval dest_hosts=\"\$${z2}_hosts\"
|
|
|
|
|
|
|
|
|
|
for h in $dest_hosts $delhost; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
for delhost in $hostlist; do
|
|
|
|
|
interface=${delhost%%:*}
|
|
|
|
|
host=${delhost#*:}
|
|
|
|
|
#
|
|
|
|
|
# Delete any nat table entries for the host(s)
|
|
|
|
|
#
|
|
|
|
|
qt_iptables -t nat -D $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $zone $delhost) -j ${zone}_dnat
|
|
|
|
|
#
|
|
|
|
|
# Delete rules rules the input chains for the passed interface
|
|
|
|
|
#
|
|
|
|
|
while read z1 z2 chain; do
|
|
|
|
|
if [ "$z1" = "$zone" ]; then
|
|
|
|
|
if [ "$z2" = "$FW" ]; then
|
|
|
|
|
qt_iptables -D $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $z1 $delhost) -j $chain
|
|
|
|
|
else
|
|
|
|
|
source_chain=$(dynamic_fwd $interface)
|
|
|
|
|
if is_ipsec_host $z1 $delhost ; then
|
|
|
|
|
qt_iptables -D $source_chain $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j ${z1}_frwd
|
|
|
|
|
else
|
|
|
|
|
eval dest_hosts=\"\$${z2}_hosts\"
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
qt_iptables -D $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $policyout -j $chain
|
|
|
|
|
[ "$z2" = "$zone" ] && dest_hosts="$dest_hosts $hostlist"
|
|
|
|
|
|
|
|
|
|
for h in $dest_hosts; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
qt_iptables -D $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $(match_ipsec_out $z2 $h) -j $chain
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
elif [ "$z2" = "$zone" ]; then
|
|
|
|
|
if [ "$z1" = "$FW" ]; then
|
|
|
|
|
qt_iptables -D $(dynamic_out $interface) $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain
|
|
|
|
|
else
|
|
|
|
|
eval source_hosts=\"\$${z1}_hosts\"
|
|
|
|
|
|
|
|
|
|
for h in $source_hosts; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
if is_ipsec_host $z1 $h; then
|
|
|
|
|
qt_iptables -D ${z1}_dyn -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain
|
|
|
|
|
else
|
|
|
|
|
qt_iptables -D $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
elif [ "$z2" = "$zone" ]; then
|
|
|
|
|
if [ "$z1" = "$FW" ]; then
|
|
|
|
|
qt_iptables -D $(dynamic_out $interface) $(match_dest_hosts $host) $policyout -j $chain
|
|
|
|
|
else
|
|
|
|
|
eval source_hosts=\"\$${z1}_hosts\"
|
|
|
|
|
|
|
|
|
|
for h in $source_hosts; do
|
|
|
|
|
iface=${h%%:*}
|
|
|
|
|
hosts=${h#*:}
|
|
|
|
|
done < ${STATEDIR}/chains
|
|
|
|
|
|
|
|
|
|
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
|
|
|
|
|
qt_iptables -D $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $policyout -j $chain
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
done < ${STATEDIR}/chains
|
|
|
|
|
progress_message "$delhost removed from zone $zone"
|
|
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
rm -rf $TMP_DIR
|
|
|
|
|
|
|
|
|
|
progress_message "$1 removed from zone $2"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
@ -7066,6 +7116,7 @@ do_initialize() {
|
|
|
|
|
DELAYBLACKLISTLOAD=
|
|
|
|
|
LOGTAGONLY=
|
|
|
|
|
LOGALLNEW=
|
|
|
|
|
DROPINVALID=
|
|
|
|
|
|
|
|
|
|
RESTOREBASE=
|
|
|
|
|
TMP_DIR=
|
|
|
|
@ -7121,7 +7172,7 @@ do_initialize() {
|
|
|
|
|
ensure_config_path
|
|
|
|
|
#
|
|
|
|
|
# Determine the capabilities of the installed iptables/netfilter
|
|
|
|
|
# We load the kernel modules here to acurately determine
|
|
|
|
|
# We load the kernel modules here to acuray determine
|
|
|
|
|
# capabilities when module autoloading isn't enabled.
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
@ -7260,6 +7311,7 @@ do_initialize() {
|
|
|
|
|
RETAIN_ALIASES=$(added_param_value_no RETAIN_ALIASES $RETAIN_ALIASES)
|
|
|
|
|
DELAYBLACKLISTLOAD=$(added_param_value_no DELAYBLACKLISTLOAD $DELAYBLACKLISTLOAD)
|
|
|
|
|
LOGTAGONLY=$(added_param_value_no LOGTAGONLY $LOGTAGONLY)
|
|
|
|
|
DROPINVALID=$(added_param_value_yes DROPINVALID $DROPINVALID)
|
|
|
|
|
#
|
|
|
|
|
# Strip the files that we use often
|
|
|
|
|
#
|
|
|
|
@ -7406,7 +7458,7 @@ case "$COMMAND" in
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
add)
|
|
|
|
|
[ $# -ne 3 ] && usage
|
|
|
|
|
[ $# -lt 3 ] && usage
|
|
|
|
|
do_initialize
|
|
|
|
|
my_mutex_on
|
|
|
|
|
if ! qt $IPTABLES -L shorewall -n ; then
|
|
|
|
@ -7415,12 +7467,13 @@ case "$COMMAND" in
|
|
|
|
|
my_mutex_off
|
|
|
|
|
exit 2;
|
|
|
|
|
fi
|
|
|
|
|
add_to_zone $2 $3
|
|
|
|
|
shift
|
|
|
|
|
add_to_zone $@
|
|
|
|
|
my_mutex_off
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
delete)
|
|
|
|
|
[ $# -ne 3 ] && usage
|
|
|
|
|
[ $# -lt 3 ] && usage
|
|
|
|
|
do_initialize
|
|
|
|
|
my_mutex_on
|
|
|
|
|
if ! qt $IPTABLES -L shorewall -n ; then
|
|
|
|
@ -7429,7 +7482,8 @@ case "$COMMAND" in
|
|
|
|
|
my_mutex_off
|
|
|
|
|
exit 2;
|
|
|
|
|
fi
|
|
|
|
|
delete_from_zone $2 $3
|
|
|
|
|
shift
|
|
|
|
|
delete_from_zone $@
|
|
|
|
|
my_mutex_off
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|