From 90b701de4de161318a3588ddddcbe57987c30090 Mon Sep 17 00:00:00 2001 From: teastep Date: Tue, 9 Jul 2002 15:44:49 +0000 Subject: [PATCH] Implement DETECT_IPADDRS parameter git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@128 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall/firewall | 94 ++++++++++++++++++++++++++++++++++------ Shorewall/shorewall.conf | 29 +++++++++++++ 2 files changed, 109 insertions(+), 14 deletions(-) diff --git a/Shorewall/firewall b/Shorewall/firewall index 832a636bf..5b682a09e 100755 --- a/Shorewall/firewall +++ b/Shorewall/firewall @@ -422,7 +422,7 @@ determine_interfaces() { # Determine the defined hosts in each zone and generate report # ################################################################################ determine_hosts() { - do_a_zone() # $1 = zone name + do_a_zone() { eval interfaces=\$${zone}_interfaces @@ -435,16 +435,40 @@ determine_hosts() { done } + recalculate_hosts() + { + interfaces= + + for host in $hosts; do + interface=${host%:*} + if ! list_search $interface $interfaces; then + if [ -z "$interfaces" ]; then + interfaces=$interface + else + interfaces="$interfaces $interface" + fi + fi + done + + eval ${zone}_interfaces="\$interfaces" + } + for zone in $zones; do hosts=`find_hosts $zone` hosts=`echo $hosts` # Remove extra trash - if [ -z "$hosts" ]; then + if [ -n "$hosts" ]; then + #################################################################### + # Zone is defined in terms of hosts -- derive the interface list + # from the host list + # + recalculate_hosts + else #################################################################### # If no hosts are defined for a zone then the zone consists of any # host that can send us messages via the interfaces to the zone # - do_a_zone $zone + do_a_zone fi eval ${zone}_hosts="\$hosts" @@ -698,7 +722,7 @@ validate_rule() { case $target in DNAT) target=ACCEPT - address=${address:=all} + address=${address:=detect} ;; REDIRECT) target=ACCEPT @@ -878,6 +902,27 @@ find_broadcasts() { done < $TMP_DIR/interfaces } +################################################################################ +# Find interface address--returns the first IP address assigned to the passed # +# device # +################################################################################ +find_interface_address() # $1 = interface +{ + # + # get the line of output containing the first IP address + # + addr=`ip addr show $1 2> /dev/null | grep inet | head -n1` + # + # If there wasn't one, bail out now + # + [ -n "$addr" ] || fatal_error "Can't determine the IP address of $1" + # + # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) + # along with everything else on the line + # + echo $addr | sed 's/inet //;s/\/.*//;s/ peer.*//' +} + ################################################################################ # Find interfaces that have the passed option specified # ################################################################################ @@ -1170,8 +1215,8 @@ setup_syn_flood_chain () run_iptables -N @$chain run_iptables -A @$chain \ - -m limit --limit $limit --limit-burst $limit_burst \ - -j RETURN + -m limit --limit $limit --limit-burst $limit_burst \ + -j RETURN run_iptables -A @$chain -j DROP } @@ -1439,7 +1484,22 @@ add_nat_rule() { # Set original destination address - [ "$addr" = "all" ] && addr= || addr=${addr:+-d $addr} + case $addr in + all) + addr= + ;; + detect) + addr= + if [ -n "$DETECT_IPADDRS" && "$source"! = "$FW" ]; then + eval interfaces=\$${source}_interfaces + for interface in $interfaces; do + addr="`find_interface_address $interface` $addr" + done + fi + ;; + esac + + addr=${addr:-0.0.0.0/0} # Select target @@ -1453,7 +1513,7 @@ add_nat_rule() { # Generate nat table rules if [ "$source" = "$FW" ]; then - run_iptables -t nat -A OUTPUT $proto $sports $addr \ + run_iptables -t nat -A OUTPUT $proto $sports -d addr $multiport $dports -j $target1 else chain=`dnat_chain $source` @@ -1466,14 +1526,18 @@ add_nat_rule() { for z in $excludezones; do eval hosts=\$${z}_hosts for host in $hosts; do - addnatrule $chain $proto -s ${host#*:} \ - $multiport $sports $addr $dports -j RETURN + for adr in $addr; do + addnatrule $chain $proto -s ${host#*:} \ + $multiport $sports -d $adr $dports -j RETURN + done done done fi - - addnatrule $chain $proto $cli $sports \ - $multiport $addr $dports -j $target1 + + for adr in $addr; do + addnatrule $chain $proto $cli $sports \ + -d $adr $multiport $dports -j $target1 + done fi # Replace destination port by the new destination port @@ -1697,7 +1761,7 @@ process_rule() { case $target in DNAT) target=ACCEPT - address=${address:=all} + address=${address:=detect} ;; REDIRECT) target=ACCEPT @@ -3249,6 +3313,7 @@ do_initialize() { ROUTE_FILTER= NAT_BEFORE_RULES= MULTIPORT= + DETECT_IPADDRS= stopping= have_mutex= masq_seq=1 @@ -3322,6 +3387,7 @@ do_initialize() { 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` + DETECT_IPADDRS=`added_param_value_no DETECT_IPADDRS $DETECT_IPADDRS` } ################################################################################ diff --git a/Shorewall/shorewall.conf b/Shorewall/shorewall.conf index 7dacd3d54..79476c86e 100755 --- a/Shorewall/shorewall.conf +++ b/Shorewall/shorewall.conf @@ -228,4 +228,33 @@ NAT_BEFORE_RULES=Yes MULTIPORT=No +# IP ADDRESS DETECTION +# +# Normally when Shorewall encounters the following rule: +# +# DNAT net loc:192.168.1.3 tcp 80 +# +# it will forward TCP port 80 connections from the net to 192.168.1.3 +# REGARDLESS OF THE ORIGINAL DESTINATION ADDRESS. This behavior is +# convenient for two reasons: +# +# a) If the the network interface has a dynamic IP address, the +# firewall configuration will work even when the address +# changes. +# +# b) It saves having to configure the IP address in the rule +# while still allowing the firewall to be started before the +# internet interface is brought up. +# +# This default behavior can also have a negative effect. If the +# internet interface has more than one IP address then the above +# rule will forward connection requests on all of these addresses; +# that may not be what is desired. +# +# By setting DETECT_IPADDRS=Yes, rules such as the above will apply +# only if the original destination address is the primary IP address of +# one of the interfaces associated with the source zone. + +DETECT_IPADDRS=No + #LAST LINE -- DO NOT REMOVE