diff --git a/Shorewall/firewall b/Shorewall/firewall index 4f711d37f..acbd0e68b 100755 --- a/Shorewall/firewall +++ b/Shorewall/firewall @@ -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` } ################################################################################ diff --git a/Shorewall/rfc1918 b/Shorewall/rfc1918 index e5c369921..8f64bea7d 100644 --- a/Shorewall/rfc1918 +++ b/Shorewall/rfc1918 @@ -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 \ No newline at end of file +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall/shorewall b/Shorewall/shorewall index 7472b3f93..e21668a66 100755 --- a/Shorewall/shorewall +++ b/Shorewall/shorewall @@ -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 [ ]" + echo " logwatch []" 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 ;; diff --git a/Shorewall/shorewall.conf b/Shorewall/shorewall.conf index dbad42c9b..98e237188 100755 --- a/Shorewall/shorewall.conf +++ b/Shorewall/shorewall.conf @@ -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 (:) 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