=================================================================== RCS file: /home/cvsd/home/cvs/scripts/shell/firewall/fw-universal.sh,v retrieving revision 2.35 retrieving revision 2.36 diff -u -p -r2.35 -r2.36 --- scripts/shell/firewall/fw-universal.sh 2006/01/10 01:33:26 2.35 +++ scripts/shell/firewall/fw-universal.sh 2006/01/12 20:05:34 2.36 @@ -5,7 +5,7 @@ # Can be started by init or by hand. # # Developed by Lubomir Host 'rajo' -# Copyright (c) 2003-2005 Platon SDG, http://platon.sk/ +# Copyright (c) 2003-2006 Platon SDG, http://platon.sk/ # Licensed under terms of GNU General Public License. # All rights reserved. # @@ -78,6 +78,16 @@ TRACEROUTE_DEST_PORTS="33434:33523" # Tr # allow some ICMP packets - needed for ping etc. ACCEPT_ICMP_PACKETS="${ACCEPT_ICMP_PACKETS:=echo-reply destination-unreachable echo-request time-exceeded}" +print_first() +{ # {{{ + echo $1 +} # }}} + +get_first_ip_addr() +{ # {{{ + varname="$1" + print_first `echo ${!varname} | sort -g` +} # }}} # load necessary modules from $MODULES variable load_modules() @@ -132,8 +142,11 @@ print_iface_status() # Print interfaces: echo "# iface | IP addr | Gateway | broadcast | netmask | HW addr" for iface in $interfaces; do - IP="IP_$iface"; Gateway="Gateway_$iface"; Bcast="Bcast_$iface"; Mask="Mask_$iface"; HWaddr="HWaddr_$iface"; - echo "$iface | ${!IP} | ${!Gateway} | ${!Bcast} | ${!Mask} | ${!HWaddr}" + IPS="IP_$iface"; + for IP in ${!IPS}; do + Gateway="Gateway_$iface"; Bcast="Bcast_$iface"; Mask="Mask_$iface"; HWaddr="HWaddr_$iface"; + echo "$iface | ${IP} | ${!Gateway} | ${!Bcast} | ${!Mask} | ${!HWaddr}" + done done } # }}} @@ -333,11 +346,11 @@ masquerade() echo " done." echo -en "NAT: Masquerading local subnet: $NAT_SUBNET_IFACE --> $NAT_LAN_IFACE" - ip="IP_$NAT_SUBNET_IFACE"; + ip="`get_first_ip_addr IP_$NAT_SUBNET_IFACE`" netmask="Mask_$NAT_SUBNET_IFACE" localnet="${!ip}/${!netmask}" - lan_ip="IP_$NAT_LAN_IFACE" + lan_ip="`get_first_ip_addr IP_$NAT_LAN_IFACE`" # alow packets from private subnet $IPTABLES -A FORWARD -s ! $localnet -i $NAT_SUBNET_IFACE -j DROP @@ -440,7 +453,6 @@ drop_output() { # {{{ for iface in $INTERFACES; do - ip="IP_$iface"; drop_output_tcp="${iface}_DROP_OUTPUT_TCP" DROP_OUTPUT_TCP="${!drop_output_tcp}" drop_output_udp="${iface}_DROP_OUTPUT_UDP" @@ -519,9 +531,11 @@ allow_input() echo -en "Accepting ALL INPUT TCP connections on ports:" for port in $ALL_ACCEPT_INPUT_TCP; do for iface in $INTERFACES; do - ip="IP_$iface"; echo -en " $port($iface)" - $IPTABLES -A INPUT -i $iface -d ${!ip} -p TCP --dport $port -j ACCEPT + IPS="IP_$iface"; + for ip in ${!IPS}; do + $IPTABLES -A INPUT -i $iface -d $ip -p TCP --dport $port -j ACCEPT + done done done echo " done." @@ -530,16 +544,18 @@ allow_input() echo -en "Accepting ALL INPUT UDP connections on ports:" for port in $ALL_ACCEPT_INPUT_UDP; do for iface in $INTERFACES; do - ip="IP_$iface"; echo -en " $port($iface)" - $IPTABLES -A INPUT -i $iface -p UDP --dport $port -j ACCEPT + IPS="IP_$iface"; + for ip in ${!IPS}; do + $IPTABLES -A INPUT -i $iface -d $ip -p UDP --dport $port -j ACCEPT + done done done echo " done." fi for iface in $INTERFACES; do - ip="IP_$iface"; + IPS="IP_$iface"; accept_input_tcp="${iface}_ACCEPT_INPUT_TCP" ACCEPT_INPUT_TCP="${!accept_input_tcp}" accept_input_udp="${iface}_ACCEPT_INPUT_UDP" @@ -549,7 +565,9 @@ allow_input() echo -en "$iface: Accepting INPUT TCP connections on ports:" for port in $ACCEPT_INPUT_TCP; do echo -en " $port" - $IPTABLES -A INPUT -i $iface -d ${!ip} -p TCP --dport $port -j ACCEPT + for ip in ${!IPS}; do + $IPTABLES -A INPUT -i $iface -d $ip -p TCP --dport $port -j ACCEPT + done done echo " done." fi @@ -560,7 +578,9 @@ allow_input() echo -en " $port" #$IPTABLES -A INPUT -i $iface -d ${!INET_IP} -p UDP --dport $port -j ACCEPT #$IPTABLES -A INPUT -i $iface --source 192.168.1.0/16 -p UDP --dport $port -j ACCEPT - $IPTABLES -A INPUT -i $iface -p UDP --dport $port -j ACCEPT + for ip in ${!IPS}; do + $IPTABLES -A INPUT -i $iface -d $ip -p UDP --dport $port -j ACCEPT + done done echo " done." fi @@ -568,12 +588,12 @@ allow_input() # Enable outgoing TRACEROUTE requests (required e.g. by Skype, http://www.skype.com) if [ ! -z "$TRACEROUTE_IFACE" ]; then - ip="IP_$ANTISPOOF_IFACE"; + ip="`get_first_ip_addr IP_$ANTISPOOF_IFACE`"; echo -en "Accepting traceroute:" $IPTABLES -A OUTPUT -o $ANTISPOOF_IFACE -p UDP \ --sport $TRACEROUTE_SRC_PORTS --dport $TRACEROUTE_DEST_PORTS \ - -s ${!ip} -d $ANYWHERE -j ACCEPT + -s $ip -d $ANYWHERE -j ACCEPT for iface in $TRACEROUTE_IFACE; do $IPTABLES -A FORWARD -p UDP -i $iface --sport $TRACEROUTE_SRC_PORTS \ @@ -591,9 +611,11 @@ allow_output() # Povolíme odchozí pakety, které mají naše IP adresy echo -en "Accepting OUTPUT packets from" for iface in $INTERFACES; do - ip="IP_$iface"; - echo -en " ${!ip}($iface)" - $IPTABLES -A OUTPUT -o $iface -s ${!ip} -j ACCEPT + IPS="IP_$iface"; + for ip in ${!IPS}; do + echo -en " $ip($iface)" + $IPTABLES -A OUTPUT -o $iface -s $ip -j ACCEPT + done done; echo " done."; @@ -612,8 +634,10 @@ allow_icmp() for type in $ACCEPT_ICMP_PACKETS; do echo -en " $type" for iface in $INTERFACES; do - ip="IP_$iface"; - $IPTABLES -A INPUT -i $iface -d ${!ip} -p ICMP --icmp-type $type -j ACCEPT + IPS="IP_$iface"; + for ip in ${!IPS}; do + $IPTABLES -A INPUT -i $iface -d $ip -p ICMP --icmp-type $type -j ACCEPT + done done done #$IPTABLES_LOG -A INPUT -p ICMP -j LOG --log-prefix "IN ICMP: " @@ -669,7 +693,7 @@ do_ip_accounting() $IPTABLES -N $IPACCT_OUT_NAME # upload: from client to server $IPTABLES -A $IPACCT_OUT_NAME - ip="IP_$NAT_SUBNET_IFACE"; + ip="`get_first_ip_addr IP_$NAT_SUBNET_IFACE`"; netmask="Mask_$NAT_SUBNET_IFACE" localnet="${!ip}/${!netmask}" @@ -707,8 +731,10 @@ accept_related() echo -en "Accepting ESTABLISHED, RELATED packets for IP:" for iface in $INTERFACES; do - ip="IP_$iface"; - echo -en " ${!ip}($iface)" + IPS="IP_$iface"; + for ip in ${!IPS}; do + echo -en " $ip($iface)" + done $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT done @@ -733,34 +759,51 @@ parse_ifconfig() { # {{{ # Parse output from ifconfig: parsed_interfaces=`$IFCONFIG | \ - $AWK 'BEGIN { interfaces=""; } - /^[a-zA-Z0-9]+[ \t]+/ { # Linux - iface=$1; - interfaces = sprintf("%s %s", interfaces, iface); - printf "\nIFACE_%s=\"%s\"; export IFACE_%s;\n", iface, iface, iface; - printf "HWaddr_%s=\"%s\"; export HWaddr_%s;\n", iface, $5, iface; - } - /^[ \t]+inet addr:/ { # Linux - split($0, fields, "[ \t:]+"); - printf "IP_%s=\"%s\"; export IP_%s;\n", iface, fields[4], iface; - printf "Bcast_%s=\"%s\"; export Bcast_%s;\n", iface, fields[6], iface; - printf "Mask_%s=\"%s\"; export Mask_%s;\n", iface, fields[8], iface; - } - /^[a-zA-Z0-9]+:/ { # FreeBSD - iface = $1; - sub(":", "", iface); - interfaces = sprintf("%s %s", interfaces, iface); - printf "\nIFACE_%s=\"%s\"; export IFACE_%s;\n", iface, iface, iface; - } - /^[ \t]+inet [0-9]+/ { # FreeBSD - printf "IP_%s=\"%s\"; export IP_%s;\n", iface, $2, iface; - printf "Bcast_%s=\"%s\"; export Bcast_%s;\n", iface, $6, iface; - printf "Mask_%s=\"%s\"; export Mask_%s;\n", iface, $4, iface; - } - /^[ \t]+ether/ { # FreeBSD - printf "HWaddr_%s=\"%s\"; export HWaddr_%s;\n", iface, $2, iface; - } - END { printf "\ninterfaces=\"%s\"; export interfaces;\n", interfaces; } + $AWK ' +BEGIN { + iface_count = 0; +} + +/^[a-zA-Z0-9:]+[ \t]+/ { # Linux interface + split($1, fields, ":"); + iface = fields[1]; + ipcount[iface]++; + hwaddr[iface] = $NF; + iface_count++; +} + +/^[ \t]+inet addr:/ { # Linux IP address + split($0, fields, "[ \t:]+"); + ip[iface, ipcount[iface]] = fields[4]; + bcast[iface] = fields[6]; # bad for loopback interface, but we don t need this + idx = length(fields); + mask[iface] = fields[idx]; +} + +/^[ \t]+inet6 addr:/ { # Linux IPv6 address + split($0, fields, "[ \t]+"); + ip6[iface] = fields[4]; + scope6[iface] = fields[5]; +} + +END { + for (i in ip6) { printf "IFACE_6_%s=\"%s\"; export IFACE_6_%s;\n", i, ip6[i], i; } + for (i in scope6) { printf "SCOPE_6_%s=\"%s\"; export SCOPE_6_%s;\n", i, scope6[i], i; } + for (i in bcast) { printf "Bcast_%s=\"%s\"; export Bcast_%s;\n", i, bcast[i], i; } + for (i in mask) { printf "Mask_%s=\"%s\"; export Mask_%s;\n", i, mask[i], i; } + for (i in hwaddr) { printf "HWaddr_%s=\"%s\"; export HWaddr_%s;\n", i, hwaddr[i], i; } + for (i in ipcount) { printf "IPcount_%s=\"%s\"; export IPcount_%s;\n", i, ipcount[i], i; } + for (i in ipcount) { + printf "IP_%s=\"", i; + for (n = 1; n <= ipcount[i]; n++) { + printf "%s ", ip[i, n]; + } + printf "\"; export IP_%s;\n", i; + } + printf "interfaces=\""; + for (i in ipcount) { printf "%s ", i; } + printf "\"; export interfaces;\n"; +} '` eval "$parsed_interfaces";