diff --git a/STABLE2/changelog.txt b/STABLE2/changelog.txt
index f168513dd..666c63b2d 100644
--- a/STABLE2/changelog.txt
+++ b/STABLE2/changelog.txt
@@ -1,74 +1,40 @@
-Changes since 1.4.10
+Changes since 2.0.0
-1) Remove 'unclean' support.
+1) Eliminate Warning about Policy as rule when using actions.
-2) Remove NAT_BEFORE_RULES.
+2) Add bridging Code.
-3) Remove HAVEROUTE column from ProxyARP.
+3) Cleanup Warning elimination.
-4) Change default for ALL INTERFACES in /etc/shorewall/nat.
+4) Add 'nobogons'
-5) Rename the product to Shorewall2.
+5) Add 'netmap'
-6) Remove common chain.
+6) Fix another _frwd problem.
-7) Add default action mechanism.
+7) Add -x option to /sbin/shorewall.
-8) Add USER/GROUP column to /etc/shorewall2/action.template.
+8) Implement Sean Mathews's fix fix Proxy ARP and IPSEC.
-9) Get installer/uninstaller to work.
+9) Improve zone-definition checking.
-10) Restore HAVEROUTE and add PERSISTENT column to the proxy arp file.
+10) Add additional options to hosts file
-11) Install correct init script on Debian.
+11) Replace 'subnet' with 'network' in the code
-12) Get the attention of 'logunclean' and 'dropunclean' users.
+12) Fix item 10 above :-(
-13) Replace all instances of `...` with $(...) for readability.
+13) Replace good code with crap to satisfy 'ash'.
-14) Add action.AllowSNMP
+14) Fix if_match to only do wild-card matches on patterns ending in
+ "+".
-15) Move some code from firewall to functions
+15) Tighten edits on bridge port names.
-16) Removed the DropBcast and DropNonSyn actions and replaced them with
- builtin actions dropBcast and dropNonSyn.
+16) Make 'routeback' on interfaces work again.
-17) Make "trace" a synonym for "debug"
+17) Reduce useless intra-zone rules on bridges.
-18) Add the ":noah" option to IPSEC tunnels.
+18) Make 'routeback' on hosts work again.
-19) Added a comment to the rules file to aid users who are terminally stupid.
-
-20) Only create the action chains that are actually used.
-
-21) Move actions.std and action.* files to /usr/share/shorewall.
-
-22) Added DISABLE_IPV6 option.
-
-23) Allow rate limiting on CONTINUE and REJECT.
-
-24) Move rfc1918 to /usr/share/shorewall
-
-25) Make detectnets and routeback play nice together.
-
-26) Avoid superfluous --state NEW tests.
-
-27) Allow backrouting of 'routestopped' devices.
-
-28) Fix the help file.
-
-29) Correct handling of !z1,z2,... in a DNAT/REDIRECT rule.
-
-30) Remove fw->fw policy.
-
-31) Issue clearer message if ip6tables not installed.
-
-32) Make 'CONTINUE' rules work again.
-
-33) Correct a comment in the rules file. Update for 2.0.0 final release.
-
-34) Eliminate Warning about Policy as rule when using actions.
-
-35) Implement Sean Mathews's fix for Proxy ARP/IPSEC.
-
-36) Fix default value of ALL INTERFACES in /etc/shorewall/nat.
+19) Fix display of ICMP packets.
diff --git a/STABLE2/fallback.sh b/STABLE2/fallback.sh
index 6aa8f8bb4..d3a8ab1e7 100755
--- a/STABLE2/fallback.sh
+++ b/STABLE2/fallback.sh
@@ -28,7 +28,7 @@
# shown below. Simply run this script to revert to your prior version of
# Shoreline Firewall.
-VERSION=2.0.0b
+VERSION=2.0.1
usage() # $1 = exit status
{
@@ -91,6 +91,8 @@ restore_file /etc/shorewall/rules
restore_file /etc/shorewall/nat
+restore_file /etc/shorewall/netmap
+
restore_file /etc/shorewall/params
restore_file /etc/shorewall/proxyarp
@@ -116,6 +118,8 @@ restore_file /etc/shorewall/whitelist
restore_file /etc/shorewall/rfc1918
restore_file /usr/share/shorewall/rfc1918
+restore_file /usr/share/shorewall/bogons
+
restore_file /etc/shorewall/init
restore_file /etc/shorewall/start
diff --git a/STABLE2/firewall b/STABLE2/firewall
index a76cdb105..ebaea2e66 100755
--- a/STABLE2/firewall
+++ b/STABLE2/firewall
@@ -99,6 +99,8 @@ report () { # $* = message
#
run_iptables() {
+ [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev
+
if ! iptables $@ ; then
[ -z "$stopping" ] && { stop_firewall; exit 2; }
fi
@@ -423,6 +425,100 @@ first_chains() #$1 = interface
echo ${c}_fwd ${c}_in
}
+#
+# Horrible hack to work around an iptables bug
+#
+physdev_echo()
+{
+ if [ -f $TMP_DIR/physdev ]; then
+ echo $@
+ else
+ echo -m physdev $@
+ > $TMP_DIR/physdev
+ fi
+}
+
+#
+# We allow hosts to be specified by IP address or by physdev. These two functions
+# are used to produce the proper match in a netfilter rule.
+#
+match_source_hosts()
+{
+ if [ -n "$BRIDGING" ]; then
+ case $1 in
+ *:*)
+ physdev_echo "--physdev-in ${1%:*} -s ${1#*:}"
+ ;;
+ *.*.*.*)
+ echo -s $1
+ ;;
+ *)
+ physdev_echo "--physdev-in $1"
+ ;;
+ esac
+ else
+ echo -s $1
+ fi
+}
+
+match_dest_hosts()
+{
+ if [ -n "$BRIDGING" ]; then
+ case $1 in
+ *:*)
+ physdev_echo "--physdev-out ${1%:*} -d ${1#*:}"
+ ;;
+ *.*.*.*)
+ echo -d $1
+ ;;
+ *)
+ physdev_echo "--physdev-out $1"
+ ;;
+ esac
+ else
+ echo -d $1
+ fi
+}
+#
+# Similarly, the source or destination in a rule can be qualified by a device name. If
+# the device is defined in /etc/shorewall/interfaces then a normal interface match is
+# generated (-i or -o); otherwise, a physdev match is generated.
+#-------------------------------------------------------------------------------------
+#
+# loosely match the passed interface with those in /etc/shorewall/interfaces.
+#
+known_interface() # $1 = interface name
+{
+ local iface
+
+ for iface in $all_interfaces ; do
+ if if_match $iface $1 ; then
+ return 0
+ fi
+ done
+
+ return 1
+}
+
+match_source_dev()
+{
+ if [ -n "$BRIDGING" ]; then
+ known_interface $1 && echo -i $1 || physdev_echo "--physdev-in $1"
+ else
+ echo -i $1
+ fi
+}
+
+match_dest_dev()
+{
+ if [ -n "$BRIDGING" ]; then
+ known_interface $1 && echo -o $1 || physdev_echo "--physdev-out $1"
+ else
+ echo -o $1
+ fi
+}
+
+#
#
# Find hosts in a given zone
#
@@ -436,7 +532,7 @@ find_hosts() # $1 = host zone
while read z hosts options; do
if [ "x$(expand $z)" = "x$1" ]; then
expandv hosts
- interface=${hosts%:*}
+ interface=${hosts%%:*}
addresses=${hosts#*:}
for address in $(separate_list $addresses); do
echo $interface:$address
@@ -459,6 +555,18 @@ determine_interfaces() {
done
}
+#
+# Determine if an interface has a given option
+#
+interface_has_option() # $1 = interface, #2 = option
+{
+ local options
+
+ eval options=\$$(chain_base $1)_options
+
+ list_search $2 $options
+}
+
#
# Determine the defined hosts in each zone and generate report
#
@@ -471,22 +579,21 @@ determine_hosts() {
eval interfaces=\$${zone}_interfaces
for interface in $interfaces; do
- eval options=\$$(chain_base $interface)_options
- if list_search detectnets $options; then
- subnets=$(get_routed_subnets $interface)
+ if interface_has_option $interface detectnets; then
+ networks=$(get_routed_networks $interface)
else
- subnets=0.0.0.0/0
+ networks=0.0.0.0/0
fi
- for subnet in $subnets; do
+ for networks in $networks; do
if [ -z "$hosts" ]; then
- hosts=$interface:$subnet
+ hosts=$interface:$networks
else
- hosts="$hosts $interface:$subnet"
+ hosts="$hosts $interface:$networks"
fi
- if list_search routeback $options; then
- eval ${zone}_routeback=\"$interface:$subnet \$${zone}_routeback\"
+ if interface_has_option $interface routeback; then
+ eval ${zone}_routeback=\"$interface:$networks \$${zone}_routeback\"
fi
done
done
@@ -496,6 +603,10 @@ determine_hosts() {
for host in $hosts; do
interface=${host%:*}
if list_search $interface $interfaces; then
+ list_search $interface:0.0.0.0/0 $hosts && \
+ startup_error "Invalid zone definition for zone $zone"
+ list_search $interface:0/0 $hosts && \
+ startup_error "Invalid zone definition for zone $zone"
eval ${zone}_is_complex=Yes
else
if [ -z "$interfaces" ]; then
@@ -525,6 +636,13 @@ validate_zone() # $1 = zone
{
list_search $1 $zones $FW
}
+#
+# Ensure that the passed zone is defined in the zones file.
+#
+validate_zone1() # $1 = zone
+{
+ list_search $1 $zones
+}
#
# Validate the zone names and options in the interfaces file
@@ -532,11 +650,11 @@ validate_zone() # $1 = zone
validate_interfaces_file() {
local wildcard
local found_obsolete_option=
- local z interface subnet options r iface option
+ local z interface networks options r iface option
- while read z interface subnet options; do
- expandv z interface subnet options
- r="$z $interface $subnet $options"
+ while read z interface networks options; do
+ expandv z interface networks options
+ r="$z $interface $networks $options"
[ "x$z" = "x-" ] && z=
@@ -550,10 +668,10 @@ validate_interfaces_file() {
wildcard=
case $interface in
- *:*)
+ *:*|+)
startup_error "Invalid Interface Name: $interface"
;;
- *+*)
+ *+)
wildcard=Yes
;;
esac
@@ -562,13 +680,13 @@ validate_interfaces_file() {
options=$(separate_list $options)
iface=$(chain_base $interface)
- eval ${iface}_broadcast="$subnet"
+ eval ${iface}_broadcast="$networks"
eval ${iface}_zone="$z"
eval ${iface}_options=\"$options\"
for option in $options; do
case $option in
- dhcp|norfc1918|tcpflags|newnotsyn|arp_filter|routefilter|blacklist|proxyarp|maclist|nosmurfs|-)
+ dhcp|norfc1918|nobogons|tcpflags|newnotsyn|arp_filter|routefilter|blacklist|proxyarp|maclist|nosmurfs|-)
;;
dropunclean|logunclean)
if [ -z "$found_obsolete_option" ]; then
@@ -605,27 +723,51 @@ validate_interfaces_file() {
# Validate the zone names and options in the hosts file
#
validate_hosts_file() {
- local z hosts options r interface host option
+ local z hosts options r interface host option port ports
while read z hosts options; do
expandv z hosts options
r="$z $hosts $options"
- validate_zone $z || startup_error "Invalid zone ($z) in record \"$r\""
+ validate_zone1 $z || startup_error "Invalid zone ($z) in record \"$r\""
- interface=${hosts%:*}
+ interface=${hosts%%:*}
+ iface=$(chain_base $interface)
list_search $interface $all_interfaces || \
startup_error "Unknown interface ($interface) in record \"$r\""
hosts=${hosts#*:}
+ eval ports=\$${iface}_ports
+ eval zports=\$${z}_ports
+
for host in $(separate_list $hosts); do
- for option in $(separate_list $options); do
+
+ [ -n "$BRIDGING" ] && case $host in
+ *:*)
+ known_interface ${host%:*} && \
+ startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host"
+ port=${host%%:*}
+ list_search $port $ports || ports="$ports $port"
+ list_search ${interface}:${port} $zports || zports="$zports ${interface}:${port}"
+ ;;
+ *.*.*.*)
+ ;;
+ *)
+ known_interface $host && \
+ startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host"
+ list_search $host $ports || ports="$ports $host"
+ list_search ${interface}:${host} $zports || zports="$zports ${interface}:${host}"
+ ;;
+ esac
+
+ for option in $(separate_list $options) ; do
case $option in
- maclist|-)
+ maclist|norfc1918|nobogons|blacklist|tcpflags|nosmurfs|newnotsyn|-)
;;
routeback)
- eval ${z}_routeback=\"$interface:$host \$${z}_routeback\"
+ [ -z "$ports" ] && \
+ eval ${z}_routeback=\"$interface:$host \$${z}_routeback\"
;;
*)
error_message "Warning: Invalid option ($option) in record \"$r\""
@@ -633,6 +775,12 @@ validate_hosts_file() {
esac
done
done
+
+ if [ -n "$ports" ]; then
+ eval ${iface}_ports=\"$ports\"
+ eval ${z}_ports=\"$zports\"
+ fi
+
done < $TMP_DIR/hosts
}
@@ -838,7 +986,7 @@ find_hosts_by_option() # $1 = option
expandv options
if list_search $1 $(separate_list $options); then
expandv hosts
- interface=${hosts%:*}
+ interface=${hosts%%:*}
addresses=${hosts#*:}
for address in $(separate_list $addresses); do
echo $interface:$address
@@ -847,8 +995,7 @@ find_hosts_by_option() # $1 = option
done < $TMP_DIR/hosts
for interface in $all_interfaces; do
- eval options=\$$(chain_base $interface)_options
- list_search $1 $options && \
+ interface_has_option $interface $1 && \
echo ${interface}:0.0.0.0/0
done
}
@@ -984,7 +1131,7 @@ disable_ipv6() {
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
else
- error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system has no ip6tables"
+ error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system does not appear to have ip6tables"
fi
}
@@ -1049,23 +1196,46 @@ stop_firewall() {
strip_file routestopped
- while read interface host; do
- expandv interface host
+ while read interface host options; do
+ expandv interface host options
[ "x$host" = "x-" -o -z "$host" ] && host=0.0.0.0/0
for h in $(separate_list $host); do
hosts="$hosts $interface:$h"
done
+
+ routeback=
+
+ if [ -n $options ]; then
+ for option in $(separate_list $options); do
+ case $option in
+ routeback)
+ if [ -n "$routeback" ]; then
+ error_message "Warning: Duplicate option ignored: routeback"
+ else
+ routeback=Yes
+ for h in $(separate_list $host); do
+ iptables -A FORWARD -i $interface -s $h -o $interface -d $h -j ACCEPT
+ done
+ fi
+ ;;
+ *)
+ error_message "Warning: Unknown option ignored: $option"
+ ;;
+ esac
+ done
+ fi
+
done < $TMP_DIR/routestopped
for host in $hosts; do
interface=${host%:*}
- subnet=${host#*:}
- iptables -A INPUT -i $interface -s $subnet -j ACCEPT
+ networks=${host#*:}
+ iptables -A INPUT -i $interface -s $networks -j ACCEPT
[ -z "$ADMINISABSENTMINDED" ] && \
- iptables -A OUTPUT -o $interface -d $subnet -j ACCEPT
+ iptables -A OUTPUT -o $interface -d $networks -j ACCEPT
for host1 in $hosts; do
- iptables -A FORWARD -i $interface -s $subnet -o ${host1%:*} -d ${host1#*:} -j ACCEPT
+ [ "$host" != "$host1" ] && iptables -A FORWARD -i $interface -s $networks -o ${host1%:*} -d ${host1#*:} -j ACCEPT
done
done
@@ -1077,6 +1247,10 @@ stop_firewall() {
iptables -A INPUT -p udp -i $interface --dport 67:68 -j ACCEPT
[ -z "$ADMINISABSENTMINDED" ] && \
iptables -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT
+ #
+ # This might be a bridge
+ #
+ iptables -A FORWARD -p udp -i $interface -o $interface --dport 67:68 -j ACCEPT
done
setup_forwarding
@@ -1415,7 +1589,7 @@ setup_mac_lists() {
maclist_interfaces=
for hosts in $maclist_hosts; do
- interface=${hosts%:*}
+ interface=${hosts%%:*}
if ! list_search $interface $maclist_interfaces; then\
if [ -z "$maclist_interfaces" ]; then
maclist_interfaces=$interface
@@ -1447,6 +1621,17 @@ setup_mac_lists() {
while read interface mac addresses; do
expandv interface mac addresses
+ physdev_part=
+
+ if [ -n "$BRIDGING" ]; then
+ case $interface in
+ *:*)
+ physdev_part="-m physdev --physdev-in ${interface#*:}"
+ interface=${interface%:*}
+ ;;
+ esac
+ fi
+
chain=$(mac_chain $interface)
if ! havechain $chain ; then
@@ -1456,10 +1641,10 @@ setup_mac_lists() {
macpart=$(mac_match $mac)
if [ -z "$addresses" ]; then
- run_iptables -A $chain $macpart -j RETURN
+ run_iptables -A $chain $macpart $physdev_part -j RETURN
else
for address in $(separate_list $addresses) ; do
- run_iptables2 -A $chain $macpart -s $address -j RETURN
+ run_iptables2 -A $chain $macpart -s $address $physdev_part -j RETURN
done
fi
done < $TMP_DIR/maclist
@@ -1494,10 +1679,10 @@ setup_mac_lists() {
# Generate jumps from the input and forward chains
#
for hosts in $maclist_hosts; do
- interface=${hosts%:*}
+ interface=${hosts%%:*}
hosts=${hosts#*:}
for chain in $(first_chains $interface) ; do
- run_iptables -A $chain -s $hosts -m state --state NEW \
+ run_iptables -A $chain $(match_source_hosts $hosts) -m state --state NEW \
-j $(mac_chain $interface)
done
done
@@ -1585,7 +1770,7 @@ setup_nat() {
run_iptables2 -t nat -A OUTPUT -d $external \
-j DNAT --to-destination $internal
fi
- elif [ -z "$allints" -o "$allints" = "No" -o "$allints" = "no" ]; then
+ elif [ -z "$allints" -o "$allints" = "No" -o "$allints" = "no" ]; then
addnatrule $(input_chain $iface) \
-d $external -j DNAT --to-destination $internal
addnatrule $(output_chain $iface) \
@@ -1621,6 +1806,34 @@ delete_nat() {
[ -d ${STATEDIR} ] && touch ${STATEDIR}/nat
}
+#
+# Setup Network Mapping (NETMAP)
+#
+setup_netmap() {
+
+ while read type net1 interface net2 ; do
+ expandv type net1 interface net2
+
+ list_search $interface $all_interfaces || \
+ fatal_error "Unknown interface $interface in entry \"$type $net1 $interface $net2\""
+
+ case $type in
+ DNAT)
+ addnatrule $(input_chain $interface) -d $net1 -j NETMAP --to $net2
+ ;;
+ SNAT)
+ addnatrule $(output_chain $interface) -s $net1 -j NETMAP --to $net2
+ ;;
+ *)
+ fatal_error "Invalid type $type in entry \"$type $net1 $interface $net2\""
+ ;;
+ esac
+
+ echo " Network $net1 on $interface mapped to $net2 ($type)"
+
+ done < $TMP_DIR/netmap
+}
+
#
# Setup ECN disabling rules
#
@@ -1692,11 +1905,11 @@ process_tc_rule()
chain=tcout
;;
*)
- if ! list_search $source $all_interfaces; then
+ if [ -z "$BRIDGING" ] && ! list_search $source $all_interfaces; then
fatal_error "Unknown interface $source in rule \"$rule\""
fi
- r="-i $source "
+ r="$(match_source_dev) $source "
;;
esac
fi
@@ -1852,7 +2065,7 @@ process_accounting_rule() {
case $source in
*:*)
- rule="-s ${source#*:} -i ${source%:*}"
+ rule="-s ${source#*:} $(match_source_dev ${source%:*})"
;;
*.*.*.*)
rule="-s $source"
@@ -1860,13 +2073,13 @@ process_accounting_rule() {
-|all|any)
;;
*)
- [ -n "$source" ] && rule="-i $source"
+ [ -n "$source" ] && rule="$(match_source_dev $source)"
;;
esac
[ -n "$dest" ] && case $dest in
*:*)
- rule="$rule -d ${dest#*:} -o ${dest%:*}"
+ rule="$rule -d ${dest#*:} $(match_dest_dev ${dest%:*})"
;;
*.*.*.*)
rule="$rule -d $dest"
@@ -1874,7 +2087,7 @@ process_accounting_rule() {
-|all|any)
;;
*)
- rule="$rule -o $dest"
+ rule="$rule $(match_dest_dev $dest)"
;;
esac
@@ -1959,7 +2172,6 @@ setup_accounting() # $1 = Name of accounting file
}
-
#
# Check the configuration
#
@@ -2113,7 +2325,7 @@ add_an_action()
-)
;;
*:*)
- cli="-i ${client%:*} -s ${client#*:}"
+ cli="$(match_source_dev ${client%:*}) -s ${client#*:}"
;;
*.*.*)
cli="-s $client"
@@ -2122,7 +2334,7 @@ add_an_action()
cli=$(mac_match $client)
;;
*)
- [ -n "$client" ] && cli="-i $client"
+ [ -n "$client" ] && cli="$(match_source_dev $client)"
;;
esac
@@ -2141,7 +2353,7 @@ add_an_action()
fatal_error "Rule \"$rule\" - Destination may not be specified by MAC Address"
;;
*)
- [ -n "$server" ] && dest_interface="-o $server"
+ [ -n "$server" ] && dest_interface="$(match_dest_dev $server)"
;;
esac
@@ -2321,7 +2533,7 @@ process_action() # $1 = action
for client in $(separate_list ${clients:=-}); do
for server in $(separate_list ${servers:=-}); do
#
- # add_a_rule() modifies these so we must set their values each time
+ # add_an_action() modifies these so we must set their values each time
#
port=${ports:=-}
cport=${cports:=-}
@@ -2673,7 +2885,7 @@ add_nat_rule() {
for z in $(separate_list $excludezones); do
eval hosts=\$${z}_hosts
for host in $hosts; do
- addnatrule $chain -s ${host#*:} -j RETURN
+ addnatrule $chain $(match_source_hosts ${host#*:}) -j RETURN
done
done
@@ -2723,7 +2935,7 @@ add_nat_rule() {
error_message "Warning: SNAT will occur on all connections to this server and port - rule \"$rule\""
[ $COMMAND = check ] || addnatrule $(snat_chain $dest) \
- -s ${source_host#*:} $proto $sports $multiport \
+ $(match_source_hosts ${source_host#*:}) $proto $sports $multiport \
-d $serv $dports -j SNAT --to-source $snat
done
fi
@@ -2784,7 +2996,7 @@ add_a_rule()
-)
;;
*:*)
- cli="-i ${client%:*} -s ${client#*:}"
+ cli="$(match_source_dev ${client%:*}) -s ${client#*:}"
;;
*.*.*)
cli="-s $client"
@@ -2793,7 +3005,7 @@ add_a_rule()
cli=$(mac_match $client)
;;
*)
- [ -n "$client" ] && cli="-i $client"
+ [ -n "$client" ] && cli="$(match_source_dev $client)"
;;
esac
@@ -2812,7 +3024,7 @@ add_a_rule()
fatal_error "Rule \"$rule\" - Destination may not be specified by MAC Address"
;;
*)
- [ -n "$server" ] && dest_interface="-o $server"
+ [ -n "$server" ] && dest_interface="$(match_dest_dev $server)"
;;
esac
@@ -2855,10 +3067,14 @@ add_a_rule()
# Some misc. setup
case "$logtarget" in
- REJECT)
- [ -n "$servport" ] && \
- fatal_error "Server port may not be specified in a REJECT rule;"\
- "rule: \"$rule\""
+ ACCEPT|DROP|REJECT|CONTINUE)
+
+ [ "$logtarget" = REJECT -a -n "$servport" ] && \
+ fatal_error "Server port may not be specified in a REJECT rule; rule: \"$rule\""
+ if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" -a -z "$userspec" ] ; then
+ error_message "Warning -- Rule \"$rule\" is a POLICY"
+ error_message " -- and should be moved to the policy file"
+ fi
;;
REDIRECT)
[ -n "$serv" ] && startup_error "REDIRECT rules cannot"\
@@ -2876,17 +3092,6 @@ add_a_rule()
;;
esac
- # Complain if the rule is really a policy
-
- case $logtarget in
- ACCEPT|DROP|REJECT)
- if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" -a -z "$userspec" ] ; then
- error_message "Warning -- Rule \"$rule\" is a POLICY"
- error_message " -- and should be moved to the policy file"
- fi
- ;;
- esac
-
if [ -n "${serv}${servport}" ]; then
if [ $COMMAND != check ]; then
@@ -3360,7 +3565,7 @@ process_tos_rule() {
[ -n "$src" ] && case "$src" in
*.*.*)
#
- # IP Address or subnet
+ # IP Address or networks
#
src="-s $src"
;;
@@ -3371,7 +3576,7 @@ process_tos_rule() {
#
# Assume that this is a device name
#
- src="-i $src"
+ src="$(match_source_dev $src)"
;;
esac
@@ -3403,7 +3608,7 @@ process_tos_rule() {
[ -n "$dst" ] && case "$dst" in
*.*.*)
#
- # IP Address or subnet
+ # IP Address or networks
#
;;
*)
@@ -3725,9 +3930,9 @@ rules_chain() # $1 = source zone, $2 = destination zone
}
#
-# echo the list of subnets routed out of a given interface
+# echo the list of networks routed out of a given interface
#
-get_routed_subnets() # $1 = interface name
+get_routed_networks() # $1 = interface name
{
local address
local rest
@@ -3753,15 +3958,15 @@ setup_masq()
case $fullinterface in
*:*:*)
- # Both alias name and subnet
+ # Both alias name and networks
destnets="${fullinterface##*:}"
fullinterface="${fullinterface%:*}"
;;
*:*)
- # Alias name OR subnet
+ # Alias name OR networks
case ${fullinterface#*:} in
*.*)
- # It's a subnet
+ # It's a networks
destnets="${fullinterface#*:}"
fullinterface="${fullinterface%:*}"
;;
@@ -3782,23 +3987,23 @@ setup_masq()
fatal_error "Unknown interface $interface"
fi
- if [ "$subnet" = "${subnet%!*}" ]; then
+ if [ "$networks" = "${networks%!*}" ]; then
nomasq=
else
- nomasq="${subnet#*!}"
- subnet="${subnet%!*}"
+ nomasq="${networks#*!}"
+ networks="${networks%!*}"
fi
- source="$subnet"
+ source="$networks"
- case $subnet in
+ case $networks in
*.*.*)
;;
*)
- subnets=$(get_routed_subnets $subnet)
- [ -z "$subnets" ] && fatal_error "Unable to determine the routes through interface $subnet"
- subnet="$subnets"
+ networks=$(get_routed_networks $networks)
+ [ -z "$networks" ] && fatal_error "Unable to determine the routes through interface $networks"
+ networks="$networks"
;;
esac
@@ -3831,11 +4036,11 @@ setup_masq()
addnatrule $newchain -d $destnet -j RETURN
done
- if [ -n "$subnet" ]; then
- for s in $subnet; do
+ if [ -n "$networks" ]; then
+ for s in $networks; do
addnatrule $chain -s $s -j $newchain
done
- subnet=
+ networks=
else
addnatrule $chain -j $newchain
fi
@@ -3856,8 +4061,8 @@ setup_masq()
newchain=masq${masq_seq}
createnatchain $newchain
- if [ -n "$subnet" ]; then
- for s in $subnet; do
+ if [ -n "$networks" ]; then
+ for s in $networks; do
for destnet in $(separate_list $destnets); do
addnatrule $chain -d $destnet -s $s -j $newchain
done
@@ -3870,7 +4075,7 @@ setup_masq()
masq_seq=$(($masq_seq + 1))
chain=$newchain
- subnet=
+ networks=
destnets=0.0.0.0/0
for addr in $(separate_list $nomasq); do
@@ -3889,8 +4094,8 @@ setup_masq()
done
fi
- if [ -n "$subnet" ]; then
- for s in $subnet; do
+ if [ -n "$networks" ]; then
+ for s in $networks; do
if [ -n "$addresses" ]; then
for destnet in $(separate_list $destnets); do
addnatrule $chain -s $s -d $destnet -j SNAT $addrlist
@@ -3919,10 +4124,10 @@ setup_masq()
strip_file masq $1
- [ -n "$NAT_ENABLED" ] && echo "Masqueraded Subnets and Hosts:"
+ [ -n "$NAT_ENABLED" ] && echo "Masqueraded Networks and Hosts:"
- while read fullinterface subnet addresses; do
- expandv fullinterface subnet addresses
+ while read fullinterface networks addresses; do
+ expandv fullinterface networks addresses
[ -n "$NAT_ENABLED" ] && setup_one || \
error_message "Warning: NAT disabled; masq rule ignored"
done < $TMP_DIR/masq
@@ -3946,7 +4151,7 @@ add_blacklist_rule() {
#
# Process a record from the blacklist file
#
-# $subnet = address/subnet
+# $networks = address/networks
# $protocol = Protocol Number/Name
# $port = Port Number/Name
#
@@ -3956,7 +4161,7 @@ process_blacklist_rec() {
local proto
local dport
- for addr in $(separate_list $subnet); do
+ for addr in $(separate_list $networks); do
case $addr in
~*)
addr=$(echo $addr | sed 's/~//;s/-/:/g')
@@ -4022,11 +4227,11 @@ process_blacklist_rec() {
# Setup the Black List
#
setup_blacklist() {
- local interfaces=$(find_interfaces_by_option blacklist)
+ local hosts=$(find_hosts_by_option blacklist)
local f=$(find_file blacklist)
local disposition=$BLACKLIST_DISPOSITION
- if [ -n "$interfaces" -a -f $f ]; then
+ if [ -n "$hosts" -a -f $f ]; then
echo "Setting up Blacklisting..."
strip_file blacklist $f
@@ -4035,18 +4240,23 @@ setup_blacklist() {
[ -n "$BLACKLISTNEWONLY" ] && state="-m state --state NEW" || state=
- for interface in $interfaces; do
- for chain in $(first_chains $interface); do
- run_iptables -A $chain $state -j blacklst
- done
+ for host in $hosts; do
+ interface=${host%%:*}
+ network=${host#*:}
- echo " Blacklisting enabled on $interface"
+ for chain in $(first_chains $interface); do
+ run_iptables -A $chain $state $(match_source_hosts $network) -j blacklst
+ done
+
+ [ $network = 0/0.0.0.0 ] && network= || network=":$network"
+
+ echo " Blacklisting enabled on ${interface}${network}"
done
[ "$disposition" = REJECT ] && disposition=reject
- while read subnet protocol ports; do
- expandv subnet protocol ports
+ while read networks protocol ports; do
+ expandv networks protocol ports
process_blacklist_rec
done < $TMP_DIR/blacklist
@@ -4069,8 +4279,8 @@ refresh_blacklist() {
run_iptables -F blacklst
- while read subnet protocol ports; do
- expandv subnet protocol ports
+ while read networks protocol ports; do
+ expandv networks protocol ports
process_blacklist_rec
done < $TMP_DIR/blacklist
fi
@@ -4109,14 +4319,14 @@ add_ip_aliases()
# decoration on these IP addresses that they see when their
# distro's net config tool adds them. In an attempt to reduce
# the anxiety level, we have the following code which sets
- # the VLSM and BRD from an existing address in the same subnet
+ # the VLSM and BRD from an existing address in the same networks
#
- # Get all of the lines that contain inet addresses
+ # Get all of the lines that contain inet addresses with broadcast
#
- ip -f inet addr show $interface 2> /dev/null | grep 'inet' | while read inet cidr rest ; do
+ ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | while read inet cidr rest ; do
case $cidr in
*/*)
- if in_subnet $external $cidr; then
+ if in_network $external $cidr; then
echo "/${cidr#*/} brd $(broadcastaddress $cidr)"
break
fi
@@ -4261,6 +4471,7 @@ initialize_netfilter () {
strip_file proxyarp
strip_file maclist
strip_file nat
+ strip_file netmap
terminator=fatal_error
@@ -4419,15 +4630,18 @@ add_common_rules() {
#
# SMURFS
#
- interfaces=$(find_interfaces_by_option nosmurfs)
+ hosts=$(find_hosts_by_option nosmurfs)
- if [ -n "$interfaces" ]; then
+ if [ -n "$hosts" ]; then
echo "Adding Anti-smurf Rules"
- for interface in $interfaces; do
+ for host in $hosts; do
+ interface=${host%%:*}
+ network=${host#*:}
+
for chain in $(first_chains $interface); do
- run_iptables -A $chain -m state --state NEW -j smurfs
+ run_iptables -A $chain -m state --state NEW $(match_source_hosts $network) -j smurfs
done
done
fi
@@ -4441,6 +4655,11 @@ add_common_rules() {
echo "Adding rules for DHCP"
for interface in $interfaces; do
+ if [ -n "$BRIDGING" ]; then
+ eval is_bridge=\$$(chain_base $interface)_ports
+ [ -n "$is_bridge" ] && \
+ iptables -A $(forward_chain $interface) -p udp -o $interface --dport 67:68 -j ACCEPT
+ fi
run_iptables -A $(input_chain $interface) -p udp --dport 67:68 -j ACCEPT
run_iptables -A OUTPUT -o $interface -p udp --dport 67:68 -j ACCEPT
done
@@ -4448,9 +4667,9 @@ add_common_rules() {
#
# RFC 1918
#
- norfc1918_interfaces="$(find_interfaces_by_option norfc1918)"
+ hosts="$(find_hosts_by_option norfc1918)"
- if [ -n "$norfc1918_interfaces" ]; then
+ if [ -n "$hosts" ]; then
echo "Enabling RFC1918 Filtering"
strip_file rfc1918
@@ -4478,7 +4697,7 @@ add_common_rules() {
run_iptables -t mangle -A rfc1918 -j DROP
fi
- while read subnet target; do
+ while read networks target; do
case $target in
logdrop)
target=rfc1918
@@ -4486,40 +4705,86 @@ add_common_rules() {
DROP|RETURN)
;;
*)
- fatal_error "Invalid target ($target) for $subnet"
+ fatal_error "Invalid target ($target) for $networks"
;;
esac
- run_iptables2 -A norfc1918 -s $subnet -j $target
+ run_iptables2 -A norfc1918 -s $networks -j $target
if [ -n "$CONNTRACK_MATCH" ]; then
#
# We have connection tracking match -- match on the original destination
#
- run_iptables2 -A norfc1918 -m conntrack --ctorigdst $subnet -j $target
+ run_iptables2 -A norfc1918 -m conntrack --ctorigdst $networks -j $target
elif [ -n "$MANGLE_ENABLED" ]; then
#
# No connection tracking match but we have mangling -- add a rule to
# the mangle table
#
- run_iptables2 -t mangle -A man1918 -d $subnet -j $target
+ run_iptables2 -t mangle -A man1918 -d $networks -j $target
fi
done < $TMP_DIR/rfc1918
- for interface in $norfc1918_interfaces; do
+ for host in $hosts; do
+ interface=${host%%:*}
+ networks=${host#*:}
+
for chain in $(first_chains $interface); do
- run_iptables -A $chain -m state --state NEW -j norfc1918
+ run_iptables -A $chain -m state --state NEW $(match_source_hosts $networks) -j norfc1918
done
[ -n "$MANGLE_ENABLED" -a -z "$CONNTRACK_MATCH" ] && \
- run_iptables -t mangle -A PREROUTING -m state --state NEW -i $interface -j man1918
+ run_iptables -t mangle -A PREROUTING -m state --state NEW -i $interface $(match_source_hosts $networks) -j man1918
+ done
+ fi
+ #
+ # Bogons
+ #
+ hosts="$(find_hosts_by_option nobogons)"
+
+ if [ -n "$hosts" ]; then
+ echo "Enabling Bogon Filtering"
+
+ strip_file bogons
+
+ createchain nobogons no
+
+ createchain bogons no
+
+ log_rule $BOGON_LOG_LEVEL bogons DROP
+
+ run_iptables -A bogons -j DROP
+
+ while read networks target; do
+ case $target in
+ logdrop)
+ target=bogons
+ ;;
+ DROP|RETURN)
+ ;;
+ *)
+ fatal_error "Invalid target ($target) for $networks"
+ ;;
+ esac
+
+ run_iptables2 -A nobogons -s $networks -j $target
+
+ done < $TMP_DIR/bogons
+
+ for host in $hosts; do
+ interface=${host%%:*}
+ network=${host#*:}
+
+ for chain in $(first_chains $interface); do
+ run_iptables -A $chain -m state --state NEW $(match_source_hosts $network) -j nobogons
+ done
done
fi
- interfaces=$(find_interfaces_by_option tcpflags)
+ hosts=$(find_hosts_by_option tcpflags)
- if [ -n "$interfaces" ]; then
+ if [ -n "$hosts" ]; then
echo "Setting up TCP Flags checking..."
createchain tcpflags no
@@ -4560,9 +4825,12 @@ add_common_rules() {
#
run_iptables -A tcpflags -p tcp --syn --sport 0 $disposition
- for interface in $interfaces; do
+ for host in $hosts; do
+ interface=${host%%:*}
+ network=${host#*:}
+
for chain in $(first_chains $interface); do
- run_iptables -A $chain -p tcp -j tcpflags
+ run_iptables -A $chain -p tcp $(match_source_hosts $network) -j tcpflags
done
done
fi
@@ -4698,8 +4966,11 @@ activate_rules()
shift
shift
- havenatchain $destchain && \
+ if havenatchain $destchain ; then
run_iptables -t nat -A $sourcechain $@ -j $destchain
+ elif [ -n "$BRIDGING" -a -f $TMP_DIR/physdev ]; then
+ rm -f #TMP_DIR/physdev
+ fi
}
#
@@ -4716,6 +4987,8 @@ activate_rules()
eval run_iptables -t nat -I $sourcechain \
\$${sourcechain}_rule $@ -j $destchain
eval ${sourcechain}_rule=\$\(\(\$${sourcechain}_rule + 1\)\)
+ elif [ -n "$BRIDGING" -a -f $TMP_DIR/physdev ]; then
+ rm -f $TMP_DIR/physdev
fi
}
@@ -4726,7 +4999,7 @@ activate_rules()
addnatjump POSTROUTING nat_out
for interface in $all_interfaces; do
- addnatjump PREROUTING $(input_chain $interface) -i $interface
+ addnatjump PREROUTING $(input_chain $interface) -i $interface
addnatjump POSTROUTING $(output_chain $interface) -o $interface
done
@@ -4754,28 +5027,31 @@ activate_rules()
need_broadcast=
for host in $source_hosts; do
- interface=${host%:*}
- subnet=${host#*:}
+ interface=${host%%:*}
+ networks=${host#*:}
- run_iptables -A OUTPUT -o $interface -d $subnet -j $chain1
+ run_iptables -A OUTPUT -o $interface $(match_dest_hosts $networks) -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
+ addrulejump PREROUTING $(dnat_chain $zone) -i $interface $(match_source_hosts $networks)
+ addrulejump POSTROUTING $(snat_chain $zone) -o $interface $(match_dest_hosts $networks)
- run_iptables -A $(input_chain $interface) -s $subnet -j $chain2
+ run_iptables -A $(input_chain $interface) $(match_source_hosts $networks) -j $chain2
[ -n "$complex" ] && \
- run_iptables -A $(forward_chain $interface) -s $subnet -j $frwd_chain
+ run_iptables -A $(forward_chain $interface) $(match_source_hosts $networks) -j $frwd_chain
- if [ "$subnet" != 0.0.0.0/0 ]; then
- if ! list_search $interface $need_broadcast ; then
- eval options=\$$(chain_base $interface)_options
- list_search detectnets $options && need_broadcast="$need_broadcast $interface"
- fi
- fi
+ case $networks in
+ *.*.*.*)
+ if [ "$networks" != 0.0.0.0/0 ]; then
+ if ! list_search $interface $need_broadcast ; then
+ interface_has_option $interface detectnets && need_broadcast="$need_broadcast $interface"
+ fi
+ fi
+ ;;
+ esac
done
@@ -4797,47 +5073,75 @@ activate_rules()
echo "$zone $zone1 $chain" >> ${STATEDIR}/chains
if [ $zone = $zone1 ]; then
+ #
+ # Try not to generate superfluous intra-zone rules
+ #
eval routeback=\"\$${zone}_routeback\"
+ eval interfaces=\"\$${zone}_interfaces\"
+ eval ports="\$${zone}_ports"
+
+ num_ifaces=$(list_count1 $interfaces)
+ #
+ # If the zone has a single interface then what matters is how many ports it has
+ #
+ [ $num_ifaces -eq 1 -a -n "$ports" ] && num_ifaces=$(list_count1 $ports)
+ #
+ # 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
+ continue
+ fi
else
routeback=
+ num_ifaces=0
fi
if [ -n "$complex" ]; then
for host1 in $dest_hosts; do
- interface1=${host1%:*}
- subnet1=${host1#*:}
- if [ $(list_count1 $source_hosts) -eq 1 -a "$source_hosts" = "$host1" ]; then
- if list_search $host1 $routeback; then
- run_iptables -A $frwd_chain -o $interface1 -d $subnet1 -j $chain
- fi
- else
- run_iptables -A $frwd_chain -o $interface1 -d $subnet1 -j $chain
+ interface1=${host1%%:*}
+ networks1=${host1#*:}
+ #
+ # Only generate an intrazone rule if the zone has more than one interface (port) or if
+ # routeback was specified for this host group
+ #
+ if [ $zone != $zone1 -o $num_ifaces -gt 1 ] || list_search $host1 $routeback ; then
+ run_iptables -A $frwd_chain -o $interface1 $(match_dest_hosts $networks1) -j $chain
fi
done
else
for host in $source_hosts; do
- interface=${host%:*}
- subnet=${host#*:}
+ interface=${host%%:*}
+ networks=${host#*:}
chain1=$(forward_chain $interface)
for host1 in $dest_hosts; do
- interface1=${host1%:*}
- subnet1=${host1#*:}
+ interface1=${host1%%:*}
+ networks1=${host1#*:}
if [ "$host" != "$host1" ] || list_search $host $routeback; then
- run_iptables -A $chain1 -s $subnet -o $interface1 -d $subnet1 -j $chain
+ run_iptables -A $chain1 $(match_source_hosts $networks) -o $interface1 $(match_dest_hosts $networks1) -j $chain
fi
done
done
fi
done
done
-
- for interface in $all_interfaces; do
- run_iptables -A FORWARD -i $interface -j $(forward_chain $interface)
- run_iptables -A INPUT -i $interface -j $(input_chain $interface)
- addnatjump POSTROUTING $(masq_chain $interface) -o $interface
+
+ for interface in $all_interfaces ; do
+
+ run_iptables -A FORWARD -i $interface -j $(forward_chain $interface)
+ run_iptables -A INPUT -i $interface -j $(input_chain $interface)
+ addnatjump POSTROUTING $(masq_chain $interface) -o $interface
+ #
+ # Bridges under the 2.4 kernel have the wierd property that REJECTS have the physdev-in and physdev-out set to the input physdev.
+ # To accomodate this feature/bug, we effectively set 'routeback' on bridge ports.
+ #
+ eval ports=\$$(chain_base $interface)_ports
+ for port in $ports; do
+ run_iptables -A $(forward_chain $interface) -o $interface -m physdev --physdev-in $port --physdev-out $port -j ACCEPT
+ done
done
chain=${FW}2${FW}
@@ -4865,7 +5169,6 @@ activate_rules()
run_iptables -D $chain -m state --state ESTABLISHED,RELATED -j ACCEPT
run_iptables -D $chain -p udp --dport 53 -j ACCEPT
done
-
}
#
@@ -4910,6 +5213,10 @@ define_firewall() # $1 = Command (Start or Restart)
setup_nat
+ echo "Setting up NETMAP..."
+
+ setup_netmap
+
echo "Adding Common Rules"
add_common_rules
@@ -5016,7 +5323,7 @@ refresh_firewall()
}
#
-# Add a host or subnet to a zone
+# Add a host or networks to a zone
#
add_to_zone() # $1 = [:] $2 = zone
{
@@ -5178,11 +5485,11 @@ add_to_zone() # $1 = [:] $2 = zone
fi
for h in $dest_hosts; do
- iface=${h%:*}
+ iface=${h%%:*}
hosts=${h#*:}
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
- do_iptables -I $source_chain $rulenum -s $host -o $iface -d $hosts -j $chain
+ do_iptables -I $source_chain $rulenum -s $host -o $iface $(match_dest_hosts $hosts) -j $chain
rulenum=$(($rulenum + 1))
fi
done
@@ -5205,7 +5512,7 @@ add_to_zone() # $1 = [:] $2 = zone
eval source_hosts=\"\$${z1}_hosts\"
for h in $source_hosts; do
- iface=${h%:*}
+ iface=${h%%:*}
hosts=${h#*:}
base=$(chain_base $iface)
@@ -5221,7 +5528,7 @@ add_to_zone() # $1 = [:] $2 = zone
fi
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
- do_iptables -I $(forward_chain $iface) $rulenum -s $hosts -o $interface -d $host -j $chain
+ do_iptables -I $(forward_chain $iface) $rulenum $(match_source_hosts $hosts) -o $interface -d $host -j $chain
rulenum=$(($rulenum + 1))
fi
@@ -5237,12 +5544,12 @@ add_to_zone() # $1 = [:] $2 = zone
}
#
-# Delete a host or subnet from a zone
+# Delete a host or networks from a zone
#
delete_from_zone() # $1 = [:] $2 = zone
{
#
- # Delete the subnect host(s) from the zone state file
+ # Delete the subject host(s) from the zone state file
#
delete_from_zones_file()
{
@@ -5328,11 +5635,11 @@ delete_from_zone() # $1 = [:] $2 = zone
eval dest_hosts=\"\$${z2}_hosts\"
for h in $dest_hosts $delhost; do
- iface=${h%:*}
+ iface=${h%%:*}
hosts=${h#*:}
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
- qt iptables -D $source_chain -s $host -o $iface -d $hosts -j $chain
+ qt iptables -D $source_chain -s $host -o $iface $(match_source_hosts $hosts) -j $chain
fi
done
fi
@@ -5343,11 +5650,11 @@ delete_from_zone() # $1 = [:] $2 = zone
eval source_hosts=\"\$${z1}_hosts\"
for h in $source_hosts; do
- iface=${h%:*}
+ iface=${h%%:*}
hosts=${h#*:}
if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then
- qt iptables -D $(forward_chain $iface) -s $hosts -o $interface -d $host -j $chain
+ qt iptables -D $(forward_chain $iface) $(match_source_hosts $hosts) -o $interface -d $host -j $chain
fi
done
fi
@@ -5450,6 +5757,7 @@ do_initialize() {
TCP_FLAGS_DISPOSITION=
TCP_FLAGS_LOG_LEVEL=
RFC1918_LOG_LEVEL=
+ BOGON_LOG_LEVEL=
MARK_IN_FORWARD_CHAIN=
SHARED_DIR=/usr/share/shorewall
FUNCTIONS=
@@ -5463,6 +5771,7 @@ do_initialize() {
USEDACTIONS=
SMURF_LOG_LEVEL=
DISABLE_IPV6=
+ BRIDGING=
stopping=
have_mutex=
@@ -5582,6 +5891,8 @@ do_initialize() {
fi
[ -z "$RFC1918_LOG_LEVEL" ] && RFC1918_LOG_LEVEL=info
+ [ -z "$BOGON_LOG_LEVEL" ] && BOGON_LOG_LEVEL=info
+
MARK_IN_FORWARD_CHAIN=$(added_param_value_no MARK_IN_FORWARD_CHAIN $MARK_IN_FORWARD_CHAIN)
[ -n "$MARK_IN_FORWARD_CHAIN" ] && marking_chain=tcfor || marking_chain=tcpre
if [ -n "$TC_ENABLED" ]; then
@@ -5613,6 +5924,7 @@ do_initialize() {
ADMINISABSENTMINDED=$(added_param_value_no ADMINISABSENTMINDED $ADMINISABSENTMINDED)
BLACKLISTNEWONLY=$(added_param_value_no BLACKLISTNEWONLY $BLACKLISTNEWONLY)
DISABLE_IPV6=$(added_param_value_no DISABLE_IPV6 $DISABLE_IPV6)
+ BRIDGING=$(added_param_value_no BRIDGING $BRIDGING)
[ -n "$MODULE_SUFFIX" ] || MODULE_SUFFIX="o gz ko o.gz"
#
@@ -5629,6 +5941,8 @@ do_initialize() {
if [ $(encodeaddr $temp) != 192.168.1.1 ]; then
startup_error "Shell $SHOREWALL_SHELL is broken and may not be used with Shorewall"
fi
+
+ rm -f $TMP_DIR/physdev
}
#
diff --git a/STABLE2/functions b/STABLE2/functions
index 9a9210325..c96f9c5bd 100755
--- a/STABLE2/functions
+++ b/STABLE2/functions
@@ -470,9 +470,9 @@ broadcastaddress() {
}
#
-# Test for subnet membership
+# Test for network membership
#
-in_subnet() # $1 = IP address, $2 = CIDR network
+in_network() # $1 = IP address, $2 = CIDR network
{
local netmask=$(ip_netmask $2)
@@ -502,11 +502,11 @@ ip_vlsm() {
#
# Chain name base for an interface -- replace all periods with underscores in the passed name.
-# The result is echoed (less "+" and anything following).
+# The result is echoed (less trailing "+").
#
chain_base() #$1 = interface
{
- local c=${1%%+*}
+ local c=${1%%+}
while true; do
case $c in
@@ -524,29 +524,25 @@ chain_base() #$1 = interface
done
}
-#
-# Remove trailing digits from a name
-#
-strip_trailing_digits() {
- echo $1 | sed s'/[0-9].*$//'
-}
-
#
# Loosly Match the name of an interface
#
if_match() # $1 = Name in interfaces file - may end in "+"
- # $2 = Name from routing table
+ # $2 = Full interface name - may also end in "+"
{
- local if_file=$1
- local rt_table=$2
-
- case $if_file in
+ local pattern=${1%+}
+
+ case $1 in
*+)
- test "$(strip_trailing_digits $rt_table)" = "${if_file%+}"
+ #
+ # Can't use ${2:0:${#pattern}} because ash and dash don't support that flavor of
+ # variable expansion :-(
+ #
+ test "x$(echo $2 | cut -b -${#pattern} )" = "x${pattern}"
;;
*)
- test "$rt_table" = "$if_file"
+ test "x$1" = "x$2"
;;
esac
}
@@ -571,7 +567,7 @@ find_rt_interface() {
ip route ls | while read addr rest; do
case $addr in
*/*)
- in_subnet ${1%/*} $addr && echo $(find_device $rest)
+ in_network ${1%/*} $addr && echo $(find_device $rest)
;;
default)
;;
diff --git a/STABLE2/help b/STABLE2/help
index 4ed47f396..8a052a9ee 100644
--- a/STABLE2/help
+++ b/STABLE2/help
@@ -147,8 +147,13 @@ logwatch)
monitor)
echo "monitor: monitor []
+
+ shorewall [-x] monitor []
+
Continuously display the firewall status, last 20 log entries and nat.
- When the log entry display changes, an audible alarm is sounded."
+ When the log entry display changes, an audible alarm is sounded.
+
+ When -x is given, that option is also passed to iptables to display actual packet and byte counts."
;;
refresh)
@@ -185,14 +190,15 @@ save)
;;
show)
- echo "show: show [ [ ...] |classifiers|connections|log|nat|tc|tos]
- shorewall show [ ... ] - produce a verbose report about the IPtable chain(s).
+ echo "show: show [ [ ...] |classifiers|connections|log|nat|tc|tos]
+
+ shorewall [-x] show [ ... ] - produce a verbose report about the IPtable chain(s).
(iptables -L chain -n -v)
- shorewall show nat - produce a verbose report about the nat table.
+ shorewall [-x] show nat - produce a verbose report about the nat table.
(iptables -t nat -L -n -v)
- shorewall show tos - produce a verbose report about the mangle table.
+ shorewall [-x] show tos - produce a verbose report about the mangle table.
(iptables -t mangle -L -n -v)
shorewall show log - display the last 20 packet log entries.
@@ -201,7 +207,9 @@ show)
being tracked by the firewall.
shorewall show tc - displays information about the traffic
- control/shaping configuration."
+ control/shaping configuration.
+
+ When -x is given, that option is also passed to iptables to display actual packet and byte counts."
;;
start)
@@ -221,9 +229,14 @@ stop)
status)
echo "status: status
+
+ shorewall [-x] status
+
Produce a verbose report about the firewall.
- (iptables -L -n -v)"
+ (iptables -L -n -)
+
+ When -x is given, that option is also passed to iptables to display actual packet and byte counts."
;;
trace)
diff --git a/STABLE2/hosts b/STABLE2/hosts
index 129e5431b..2aaf93a97 100644
--- a/STABLE2/hosts
+++ b/STABLE2/hosts
@@ -5,28 +5,39 @@
# ONE ZONE CONNECTED THROUGH A SINGLE INTERFACE.
#
# IF YOU DON'T HAVE THAT SITUATION THEN DON'T TOUCH THIS FILE.
-#
+#------------------------------------------------------------------------------
+# IF YOU HAVE AN ENTRY FOR A ZONE AND INTERFACE IN
+# /etc/shorewall/interfaces THEN DO NOT ADD ANY ENTRIES FOR THAT
+# ZONE AND INTERFACE IN THIS FILE.
+#------------------------------------------------------------------------------
# This file is used to define zones in terms of subnets and/or
# individual IP addresses. Most simple setups don't need to
# (should not) place anything in this file.
#
# ZONE - The name of a zone defined in /etc/shorewall/zones
#
-# HOST(S) - The name of an interface followed by a colon (":") and
+# HOST(S) - The name of an interface defined in the
+# /etc/shorewall/interfaces file followed by a colon (":") and
# a comma-separated list whose elements are either:
#
# a) The IP address of a host
# b) A subnetwork in the form
# /
-#
-# The interface must be defined in the
-# /etc/shorewall/interfaces file.
+# c) A physical port name; only allowed when the
+# interface names a bridge created by the
+# brctl addbr command. This port must not
+# be defined in /etc/shorewall/interfaces and may
+# optionally followed by a colon (":") and a
+# host or network IP.
+# See http://www.shorewall.net/Bridge.html for details.
#
# Examples:
#
# eth1:192.168.1.3
# eth2:192.168.2.0/24
# eth3:192.168.2.0/24,192.168.3.1
+# br0:eth4
+# br0:eth0:192.168.1.16/28
#
# OPTIONS - A comma-separated list of options. Currently-defined
# options are:
@@ -47,6 +58,66 @@
# to send requests originating from this
# group to a server in the group.
#
+# norfc1918 - This option only makes sense for ports
+# on a bridge.
+#
+# The port should not accept
+# any packets whose source is in one
+# of the ranges reserved by RFC 1918
+# (i.e., private or "non-routable"
+# addresses. If packet mangling or
+# connection-tracking match is enabled in
+# your kernel, packets whose destination
+# addresses are reserved by RFC 1918 are
+# also rejected.
+#
+# nobogons - This option only makes sense for ports
+# on a bridge.
+#
+# This port should not accept
+# any packets whose source is in one
+# of the ranges reserved by IANA (this
+# option does not cover those ranges
+# reserved by RFC 1918 -- see
+# 'norfc1918' above).
+#
+# blacklist - This option only makes sense for ports
+# on a bridge.
+#
+# Check packets arriving on this port
+# against the /etc/shorewall/blacklist
+# file.
+#
+# tcpflags - Packets arriving from these hosts are
+# checked for certain illegal combinations
+# of TCP flags. Packets found to have
+# such a combination of flags are handled
+# according to the setting of
+# TCP_FLAGS_DISPOSITION after having been
+# logged according to the setting of
+# TCP_FLAGS_LOG_LEVEL.
+#
+# nosmurfs - This option only makes sense for ports
+# on a bridge.
+#
+# Filter packets for smurfs
+# (packets with a broadcast
+# address as the source).
+#
+# Smurfs will be optionally logged based
+# on the setting of SMURF_LOG_LEVEL in
+# shorewall.conf. After logging, the
+# packets are dropped.
+#
+# newnotsyn - TCP packets that don't have the SYN
+# flag set and which are not part of an
+# established connection will be accepted
+# from these hosts, even if
+# NEWNOTSYN=No has been specified in
+# /etc/shorewall/shorewall.conf.
+#
+# This option has no effect if
+# NEWNOTSYN=Yes.
#
#ZONE HOST(S) OPTIONS
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS LINE -- DO NOT REMOVE
diff --git a/STABLE2/install.sh b/STABLE2/install.sh
index 0e83f5b98..69d82b463 100755
--- a/STABLE2/install.sh
+++ b/STABLE2/install.sh
@@ -22,7 +22,7 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
#
-VERSION=2.0.0b
+VERSION=2.0.1
usage() # $1 = exit status
{
@@ -270,6 +270,16 @@ else
echo "NAT file installed as ${PREFIX}/etc/shorewall/nat"
fi
#
+# Install the NETMAP file
+#
+if [ -f ${PREFIX}/etc/shorewall/netmap ]; then
+ backup_file /etc/shorewall/netmap
+else
+ run_install -o $OWNER -g $GROUP -m 0600 netmap ${PREFIX}/etc/shorewall/netmap
+ echo
+ echo "NETMAP file installed as ${PREFIX}/etc/shorewall/netmap"
+fi
+#
# Install the Parameters file
#
if [ -f ${PREFIX}/etc/shorewall/params ]; then
@@ -384,6 +394,12 @@ install_file_with_backup rfc1918 ${PREFIX}/usr/share/shorewall/rfc1918 0600
echo
echo "RFC 1918 file installed as ${PREFIX}/etc/shorewall/rfc1918"
#
+# Install the bogons file
+#
+install_file_with_backup bogons ${PREFIX}/usr/share/shorewall/bogons 0600
+echo
+echo "Bogon file installed as ${PREFIX}/etc/shorewall/bogons"
+#
# Install the init file
#
if [ -f ${PREFIX}/etc/shorewall/init ]; then
diff --git a/STABLE2/interfaces b/STABLE2/interfaces
index 9d25a0f1f..9a9642362 100644
--- a/STABLE2/interfaces
+++ b/STABLE2/interfaces
@@ -46,31 +46,51 @@
# OPTIONS A comma-separated list of options including the
# following:
#
-# dhcp - interface is managed by DHCP or used by
-# a DHCP server running on the firewall or
-# you have a static IP but are on a LAN
-# segment with lots of Laptop DHCP clients.
+# dhcp - Specify this option when any of
+# the following are true:
+# 1. the interface gets its IP address
+# via DHCP
+# 2. the interface is used by
+# a DHCP server running on the firewall
+# 3. you have a static IP but are on a LAN
+# segment with lots of Laptop DHCP
+# clients.
+# 4. the interface is a bridge with
+# a DHCP server on one port and DHCP
+# clients on another port.
+#
# norfc1918 - This interface should not receive
# any packets whose source is in one
# of the ranges reserved by RFC 1918
# (i.e., private or "non-routable"
-# addresses. If packet mangling is
-# enabled in shorewall.conf, packets
-# whose destination addresses are
-# reserved by RFC 1918 are also rejected.
+# addresses. If packet mangling or
+# connection-tracking match is enabled in
+# your kernel, packets whose destination
+# addresses are reserved by RFC 1918 are
+# also rejected.
+#
+# nobogons - This interface should not receive
+# any packets whose source is in one
+# of the ranges reserved by IANA (this
+# option does not cover those ranges
+# reserved by RFC 1918 -- see above).
+#
# routefilter - turn on kernel route filtering for this
# interface (anti-spoofing measure). This
# option can also be enabled globally in
# the /etc/shorewall/shorewall.conf file.
+#
# . . blacklist - Check packets arriving on this interface
# against the /etc/shorewall/blacklist
# file.
+#
# maclist - Connection requests from this interface
# are compared against the contents of
# /etc/shorewall/maclist. If this option
# is specified, the interface must be
# an ethernet NIC and must be up before
# Shorewall is started.
+#
# tcpflags - Packets arriving on this interface are
# checked for certain illegal combinations
# of TCP flags. Packets found to have
@@ -79,6 +99,7 @@
# TCP_FLAGS_DISPOSITION after having been
# logged according to the setting of
# TCP_FLAGS_LOG_LEVEL.
+#
# proxyarp -
# Sets
# /proc/sys/net/ipv4/conf//proxy_arp.
@@ -127,7 +148,7 @@
# hosts routed through the interface.
#
# WARNING: DO NOT SET THE detectnets OPTION ON YOUR
-# INTERNET INTERFACE!
+# INTERNET INTERFACE.
#
# The order in which you list the options is not
# significant but the list should have no embedded white
diff --git a/STABLE2/releasenotes.txt b/STABLE2/releasenotes.txt
index 5a16c6b15..cc2f9bee0 100644
--- a/STABLE2/releasenotes.txt
+++ b/STABLE2/releasenotes.txt
@@ -1,237 +1,100 @@
-Shorewall 2.0.0b
+Shorewall 2.0.1
----------------------------------------------------------------------
-Problems Corrected since 1.4.10
-
-1) A blank USER/GROUP column in /etc/shorewall/tcrules no longer causes
- a [re]start error.
-
-2) The 'fgrep' utility is no longer required (caused startup problems
- on LEAF/Bering).
-
-3) The "shorewall add" command no longer inserts rules before checking
- of the blacklist.
-
-4) The 'detectnets' and 'routeback' options may now be used together
- with the intended effect.
-
-5) The following syntax previously produced an error:
-
- DNAT z1!z2,z3 z4...
-
-Problems Corrected since RC2
-
-1) CONTINUE rules now work again.
-
-2) A comment in the rules file has been corrected.
-
Problems Corrected since 2.0.0
1) Using actions in the manner recommended in the documentation
results in a Warning that the rule is a policy.
-Problems Corrected since 2.0.0a
+2) When a zone on a single interface is defined using
+ /etc/shorewall/hosts, superfluous rules are generated in the
+ _frwd chain.
-1) Thanks to Sean Mathews, a long-time problem with Proxy ARP and IPSEC
- has been corrected.
+3) Thanks to Sean Mathews, a long-standing problem with Proxy ARP and
+ IPSEC has been corrected. Thanks Sean!!!
-2) The Default value for ALL INTERFACES in the /etc/shorewall/nat file
- is supposed to be 'no' but it remained 'yes' as in 1.4.
+4) The "shorewall show log" and "shorewall logwatch" commands
+ incorrectly displayed type 3 ICMP packets.
-----------------------------------------------------------------------
-Issues when migrating from Shorewall 1.4.x to Shorewall 2.0.0:
+Issues when migrating from Shorewall 2.0.0 to Shorewall 2.0.1:
-1) The 'dropunclean' and 'logunclean' interface options are no longer
- supported. If either option is specified in
- /etc/shorewall/interfaces, an threatening message will be
- generated.
+1) The function of 'norfc1918' is now split between that option and a
+ new 'nobogons' option.
-2) The NAT_BEFORE_RULES option has been removed from
- shorewall.conf. The behavior of Shorewall is as if
- NAT_BEFORE_RULES=No had been specified. In other words, DNAT rules
- now always take precidence over one-to-one NAT specifications.
+ The rfc1918 file released with Shorewall now contains entries for
+ only those three address ranges reserved by RFC 1918. A 'nobogons'
+ interface option has been added which handles bogon source
+ addresses (those which are reserved by the IANA, those reserved for
+ DHCP auto-configuration and the class C test-net reserved for
+ testing and documentation examples). This will allow users to
+ perform RFC 1918 filtering without having to deal with out
+ of date data from IANA. Those who are willing to update their
+ /usr/share/shorewall/bogons file regularly can specify the
+ 'nobogons' option in addition to 'norfc1918'.
-3) The default value for the ALL INTERFACES column in
- /etc/shorewall/nat has changed. In Shorewall 1.*, if the column was
- left empty, a value of "Yes" was assumed. This has been changed so
- that a value of "No" is now assumed.
-
-4) The following files don't exist in Shorewall 2.0:
-
- /etc/shorewall/common.def
- /etc/shorewall/common
- /etc/shorewall/icmpdef
- /etc/shorewall/action.template (Moved to /usr/share/shorewall)
- /etc/shorewall/rfc1918 (Moved to /usr/share/shorewall).
-
- The /etc/shorewall/action file now allows an action to be
- designated as the "common" action for a particular policy type by
- following the action name with ":" and the policy (DROP, REJECT or
- ACCEPT).
-
- The file /usr/share/shorewall/actions.std has been added to define those
- actions that are released as part of Shorewall. In that file are
- two actions as follows:
-
- Drop:DROP
- Reject:REJECT
-
- The "Drop" action is the common action for DROP policies while the
- "Reject" action is the default action for "REJECT" policies. These
- actions will be performed on packets prior to applying the DROP or
- REJECT policy respectively. In the first release, the difference
- between "Reject" and "Drop" is that "Reject" REJECTs SMB traffic
- while "Drop" silently drops such traffic.
-
- As described above, Shorewall allows a common action for ACCEPT
- policies but does not specify such an action in the default
- configuration.
-
- If for some reason, you don't wish to have a common DROP or REJECT
- action, just include :DROP or :REJECT respectively in your
- /etc/shorewall/actions file.
-
- The file /usr/share/shorewall/actions.std catalogs the standard
- actions and is processed prior to /etc/shorewall/actions. This
- causes a large number of actions to be defined. The files which
- define these aactions are also located in /usr/share/shorewall as
- is the he action template file (action.template).
-
- In the initial release, the following actions are defined:
-
- dropBcast #Silently Drops Broadcast Traffic
- dropNonSyn #Silently Drop Non-syn TCP packets
-
- DropSMB #Silently Drops Microsoft SMB Traffic
- RejectSMB #Silently Reject Microsoft SMB Traffic
- DropUPnP #Silently Drop UPnP Probes
- RejectAuth #Silently Reject Auth
- DropPing #Silently Drop Ping
- DropDNSrep #Silently Drop DNS Replies
-
- AllowPing #Accept Ping
- AllowFTP #Accept FTP
- AllowDNS #Accept DNS
- AllowSSH #Accept SSH
- AllowWeb #Allow Web Browsing
- AllowSMB #Allow MS Networking
- AllowAuth #Allow Auth (identd)
- AllowSMTP #Allow SMTP (Email)
- AllowPOP3 #Allow reading mail via POP3
- AllowIMAP #Allow reading mail via IMAP
- AllowTelnet #Allow Telnet Access (not recommended for use over the
- #Internet)
- AllowVNC #Allow VNC, Displays 0-9
- AllowVNCL #Allow access to VNC viewer in listen mode
- AllowNTP #Allow Network Time Protocol (ntpd)
- AllowRdate #Allow remote time (rdate).
- AllowNNTP #Allow network news (Usenet).
- AllowTrcrt #Allows Traceroute (20 hops)
- AllowSNMP #Allows SNMP (including traps)
- AllowPCA #Allows PCAnywhere (tm).
-
- Drop:DROP #Common rules for DROP policy
- Reject:REJECT #Common Action for Reject policy
-
- These actions may be used in the ACTION column of the rules
- column. So for example, to allow FTP from your loc zone to your firewall,
- you would place this rule in /etc/shorewall/rules:
-
- #ACTION SOURCE DEST
- AllowFTP loc fw
-
- if you want to redefine any of the Shorewall-defined actions,
- simply copy the appropriate action file from /usr/share/shorewall
- to /etc/shorewall and modify the copy as desired. Your modified
- copy will be used rather than the original one in
- /usr/share/shorewall.
-
- Note: The 'dropBcast' and 'dropNonSyn' actions are built into
- Shorewall and may not be changed.
-
- Beginning with version 2.0.0-Beta2, Shorewall will only create a
- chain for those actions that are actually used.
-
-5) The /etc/shorewall directory no longer contains a 'users' file or a
- 'usersets' file. Similar functionality is now available using
- user-defined actions.
-
- Now, action files created by copying
- /usr/share/shorewall/action.template may now specify a USER and or
- GROUP name/id in the final column just like in the rules file (see
- below). It is thus possible to create actions that control traffic
- from a list of users and/or groups.
-
- The last column in /etc/shorewall/rules is now labeled USER/GROUP
- and may contain:
-
- [!][:]
- [!][:]
- [!]:
- [!]:
- [!]:
- [!]:
- [!]:
- [!]:
-
-6) It is no longer possible to specify rate limiting in the ACTION
- column of /etc/shorewall/rules -- you must use the RATE LIMIT
- column.
-
-7) Depending on which method you use to upgrade, if you have your own
- version of /etc/shorewall/rfc1918, you may have to take special
- action to restore it after the upgrade. Look for
- /etc/shorewall/rfc1918*, locate the proper file and rename it back
- to /etc/shorewall/rfc1918. The contents of that file will supercede
- the contents of /usr/share/shorewall/rfc1918.
+ The level at which bogon packets are logged is specified in the new
+ BOGON_LOG_LEVEL variable in shorewall.conf. If that option is not
+ specified or is specified as empty (e.g, BOGON_LOG_LEVEL="") then
+ bogon packets whose TARGET is 'logdrop' in
+ /usr/share/shorewall/bogons are logged at the 'info' level.
New Features:
-1) The INCLUDE directive now allows absolute file names.
+1) Support for Bridging Firewalls has been added. For details, see
-2) A 'nosmurfs' interface option has been added to
- /etc/shorewall/interfaces. When specified for an interface, this
- option causes smurfs (packets with a broadcast address as their
- source) to be dropped and optionally logged (based on the setting of
- a new SMURF_LOG_LEVEL option in shorewall.conf).
+ http://shorewall.net/bridge.html
-3) fw->fw traffic may now be controlled by Shorewall. There is no need
- to define the loopback interface in /etc/shorewall/interfaces; you
- simply add a fw->fw policy and fw->fw rules. If you have neither a
- fw->fw policy nor fw->fw rules, all fw->fw traffic is allowed.
+2) Support for NETMAP has been added. NETMAP allows NAT to be defined
+ between two network:
-4) There is a new PERSISTENT column in the proxyarp file. A value of
- "Yes" in this column means that the route added by Shorewall for
- this host will remain after a "shorewall stop" or "shorewall clear".
+ a.b.c.1 -> x.y.z.1
+ a.b.c.2 -> x.y.z.2
+ a.b.c.3 -> x.y.z.3
+ ...
-5) "trace" is now a synonym for "debug" in /sbin/shorewall commands.
- So to trace the "start" command, you could enter:
+ http://shorewall.net/netmap.html
- shorewall trace start 2> /tmp/trace
+3) The /sbin/shorewall program now accepts a "-x" option to cause
+ iptables to print out the actual packet and byte counts rather than
+ abbreviated counts such as "13MB".
- The trace information would be written to the file /tmp/trace.
+ Commands affected by this are:
-6) When defining an ipsec tunnel in /etc/shorewall/tunnels, if you
- follow the tunnel type ("ipsec" or "ipsecnet") with ":noah"
- (e.g., "ipsec:noah"), then Shorewall will only create rules for
- ESP (protocol 50) and will not create rules for AH (protocol 51).
+ shorewall -x show [ [ ...] ]
+ shorewall -x show tos|mangle
+ shorewall -x show nat
+ shorewall -x status
+ shorewall -x monitor [ ]
-7) A new DISABLE_IPV6 option has been added to shorewall.conf. When
- this option is set to "Yes", Shorewall will set the policy for the
- IPv6 INPUT, OUTPUT and FORWARD chains to DROP during "shorewall
- [re]start" and "shorewall stop". Regardless of the setting of this
- variable, "shorewall clear" will silently attempt to set these
- policies to ACCEPT.
+4) Shorewall now traps two common zone definition errors:
- If this option is not set in your existing shorewall.conf then a
- setting of DISABLE_IPV6=No is assumed in which case, Shorewall will
- not touch any IPv6 settings except during "shorewall clear".
+ - Including the firewall zone in a /etc/shorewall/hosts record.
+ - Defining an interface for a zone in both /etc/shorewall/interfaces
+ and /etc/shorewall/hosts.
-8) The CONTINUE target is now available in action definitions. CONTINUE
- terminates processing of the current action and returns to the point
- where that action was invoked.
+ In the second case, the following will appear during "shorewall
+ [re]start" or "shorewall check":
+ Determining Hosts in Zones...
+ ...
+ Error: Invalid zone definition for zone
+ Terminated
+5) To support bridging, the following options have been added to
+ entries in /etc/shorewall/hosts:
+ norfc1918
+ nobogons
+ blacklist
+ tcpflags
+ nosmurfs
+ newnotsyn
-
+ With the exception of 'newnotsyn', these options are only
+ useful when the entry refers to a bridge port.
+
+ Example:
+
+ #ZONE HOST(S) OPTIONS
+ net br0:eth0 norfc1918,nobogons,blacklist,tcpflags,nosmurfs
diff --git a/STABLE2/rfc1918 b/STABLE2/rfc1918
index 01123a4b7..42bd82e3d 100644
--- a/STABLE2/rfc1918
+++ b/STABLE2/rfc1918
@@ -5,9 +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.
+# The default list includes those IP addresses listed in RFC 1918.
+#
+# DO NOT MODIFY THIS FILE. IF YOU NEED TO MAKE CHANGES, COPY THE FILE
+# TO /etc/shorewall AND MODIFY THE COPY.
#
# Columns are:
#
@@ -19,45 +20,7 @@
#
###############################################################################
#SUBNET TARGET
-255.255.255.255 RETURN # We need to allow limited broadcast
-169.254.0.0/16 DROP # DHCP autoconfig
172.16.0.0/12 logdrop # RFC 1918
-192.0.2.0/24 logdrop # Example addresses (RFC 3330)
192.168.0.0/16 logdrop # RFC 1918
-#
-# The following are generated with the help of the Python program found at:
-#
-# http://www.shorewall.net/pub/shorewall/contrib/iana_reserved/
-#
-# The program was contributed by Andy Wiggin
-#
-0.0.0.0/7 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 # Reserved
-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
-49.0.0.0/8 logdrop # JTC - Returned to IANA Mar 98
-50.0.0.0/8 logdrop # JTC - Returned to IANA Mar 98
-58.0.0.0/7 logdrop # Reserved
-70.0.0.0/7 logdrop # Reserved
-72.0.0.0/5 logdrop # Reserved
-85.0.0.0/8 logdrop # Reserved
-86.0.0.0/7 logdrop # Reserved
-88.0.0.0/5 logdrop # Reserved
-96.0.0.0/3 logdrop # Reserved
-127.0.0.0/8 logdrop # Loopback
-197.0.0.0/8 logdrop # Reserved
-198.18.0.0/15 logdrop # Reserved
-223.0.0.0/8 logdrop # Reserved - Returned by APNIC in 2003
-240.0.0.0/4 logdrop # Reserved
-#
-# End of generated entries
-#
+10.0.0.0/8 logdrop # RFC 1918
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
diff --git a/STABLE2/shorewall b/STABLE2/shorewall
index 42efa2091..90185f2d9 100755
--- a/STABLE2/shorewall
+++ b/STABLE2/shorewall
@@ -175,7 +175,7 @@ display_chains()
# Send the output to a temporary file since ash craps if we try to store
# the output in a variable.
#
- iptables -L -n -v > /tmp/chains-$$
+ iptables -L $IPT_OPTIONS > /tmp/chains-$$
clear
echo "$banner $(date)"
@@ -289,7 +289,7 @@ packet_log() # $1 = number of messages
sed s/" kernel:"// | \
sed s/" $host $LOGFORMAT"/" "/ | \
sed s/" $host kernel: ipt_unclean: "/" "/ | \
- sed 's/MAC=.*SRC=/SRC=/' | \
+ sed 's/MAC=.* SRC=/SRC=/' | \
tail $options
}
@@ -420,7 +420,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that
echo
echo "NAT Status"
echo
- iptables -t nat -L -n -v
+ iptables -t nat -L $IPT_OPTIONS
timed_read
clear
@@ -429,7 +429,7 @@ monitor_firewall() # $1 = timeout -- if negative, prompt each time that
echo
echo "TOS/MARK Status"
echo
- iptables -t mangle -L -n -v
+ iptables -t mangle -L $IPT_OPTIONS
timed_read
clear
@@ -530,7 +530,7 @@ help()
#
usage() # $1 = exit status
{
- echo "Usage: $(basename $0) [debug|trace] [nolock] [-c ] "
+ echo "Usage: $(basename $0) [debug|trace] [nolock] [-c ] [ -x ] "
echo "where is one of:"
echo " add [:] "
echo " allow ..."
@@ -585,6 +585,7 @@ if [ $# -gt 0 ] && [ "$1" = "nolock" ]; then
fi
SHOREWALL_DIR=
+IPT_OPTIONS="-nv"
done=0
while [ $done -eq 0 ]; do
@@ -605,6 +606,10 @@ while [ $done -eq 0 ]; do
shift
shift
;;
+ -x)
+ IPT_OPTIONS="-xnv"
+ shift
+ ;;
*)
done=1
;;
@@ -710,14 +715,14 @@ case "$1" in
echo "Shorewall-$version NAT at $HOSTNAME - $(date)"
echo
show_reset
- iptables -t nat -L -n -v
+ iptables -t nat -L $IPT_OPTIONS
;;
tos|mangle)
[ $# -gt 2 ] && usage 1
echo "Shorewall-$version TOS at $HOSTNAME - $(date)"
echo
show_reset
- iptables -t mangle -L -n -v
+ iptables -t mangle -L $IPT_OPTIONS
;;
log)
[ $# -gt 2 ] && usage 1
@@ -748,10 +753,10 @@ case "$1" in
show_reset
if [ $# -gt 0 ]; then
for chain in $*; do
- iptables -L $chain -n -v
+ iptables -L $chain $IPT_OPTIONS
done
else
- iptables -L -n -v
+ iptables -L $IPT_OPTIONS
fi
;;
esac
@@ -775,17 +780,17 @@ case "$1" in
echo
show_reset
host=$(echo $HOSTNAME | sed 's/\..*$//')
- iptables -L -n -v
+ iptables -L $IPT_OPTIONS
echo
packet_log 20
echo
echo "NAT Table"
echo
- iptables -t nat -L -n -v
+ iptables -t nat -L $IPT_OPTIONS
echo
echo "Mangle Table"
echo
- iptables -t mangle -L -n -v
+ iptables -t mangle -L $IPT_OPTIONS
echo
cat /proc/net/ip_conntrack
;;
diff --git a/STABLE2/shorewall.conf b/STABLE2/shorewall.conf
index 1e0bd1755..2530f0485 100644
--- a/STABLE2/shorewall.conf
+++ b/STABLE2/shorewall.conf
@@ -169,11 +169,29 @@ RFC1918_LOG_LEVEL=info
# SMURF Log Level
#
# Specifies the logging level for smurf packets dropped by the
-#'nosmurfs' interface option in /etc/shorewall/interfaces. If set to the empty
-# value ( SMURF_LOG_LEVEL="" ) then dropped smurfs are not logged.
+#'nosmurfs' interface option in /etc/shorewall/interfaces and in
+# /etc/shorewall/hosts. If set to the empty value ( SMURF_LOG_LEVEL=""
+# ) then dropped smurfs are not logged.
+
+#
+# See the comment at the top of this section for a description of log levels
+#
SMURF_LOG_LEVEL=info
+#
+# BOGON Log Level
+#
+# Specifies the logging level for bogon packets dropped by the
+#'nobogons' interface option in /etc/shorewall/interfaces and in
+# /etc/shorewall/hosts. If set to the empty value
+# ( BOGON_LOG_LEVEL="" ) then packets whose TARGET is 'logdrop'
+# in /usr/share/shorewall/bogons are logged at the 'info' level.
+#
+# See the comment at the top of this section for a description of log levels
+#
+
+BOGON_LOG_LEVEL=info
################################################################################
# L O C A T I O N O F F I L E S A N D D I R E C T O R I E S
################################################################################
@@ -417,7 +435,7 @@ MUTEX_TIMEOUT=60
# established connection.
#
# If NEWNOTSYN is set to "No" or "no", then non-SYN packets that are not
-# part of an already established connection, it will be dropped by the
+# part of an already established connection will be dropped by the
# firewall. The setting of LOGNEWNOTSYN above determines if these packets are
# logged before they are dropped.
#
@@ -429,7 +447,9 @@ MUTEX_TIMEOUT=60
# also need to select NEWNOTSYN=Yes.
#
# The behavior of NEWNOTSYN=Yes may also be enabled on a per-interface basis
-# using the 'newnotsyn' option in /etc/shorewall/interfaces.
+# using the 'newnotsyn' option in /etc/shorewall/interfaces and on a
+# network or host basis using the same option in /etc/shorewall/hosts.
+
#
# I find that NEWNOTSYN=No tends to result in lots of "stuck"
# connections because any network timeout during TCP session tear down
@@ -524,6 +544,18 @@ MODULE_SUFFIX=
# firewall system. This requires that you have ip6tables installed.
DISABLE_IPV6=Yes
+
+#
+# BRIDGING
+#
+# If you wish to control traffic through a bridge (see http://bridge.sf.net),
+# then set BRIDGING=Yes. Your kernel must have the physdev match option
+# enabled; that option is available at the above URL for 2.4 kernels and
+# is included as a standard part of the 2.6 series kernels. If not
+# specified or specified as empty (BRIDGING="") then "No" is assumed.
+#
+
+BRIDGING=No
################################################################################
# P A C K E T D I S P O S I T I O N
################################################################################
@@ -534,6 +566,7 @@ DISABLE_IPV6=Yes
# Blacklisted systems. Must be DROP or REJECT. If not set or set to empty,
# DROP is assumed.
#
+
BLACKLIST_DISPOSITION=DROP
#
@@ -552,8 +585,9 @@ MACLIST_DISPOSITION=REJECT
#
# This variable determins the disposition of packets having an invalid
# combination of TCP flags that are received on interfaces having the
-# 'tcpflags' option specified in /etc/shorewall/interfaces. If not specified
-# or specified as empty (TCP_FLAGS_DISPOSITION="") then DROP is assumed.
+# 'tcpflags' option specified in /etc/shorewall/interfaces or in
+# /etc/shorewall/hosts. If not specified or specified as empty
+# (TCP_FLAGS_DISPOSITION="") then DROP is assumed.
TCP_FLAGS_DISPOSITION=DROP
diff --git a/STABLE2/shorewall.spec b/STABLE2/shorewall.spec
index 6ff60c28d..dbf66a6bb 100644
--- a/STABLE2/shorewall.spec
+++ b/STABLE2/shorewall.spec
@@ -1,5 +1,5 @@
%define name shorewall
-%define version 2.0.0b
+%define version 2.0.1
%define release 1
%define prefix /usr
@@ -78,6 +78,7 @@ fi
%attr(0600,root,root) %config(noreplace) /etc/shorewall/interfaces
%attr(0600,root,root) %config(noreplace) /etc/shorewall/rules
%attr(0600,root,root) %config(noreplace) /etc/shorewall/nat
+%attr(0600,root,root) %config(noreplace) /etc/shorewall/netmap
%attr(0600,root,root) %config(noreplace) /etc/shorewall/params
%attr(0600,root,root) %config(noreplace) /etc/shorewall/proxyarp
%attr(0600,root,root) %config(noreplace) /etc/shorewall/routestopped
@@ -133,14 +134,31 @@ fi
%attr(0544,root,root) /usr/share/shorewall/firewall
%attr(0544,root,root) /usr/share/shorewall/help
%attr(0600,root,root) /usr/share/shorewall/rfc1918
+%attr(0600,root,root) /usr/share/shorewall/bogons
%doc COPYING INSTALL changelog.txt releasenotes.txt tunnel
%changelog
-* Sat Mar 20 2004 Tom Eastep
-- Update for 2.0.0b
+* Mon Apr 05 2004 Tom Eastep tom@shorewall.net
+- Updated for 2.0.1-1
+* Thu Apr 02 2004 Tom Eastep tom@shorewall.net
+- Updated for 2.0.1 RC5
+* Thu Apr 01 2004 Tom Eastep tom@shorewall.net
+- Updated for 2.0.1 RC4
+* Sun Mar 28 2004 Tom Eastep tom@shorewall.net
+- Updated for 2.0.1 RC3
+* Thu Mar 25 2004 Tom Eastep tom@shorewall.net
+- Updated for 2.0.1 RC2
+* Wed Mar 24 2004 Tom Eastep tom@shorewall.net
+- Updated for 2.0.1 RC1
+* Fri Mar 19 2004 Tom Eastep tom@shorewall.net
+- Updated for 2.0.1 Beta 2
+* Thu Mar 18 2004 Tom Eastep tom@shorewall.net
+- Added netmap file
* Wed Mar 17 2004 Tom Eastep
-- Update for 2.0.0a
+- Update for 2.0.1 Beta 1
+* Wed Mar 17 2004 Tom Eastep
+- Add bogons file
* Sat Mar 13 2004 Tom Eastep
- Update for 2.0.0 Final
* Sat Mar 06 2004 Tom Eastep
diff --git a/STABLE2/uninstall.sh b/STABLE2/uninstall.sh
index cd5251bbc..a7a06e9cd 100755
--- a/STABLE2/uninstall.sh
+++ b/STABLE2/uninstall.sh
@@ -26,7 +26,7 @@
# You may only use this script to uninstall the version
# shown below. Simply run this script to remove Seattle Firewall
-VERSION=2.0.0b
+VERSION=2.0.1
usage() # $1 = exit status
{
diff --git a/Shorewall-Website/Banner.html b/Shorewall-Website/Banner.html
index a4fcd9ad8..b64ca2cce 100755
--- a/Shorewall-Website/Banner.html
+++ b/Shorewall-Website/Banner.html
@@ -1,11 +1,10 @@
-
+
Banner
-
+
diff --git a/Shorewall-Website/News.htm b/Shorewall-Website/News.htm
index b76ab6b2a..2196e304a 100644
--- a/Shorewall-Website/News.htm
+++ b/Shorewall-Website/News.htm
@@ -18,9 +18,235 @@ Texts. A copy of the license is included in the section entitled “GNU Free
Documentation Licenseâ€.
-2004-01-30
+
2004-04-05
+3/14/2004 - Shorewall 2.0.0b
+Corrects two problems:
+
+ - Thanks to Sean Mathews, the long-standing problem with
+Proxy ARP and IPSEC has been eliminated!
+ - The default value of the ALL INTERFACES column in
+/etc/shorewall/nat is documented as 'No' but the default continued to
+be 'Yes' as it was in Shorewall 1.4.
+
+
+3/14/2004 - Shorewall 2.0.0a
+Corrects one problem:
+
+
+ - Rules of the form:
+
+<action>
+zone1 zone2
+
+generated a warning stating that the rule was a policy.
+
+
+3/14/2004 - Shorewall 2.0.0
+
+Dedicated to Agnes Van Slyke Eastep: March 14, 1910 - February
+23, 2004
+
+Problems Corrected since 1.4.10
+
+
+ - A blank USER/GROUP column in /etc/shorewall/tcrules no
+longer causes a [re]start error.
+ - The 'fgrep' utility is no longer required (caused startup
+problems on LEAF/Bering).
+ - The "shorewall add" command no longer inserts rules before
+checking of the blacklist.
+ - The 'detectnets' and 'routeback' options may now be used
+together with the intended effect.
+ - The following syntax previously produced an error:
+
+DNAT z1!z2,z3 z4...
+
+
+Problems Corrected since RC2
+
+
+
+ - CONTINUE rules now work again.
+ - A comment in the rules file has been corrected.
+
+
+Issues when migrating from Shorewall 1.4.x to Shorewall 2.0.0:
+
+
+ - The 'dropunclean' and 'logunclean' interface options are no
+longer supported. If either option is specified in
+/etc/shorewall/interfaces, an threatening message will be generated.
+ - The NAT_BEFORE_RULES option has been removed from
+shorewall.conf. The behavior of Shorewall is as if NAT_BEFORE_RULES=No
+had been specified. In other words, DNAT rules now always take
+precidence over one-to-one NAT specifications.
+ - The default value for the ALL INTERFACES column in
+/etc/shorewall/nat has changed. In Shorewall 1.*, if the column was
+left empty, a value of "Yes" was assumed. This has been changed so that
+a value of "No" is now assumed.
+ - The following files don't exist in Shorewall 2.0:
+/etc/shorewall/common.def
+/etc/shorewall/common
+/etc/shorewall/icmpdef
+/etc/shorewall/action.template (Moved to /usr/share/shorewall)
+/etc/shorewall/rfc1918 (Moved to /usr/share/shorewall).
+
+The /etc/shorewall/action file now allows an action to be designated as
+the "common" action for a particular policy type by following the
+action name with ":" and the policy (DROP, REJECT or ACCEPT).
+
+The file /usr/share/shorewall/actions.std has been added to define
+those actions that are released as part of Shorewall. In that file are
+two actions as follows:
+
+ Drop:DROP
+ Reject:REJECT
+
+The "Drop" action is the common action for DROP policies while the
+"Reject" action is the default action for "REJECT" policies. These
+actions will be performed on packets prior to applying the DROP or
+REJECT policy respectively. In the first release, the difference
+between "Reject" and "Drop" is that "Reject" REJECTs SMB traffic while
+"Drop" silently drops such traffic.
+
+As described above, Shorewall allows a common action for ACCEPT
+policies but does not specify such an action in the default
+configuration.
+
+If for some reason, you don't wish to have a common DROP or REJECT
+action, just include :DROP or :REJECT respectively in your
+/etc/shorewall/actions file.
+
+The file /usr/share/shorewall/actions.std catalogs the standard actions
+and is processed prior to /etc/shorewall/actions. This causes a large
+number of actions to be defined. The files which define these aactions
+are also located in /usr/share/shorewall as is the he action template
+file (action.template).
+
+These actions may be used in the ACTION column of the rules column. So
+for example, to allow FTP from your loc zone to your firewall, you
+would place this rule in /etc/shorewall/rules:
+
+ #ACTION
+SOURCE DEST
+ AllowFTP
+loc
+ fw
+
+If you want to redefine any of the Shorewall-defined actions, simply
+copy the appropriate action file from /usr/share/shorewall to
+/etc/shorewall and modify the copy as desired. Your modified copy will
+be used rather than the original one in /usr/share/shorewall.
+
+Note: The 'dropBcast' and 'dropNonSyn' actions are built into Shorewall
+and may not be changed.
+
+Beginning with version 2.0.0-Beta2, Shorewall will only create a chain
+for those actions that are actually used.
+
+
+ - The /etc/shorewall directory no longer contains a 'users'
+file or a 'usersets' file. Similar functionality is now available using
+user-defined actions.
+
+Now, action files created by copying
+/usr/share/shorewall/action.template may specify a USER and or GROUP
+name/id in the final column just like in the rules file (see below). It
+is thus possible to create actions that control traffic from a list of
+users and/or groups.
+
+The last column in /etc/shorewall/rules is now labeled USER/GROUP and
+may contain:
+
+ [!]<user number>[:]
+ [!]<user name>[:]
+ [!]:<group number>
+ [!]:<group name>
+ [!]<user number>:<group number>
+ [!]<user number>:<group name>
+ [!]<user name>:<group number>
+ [!]<user name>:<group name>
+
+
+ - It is no longer possible to specify rate limiting in the
+ACTION column of /etc/shorewall/rules -- you must use the RATE LIMIT
+column.
+
+
+ - Depending on which method you use to upgrade, if you have
+your own version of /etc/shorewall/rfc1918, you may have to take
+special action to restore it after the upgrade. Look for
+/etc/shorewall/rfc1918*, locate the proper file and rename it back to
+/etc/shorewall/rfc1918. The contents of that file will supercede the
+contents of /usr/share/shorewall/rfc1918.
+
+New Features:
+
+
+ - The INCLUDE directive now allows absolute file names.
+ - A 'nosmurfs' interface option has been added to
+/etc/shorewall/interfaces. When specified for an interface, this option
+causes smurfs (packets with a broadcast address as their source) to be
+dropped and optionally logged (based on the setting of a new
+SMURF_LOG_LEVEL option in shorewall.conf).
+ - fw->fw traffic may now be controlled by Shorewall. There
+is no need to define the loopback interface in
+/etc/shorewall/interfaces; you simply add a fw->fw policy and
+fw->fw rules. If you have neither a fw->fw policy nor fw->fw
+rules, all fw->fw traffic is allowed.
+ - There is a new PERSISTENT column in the proxyarp file. A
+value of "Yes" in this column means that the route added by Shorewall
+for this host will remain after a "shorewall stop" or "shorewall clear".
+ - "trace" is now a synonym for "debug" in /sbin/shorewall
+commands. So to trace the "start" command, you could enter:
+
+shorewall trace start 2> /tmp/trace
+
+The trace information would be written to the file /tmp/trace.
+
+
+ - When defining an ipsec tunnel in /etc/shorewall/tunnels, if
+you follow the tunnel type ("ipsec" or "ipsecnet") with ":noah" (e.g.,
+"ipsec:noah"), then Shorewall will only create rules for ESP (protocol
+50) and will not create rules for AH (protocol 51).
+ - A new DISABLE_IPV6 option has been added to shorewall.conf.
+When this option is set to "Yes", Shorewall will set the policy for the
+IPv6 INPUT, OUTPUT and FORWARD chains to DROP during "shorewall
+[re]start" and "shorewall stop". Regardless of the setting of this
+variable, "shorewall clear" will silently attempt to set these policies
+to ACCEPT.
+
+If this option is not set in your existing shorewall.conf then a
+setting of DISABLE_IPV6=No is assumed in which case, Shorewall will not
+touch any IPv6 settings except during "shorewall clear".
+ - The CONTINUE target is now available in action definitions.
+CONTINUE terminates processing of the current action and returns to the
+point where that action was invoked.
+
+2/15/2004 - Shorewall 1.4.10c
+Corrects one problem:
+
+Entries in /etc/shorewall/tcrules with an empty USER/GROUP column would
+cause a startup error.
+2/12/2004 - Shorewall 1.4.10b
+Corrects one problem:
+
+
+ - In the /etc/shorewall/masq entry “eth0:!10.1.1.150
+ 0.0.0.0/0!10.1.0.0/16 10.1.2.16â€, the
+“!10.1.0.0/16†is ignored.
+
+2/8/2004 - Shorewall 1.4.10a
+Corrects two problems:
+
+
+ - A problem which can cause [re]start to fail inexplicably
+while processing /etc/shorewall/masq.
+ - Interfaces using the Atheros WiFi card to use the 'maclist'
+option.
+
1/30/2004 - Shorewall 1.4.10
Problems Corrected since version 1.4.9
diff --git a/Shorewall-Website/SeattleInTheSpring.html b/Shorewall-Website/SeattleInTheSpring.html
index 31c8c8231..083f3936b 100755
--- a/Shorewall-Website/SeattleInTheSpring.html
+++ b/Shorewall-Website/SeattleInTheSpring.html
@@ -8,7 +8,6 @@
--+
Visit Seattle in the Springtime!!!
diff --git a/Shorewall-Website/Shorewall_index_frame.htm b/Shorewall-Website/Shorewall_index_frame.htm
index 99bd80c23..0aba4cb76 100644
--- a/Shorewall-Website/Shorewall_index_frame.htm
+++ b/Shorewall-Website/Shorewall_index_frame.htm
@@ -7,54 +7,50 @@
-
-Copyright © 2001-2004 Thomas
-M. Eastep.
-
+
+
+
+Copyright © 2001-2004 Thomas
+M. Eastep.
+
+
diff --git a/Shorewall-Website/Shorewall_sfindex_frame.htm b/Shorewall-Website/Shorewall_sfindex_frame.htm
index afeb12fa1..21f2a7c6c 100644
--- a/Shorewall-Website/Shorewall_sfindex_frame.htm
+++ b/Shorewall-Website/Shorewall_sfindex_frame.htm
@@ -37,11 +37,14 @@ Guides (HOWTOs)
target="_top">Wiki)
- Useful Links
- - Things to try if it doesn't
+
- Troubleshooting - Things to try if
+it doesn't
work
- Errata
- Upgrade Issues
- - Getting help or Answers to Questions
+ - Support
+- Getting help or Answers to Questions
- Mailing Lists
@@ -66,7 +69,11 @@ Repository
Copyright © 2001-2004 Thomas M. Eastep.
+
-
+This site is hosted by the generous folks at SourceForge.net