Fix problem with double-counting SYN packets.

Avoid superfluous jumps to the policy chain with CONTINUE.
Add reserved networks to rfc1918.
Implement MULTIPORT option for multiport match support.


git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@50 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2002-06-02 17:05:51 +00:00
parent 4e70354d83
commit ca9c02ce7f
4 changed files with 252 additions and 58 deletions

View File

@ -505,6 +505,15 @@ mac_match() # $1 = MAC address formated as described above
# and has loaded a space-separated list of their values in "rule". #
################################################################################
validate_rule() {
############################################################################
# Ensure that the passed comma-separated list has 15 or fewer elements
#
validate_list() {
local temp=`separate_list $1`
[ `echo $temp | wc -w` -le 15 ]
}
############################################################################
# validate one rule
#
@ -724,6 +733,16 @@ validate_rule() {
fi
dest=$serverzone
############################################################################
# Check length of port lists if MULTIPORT set
#
if [ -n "$MULTIPORT" ]; then
validate_list $ports ||
error_message "Warning: Too many destination ports: Rule \"$rule\""
validate_list $cports ||
error_message "Warning: Too many source ports: Rule \"$rule\""
fi
############################################################################
# Iterate through the various lists validating individual rules
#
@ -1360,8 +1379,12 @@ delete_tc()
# target clients servers protocol ports cports address #
# #
# and has loaded a space-separated list of their values in "rule". #
# #
# The 'multioption' variable has also been loaded appropriately to reflect #
# the setting of the MULTIPORT option in /etc/shorewall/shorewall.conf #
################################################################################
process_rule() {
############################################################################
# Add a NAT rule
#
@ -1481,24 +1504,30 @@ process_rule() {
################################################################
# Setup PROTOCOL, PORT and STATE variables
#
sports=""
dports=""
sports=
dports=
state="-m state --state NEW"
proto=$protocol
addr=$address
servport=$serverport
servport=$serverport
multiport=
case $proto in
tcp|udp|TCP|UDP|6|17)
[ -n "$port" ] && [ "x${port}" != "x-" ] && \
if [ -n "$port" -a "x${port}" != "x-" ]; then
dports="--dport $port"
[ -n "$cport" ] && [ "x${cport}" != "x-" ] && \
multiport="$multioption"
fi
if [ -n "$cport" -a "x${cport}" != "x-" ]; then
sports="--sport $cport"
multiport="$multioption"
fi
;;
icmp|ICMP|0)
[ -n "$port" ] && [ "x${port}" != "x-" ] && \
dports="--icmp-type $port"
state=""
state=
;;
all|ALL)
[ -n "$port" ] && [ "x${port}" != "x-" ] && \
@ -1552,10 +1581,11 @@ process_rule() {
serv="${serv:+-d $serv}"
[ -n "$loglevel" ] && run_iptables -A $chain $proto $state \
$cli $sports $serv $dports -j LOG $LOGPARMS --log-prefix \
"Shorewall:$chain:$logtarget:" --log-level $loglevel
run_iptables -A $chain $proto $state $cli $sports \
[ -n "$loglevel" ] && run_iptables -A $chain $proto $multiport \
$state $cli $sports $serv $dports -j LOG $LOGPARMS \
--log-prefix "Shorewall:$chain:$logtarget:" \
--log-level $loglevel
run_iptables -A $chain $proto $multiport $state $cli $sports \
$serv $dports -j $target
else
####################################################################
@ -1564,17 +1594,27 @@ process_rule() {
[ -n "$addr" ] && fatal_error \
"Error: An ADDRESS ($addr) is only allowed in" \
" a DNAT or REDIRECT: \"$rule\""
[ -n "$loglevel" ] && run_iptables -A $chain $proto \
[ -n "$loglevel" ] && run_iptables -A $chain $proto $multiport \
$dest_interface $state $cli $sports $dports -j LOG \
$LOGPARMS --log-prefix "Shorewall:$chain:$logtarget:" \
--log-level $loglevel
run_iptables -A $chain $proto $dest_interface $state \
run_iptables -A $chain $proto $multiport $dest_interface $state \
$cli $sports $dports -j $target
fi
}
############################################################################
# Return the number of elements in the passed comma-separated list
#
list_count() {
local temp=`separate_list $1`
echo $temp | wc -w
}
############################################################################
# P r o c e s s _ R u l e S t a r t s H e r e
############################################################################
@ -1674,15 +1714,32 @@ process_rule() {
############################################################################
# Iterate through the various lists creating individual rules
#
for client in `separate_list ${clients:=-}`; do
for server in `separate_list ${servers:=-}`; do
for port in `separate_list ${ports:=-}`; do
for cport in `separate_list ${cports:=-}`; do
add_a_rule
if [ -n "$MULTIPORT" -a \
"$ports" = "${ports%:*}" -a \
"$cports" = "${cports%:*}" -a \
`list_count $ports` -le 15 -a \
`list_count $cports` -le 15 ]
then
multioption="-m multiport"
for client in `separate_list ${clients:=-}`; do
for server in `separate_list ${servers:=-}`; do
port=${ports:=-}
cport=${cports:=-}
add_a_rule
done
done
else
multioption=
for client in `separate_list ${clients:=-}`; do
for server in `separate_list ${servers:=-}`; do
for port in `separate_list ${ports:=-}`; do
for cport in `separate_list ${cports:=-}`; do
add_a_rule
done
done
done
done
done
fi
echo " Rule \"$rule\" added."
}
@ -1993,16 +2050,27 @@ default_policy() # $1 = client $2 = server
local chain="${1}2${2}"
local policy=
local loglevel=
local chain1
jump_to_policy_chain() {
########################################################################
# Add a jump to from the canonical chain to the policy chain. On return,
# $chain is set to the name of the policy chain
#
run_iptables -A $chain -j $chain1
chain=$chain1
}
apply_default()
{
########################################################################
# Add the appropriate rules to the canonical chain ($chain) to enforce
# the specified policy
#-----------------------------------------------------------------------
# Construct policy chain name
#
chain1=${client}2${server}
echo " Policy $policy for $1 to $2 using chain $chain1"
if [ "$chain" = "$chain1" ]; then
####################################################################
# The policy chain is the canonical chain; add policy rule to it
@ -2011,15 +2079,48 @@ default_policy() # $1 = client $2 = server
policy_rules $chain $policy $loglevel
else
####################################################################
# Policy chain is different; add a rule to jump from the canonical
# chain to the policy chain (unless the policy is CONTINUE) and
# optionally, insert a jump to the policy chain's syn flood chain.
# The policy chain is different from the canonical chain -- approach
# depends on the policy
#
run_iptables -A $chain -j $chain1
[ -n "$synparams" ] && \
enable_syn_flood_protection $chain $chain1
case $policy in
ACCEPT)
if [ -n "$synparams" ]; then
############################################################
# To avoid double-counting SYN packets, enforce the policy
# in this chain.
#
enable_syn_flood_protection $chain $chain1
policy_rules $chain $policy $loglevel
else
############################################################
# No problem with double-counting so just jump to the
# policy chain.
#
jump_to_policy_chain
fi
;;
CONTINUE)
################################################################
# Silly to jump to the policy chain -- add any logging
# rules and enable SYN flood protection if requested
#
[ -n "$synparams" ] && \
enable_syn_flood_protection $chain $chain1
policy_rules $chain $policy $loglevel
;;
*)
################################################################
# DROP or REJECT policy -- enforce in the policy chain and
# enable SYN flood protection if requested.
#
[ -n "$synparams" ] && \
enable_syn_flood_protection $chain $chain1
jump_to_policy_chain
;;
esac
fi
echo " Policy $policy for $1 to $2 using chain $chain"
}
while read client server policy loglevel synparams; do
@ -3003,6 +3104,7 @@ do_initialize() {
CLAMPMSS=
ROUTE_FILTER=
NAT_BEFORE_RULES=
MULTIPORT=
stopping=
have_mutex=
masq_seq=1
@ -3078,6 +3180,7 @@ do_initialize() {
ADD_SNAT_ALIASES=`added_param_value_no ADD_SNAT_ALIASES $ADD_SNAT_ALIASES`
ROUTE_FILTER=`added_param_value_no ROUTE_FILTER $ROUTE_FILTER`
NAT_BEFORE_RULES=`added_param_value_yes NAT_BEFORE_RULES $NAT_BEFORE_RULES`
MULTIPORT=`added_param_value_no MULTIPORT $MULTIPORT`
}
################################################################################

View File

@ -5,6 +5,10 @@
#
# Lists the subnetworks that are blocked by the 'norfc1918' interface option.
#
# The default list includes those IP addresses listed in RFC 1918, those listed
# as 'reserved' by the IANA, the DHCP Autoconfig class B, and the class C
# reserved for use in documentation and examples.
#
# Columns are:
#
# SUBNET The subnet (host addresses also allowed)
@ -16,12 +20,31 @@
###############################################################################
#SUBNET TARGET
255.255.255.255 RETURN # We need to allow limited broadcast
169.254.0.0/16 DROP # DHCP autoconfig
0.0.0.0/8 logdrop # Reserved
1.0.0.0/8 logdrop # Reserved
2.0.0.0/8 logdrop # Reserved
5.0.0.0/8 logdrop # Reserved
7.0.0.0/8 logdrop # Reserved
10.0.0.0/8 logdrop # RFC 1918
127.0.0.0/8 logdrop # Loop Back
23.0.0.0/8 logdrop # Reserved
27.0.0.0/8 logdrop # Reserved
31.0.0.0/8 logdrop # Reserved
36.0.0.0/7 logdrop # Reserved
39.0.0.0/8 logdrop # Reserved
41.0.0.0/8 logdrop # Reserved
42.0.0.0/8 logdrop # Reserved
58.0.0.0/7 logdrop # Reserved
60.0.0.0/8 logdrop # Reserved
69.0.0.0/8 logdrop # Reserved
70.0.0.0/7 logdrop # Reserved
72.0.0.0/5 logdrop # Reserved
82.0.0.0/7 logdrop # Reserved
84.0.0.0/6 logdrop # Reserved
88.0.0.0/5 logdrop # Reserved
96.0.0.0/3 logdrop # Reserved
169.254.0.0/16 DROP # DHCP autoconfig
192.0.2.0/24 logdrop # Example addresses
192.168.0.0/16 logdrop # RFC 1918
172.16.0.0/12 logdrop # RFC 1918
240.0.0.0/4 logdrop # Reserved
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE

View File

@ -218,13 +218,13 @@ timed_read ()
}
#################################################################################
# Display the last 20 packets logged #
# Display the last $1 packets logged #
#################################################################################
packet_log()
packet_log() # $1 = number of messages
{
local options
[ -n "$realtail" ] && options="-n20"
[ -n "$realtail" ] && options="-n$1"
grep 'Shorewall:\|ipt_unclean' $LOGFILE | \
sed s/" $host kernel: Shorewall:"/" "/ | \
@ -297,23 +297,20 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that
if [ "$rejects" != "$oldrejects" ]; then
oldrejects="$rejects"
echo -e '\a'
packet_log
packet_log 20
if [ "$pause" = "Yes" ]; then
echo -en '\nEnter any character to continue: '
read foo
else
timed_read
timed_read
fi
else
if [ "$pause" != "Yes" ]; then
echo
packet_log
fi
echo
packet_log 20
timed_read
fi
clear
echo -e "$banner `date`\\n"
echo -e "NAT Status\\n"
@ -336,6 +333,54 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that
done
}
#################################################################################
# Watch the Firewall Log #
#################################################################################
logwatch() # $1 = timeout -- if negative, prompt each time that
# an 'interesting' packet count changes
{
get_config
host=`echo $HOSTNAME | sed 's/\..*$//'`
oldrejects=`iptables -L -v -n | grep 'LOG'`
if [ $1 -lt 0 ]; then
timeout=$((- $1))
pause="Yes"
else
pause="No"
timeout=$1
fi
qt which awk && haveawk=Yes || haveawk=
while true; do
clear
echo -e "$banner `date`\\n"
echo -e "Dropped/Rejected Packet Log\\n"
rejects=`iptables -L -v -n | grep 'LOG'`
if [ "$rejects" != "$oldrejects" ]; then
oldrejects="$rejects"
echo -e '\a'
packet_log 40
if [ "$pause" = "Yes" ]; then
echo -en '\nEnter any character to continue: '
read foo
else
timed_read
fi
else
echo
packet_log 40
timed_read
fi
done
}
#################################################################################
# Give Usage Information #
#################################################################################
@ -356,6 +401,7 @@ usage() # $1 = exit status
echo " version"
echo " check"
echo " try <directory> [ <timeout> ]"
echo " logwatch [<refresh interval>]"
exit $1
}
@ -473,7 +519,7 @@ case "$1" in
get_config
echo -e "Shorewall-$version Log at $HOSTNAME - `date`\\n"
host=`echo $HOSTNAME | sed 's/\..*$//'`
packet_log
packet_log 20
;;
tc)
echo -e "Shorewall-$version Traffic Control at $HOSTNAME - `date`\\n"
@ -559,6 +605,15 @@ case "$1" in
$0 restart
fi
;;
logwatch)
if [ $# -eq 2 ]; then
logwatch $2
elif [ $# -eq 1 ]; then
logwatch 30
else
usage 1
fi
;;
*)
usage 1
;;

View File

@ -37,14 +37,14 @@ STATEDIR=/var/lib/shorewall
# explicit "related" rules in /etc/shorewall/rules.
#
ALLOWRELATED="yes"
ALLOWRELATED=yes
#
# If your netfilter kernel modules are in a directory other than
# /lib/modules/`uname -r`/kernel/net/ipv4/netfilter then specify that
# directory in this variable. Example: MODULESDIR=/etc/modules.
MODULESDIR=""
MODULESDIR=
#
# The next two variables can be used to control the amount of log output
@ -57,8 +57,8 @@ MODULESDIR=""
# If BOTH variables are set empty then logging will not be rate-limited.
#
LOGRATE=""
LOGBURST=""
LOGRATE=
LOGBURST=
#
@ -80,7 +80,7 @@ LOGUNCLEAN=info
#
# http://www.shorewall.net/FAQ.htm#faq6
LOGFILE="/var/log/messages"
LOGFILE=/var/log/messages
#
# Enable nat support.
@ -88,7 +88,7 @@ LOGFILE="/var/log/messages"
# You probally want yes here. Only gateways not doing NAT in any form, like
# SNAT,DNAT masquerading, port forwading etc. should say "no" here.
#
NAT_ENABLED="Yes"
NAT_ENABLED=Yes
#
# Enable mangle support.
@ -98,7 +98,7 @@ NAT_ENABLED="Yes"
# your firewall. You must enable mangling if you want Traffic Shaping
# (see TC_ENABLED below).
#
MANGLE_ENABLED="Yes"
MANGLE_ENABLED=Yes
#
# Enable IP Forwarding
@ -112,7 +112,7 @@ MANGLE_ENABLED="Yes"
# If you set this variable to "Keep" or "keep", Shorewall will neither
# enable nor disable packet forwarding.
#
IP_FORWARDING="On"
IP_FORWARDING=On
#
# Automatically add IP Aliases
#
@ -120,7 +120,7 @@ IP_FORWARDING="On"
# for each NAT external address that you give in /etc/shorewall/nat. If you say
# "No" or "no", you must add these aliases youself.
#
ADD_IP_ALIASES="Yes"
ADD_IP_ALIASES=Yes
#
# Automatically add SNAT Aliases
@ -129,7 +129,7 @@ ADD_IP_ALIASES="Yes"
# for each SNAT external address that you give in /etc/shorewall/masq. If you say
# "No" or "no", you must add these aliases youself.
#
ADD_SNAT_ALIASES="No"
ADD_SNAT_ALIASES=No
#
# Enable Traffic Shaping
@ -139,7 +139,7 @@ ADD_SNAT_ALIASES="No"
# shaping you must have iproute[2] installed (the "ip" and "tc" utilities) and
# you must enable packet mangling above.
#
TC_ENABLED="No"
TC_ENABLED=No
#
# Blacklisting
@ -186,7 +186,7 @@ BLACKLIST_LOGLEVEL=
#
# If left blank, or set to "No" or "no", the option is not enabled.
#
CLAMPMSS="No"
CLAMPMSS=No
#
# Route Filtering
@ -196,7 +196,7 @@ CLAMPMSS="No"
#
# If this variable is not set or is set to the empty value, "No" is assumed.
ROUTE_FILTER="No"
ROUTE_FILTER=No
#
# NAT before RULES
@ -206,6 +206,19 @@ ROUTE_FILTER="No"
#
# If this variable is not set or is set to the empty value, "Yes" is assumed.
NAT_BEFORE_RULES="Yes"
NAT_BEFORE_RULES=Yes
# MULTIPORT
#
# If your kernel supports the multiport match option, you may enable it's use
# here. When this option is enabled by setting it's value to "Yes" or "yes":
#
# 1) You may not list more that 15 ports in a comma-seperated list in
# /etc/shorewall/rules.
# 2) If you include a port range (<low port>:<high port>) in the
# rule, Shorewall will not use the multiport option but will generate
# a separate rule for each element of each port list.
MULTIPORT=No
#LAST LINE -- DO NOT REMOVE