#! /bin/sh # the following 3 lines are from SuSE. # Determine the base and follow a runlevel link name. base=${0##*/} link=${base#*[SK][0-9][0-9]} # the rest is by markus@wernig.net and chris@rebmatt.ch # /etc/rc.d/firewall # sets up a packet filtering firewall with masquerading and port forwarding # (for transparent proxying by squid and/or dansguardian) # see http://www.lugbe.ch/lostfound/contrib/router_biel/ ARG=$1 . /etc/rc.config [ $START_FW = 'yes' ] || ARG='stop' # 2 more SuSE lines ;-) # The echo return value for success (defined in /etc/rc.config). return=$rc_done IPTABLES=`which iptables` || IPTABLES=/sbin/iptables LOCALNET=192.168.1.0/24 EXTNET=147.87.65.0/24 DEFAULT_GW=147.87.65.250 # Für etwas mehr "magic": #EXTNET=`netstat -rn | grep eth0 | awk '$2 == "0.0.0.0" {print $1}'`/`netstat -rn | grep eth0 | awk '$2 == "0.0.0.0" {print $3}'` #DEFAULT_GW=`netstat -rn | grep eth0 | awk '$1 == "0.0.0.0" {print $2}'` # first we have to get our interfaces/addresses # we start with a crude assumption: our local net starts with "192.168." # might fail for some nets. # get address 192.168.* MY_LOCAL_ADDR=`ifconfig |grep "192.168." | sed -e s/"inet addr\:"//g | awk '{print $1}'` # get interface for address 192.168.* for if in eth0 eth1 do if ifconfig $if | grep "$MY_LOCAL_ADDR" >/dev/null 2>&1; then MY_LOCAL_IF=$if else MY_EXT_IF=$if fi done # get other address MY_EXT_ADDR=`ifconfig $MY_EXT_IF | grep "inet addr" | sed -e s/"inet addr\:"//g | awk '{print $1}'` # blabber echo "local: $MY_LOCAL_ADDR ($MY_LOCAL_IF), external: $MY_EXT_ADDR ($MY_EXT_IF)" # script can be called by boot.local with "start" or "stop" case "$ARG" in start) echo -n "Starting firewall" # set some kernel network parameters echo '1' > /proc/sys/net/ipv4/ip_forward echo '1' > /proc/sys/net/ipv4/tcp_syncookies for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo '1' > $f done echo '0' > /proc/sys/net/ipv4/tcp_timestamps echo '30' > /proc/sys/net/ipv4/tcp_fin_timeout echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_all echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo '1' > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses # set default policies and flush chains $IPTABLES -F INPUT $IPTABLES -F OUTPUT $IPTABLES -F FORWARD $IPTABLES -t nat -F PREROUTING $IPTABLES -t nat -F POSTROUTING # set flow-chains and drop spoofed packets $IPTABLES -N Spoofed $IPTABLES -A Spoofed -j LOG --log-prefix Spoofed $IPTABLES -A Spoofed -j DROP # accept traffic on lo $IPTABLES -A INPUT -i lo -j ACCEPT $IPTABLES -A OUTPUT -o lo -j ACCEPT # enable stateful inspection $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # accept all on OUTPUT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # allow all icmp packets from the gateway $IPTABLES -A INPUT -p icmp -i $MY_EXT_IF -s $DEFAULT_GW -d $MY_EXT_ADDR -j ACCEPT # set up necessary chains $IPTABLES -N LOCALNET-FW $IPTABLES -N INTERNET-FW $IPTABLES -N LOCALNET-INTERNET $IPTABLES -N INTERNET-LOCALNET $IPTABLES -N LOCALNET-HTANET $IPTABLES -N HTANET-LOCALNET # allow dhcp to and from LOCALNET $IPTABLES -A INPUT -i $MY_LOCAL_IF -p udp -d 255.255.255.255 --dport 67 -s 0.0.0.0 --sport 68 -j ACCEPT $IPTABLES -A OUTPUT -o $MY_LOCAL_IF -p udp -s $MY_LOCAL_ADDR --sport 67 -d 255.255.255.255 --dport 68 -j ACCEPT # split the traffic to different chains, all uncatched packets are spoofed $IPTABLES -A INPUT -i $MY_LOCAL_IF -s $LOCALNET -d $MY_LOCAL_ADDR -j LOCALNET-FW $IPTABLES -A INPUT -i $MY_EXT_IF -d $MY_EXT_ADDR ! -s $EXTNET -j INTERNET-FW $IPTABLES -A INPUT -j Spoofed $IPTABLES -A FORWARD -i $MY_LOCAL_IF -s $LOCALNET -o $MY_EXT_IF ! -d $EXTNET -j LOCALNET-INTERNET $IPTABLES -A FORWARD -i $MY_EXT_IF ! -s $EXTNET -o $MY_LOCAL_IF -d $LOCALNET -j INTERNET-LOCALNET $IPTABLES -A FORWARD -i $MY_LOCAL_IF -s $LOCALNET -o $MY_EXT_IF -d $EXTNET -j LOCALNET-HTANET $IPTABLES -A FORWARD -i $MY_EXT_IF -s $EXTNET -o $MY_LOCAL_IF -d $LOCALNET -j HTANET-LOCALNET $IPTABLES -A FORWARD -j Spoofed # the Chain from LOCALNET to the Firewall for type in echo-request echo-reply destination-unreachable source-quench time-exceeded parameter-problem fragmentation-needed do $IPTABLES -A LOCALNET-FW -p icmp --icmp-type $type -j ACCEPT done $IPTABLES -A LOCALNET-FW -p tcp --dport 8080 --syn -j ACCEPT # for dansguardian $IPTABLES -A LOCALNET-FW -p udp --dport domain -j ACCEPT $IPTABLES -A LOCALNET-FW -p udp --dport ntp -j ACCEPT $IPTABLES -A LOCALNET-FW -p tcp --dport ntp --syn -j ACCEPT $IPTABLES -A LOCALNET-FW -p udp --dport time -j ACCEPT $IPTABLES -A LOCALNET-FW -p tcp --dport time --syn j ACCEPT $IPTABLES -A LOCALNET-FW -p tcp --dport ssh --syn -j ACCEPT $IPTABLES -A LOCALNET-FW -p tvd --dport squid --syn -j ACCEPT $IPTABLES -A LOCALNET-FW -j LOG --log-prefix LOCALNET-FW $IPTABLES -A LOCALNET-FW -j DROP # the Chain from the Internet to the Firewall for type in echo-request echo-reply destination-unreachable source-quench time-exceeded parameter-problem fragmentation-needed do $IPTABLES -A INTERNET-FW -p icmp --icmp-type $type -j ACCEPT done $IPTABLES -A INTERNET-FW -p tcp --dport auth -j REJECT $IPTABLES -A INTERNET-FW -p udp --dport auth -j REJECT $IPTABLES -A INTERNET-FW -j LOG --log-prefix INTERNET-FW $IPTABLES -A INTERNET-FW -j DROP # the Chain from the Localnet to the Internet $IPTABLES -A LOCALNET-INTERNET -m state --state NEW -j ACCEPT # all traffic accepted $IPTABLES -A LOCALNET-INTERNET -j LOG --log-prefix LOCALNET-INTERNET $IPTABLES -A LOCALNET-INTERNET -j DROP # Traffic from Localnet to the HTA-Net gets logged and dropped $IPTABLES -A LOCALNET-HTANET -j LOG --log-prefix LOCALNET-HTANET $IPTABLES -A LOCALNET-HTANET -j DROP # The Chain from the Internet to the Localnet $IPTABLES -A INTERNET-LOCALNET -j LOG --log-prefix INTERNET-LOCALNET $IPTABLES -A INTERNET-LOCALNET -j DROP # The CHain from the HTA-Net to the Localnet, also logged and dropped $IPTABLES -A HTANET-LOCALNET -j LOG --log-prefix HTANET-LOCALNET $IPTABLES -A HTANET-LOCALNET -j DROP # the rediredtion of http-traffic to port 8080 $IPTABLES -t nat -A PREROUTING -i $MY_LOCAL_IF -s $LOCALNET ! -d $LOCALNET -p tcp --dport http -j REDIRECT --to-ports 8080 # the masquerading of the outgoing traffic $IPTABLES -t nat -A POSTROUTING -o $MY_EXT_IF -s $LOCALNET -j MASQUERADE ;; stop|open) echo -n "Opening up firewall" $IPTABLES -P INPUT ACCEPT $IPTABLES -F $IPTABLES -t nat -F echo '1' > /proc/sys/net/ipv4/ip_forward $IPTABLES -t nat -A POSTROUTING -s $LOCALNET -d ! $LOCALNET -o $MY_EXT_IF -j MASQUERADE || return=$rc_failed echo -e "$return" # This now is a mere router with no firewall whatsoever. it just masquerades. ;; close) echo -n "Shutting down firewall" $IPTABLES -P INPUT ACCEPT $IPTABLES -F $IPTABLES -t nat -F echo '0' > /proc/sys/net/ipv4/ip_forward echo -e "$return" # No more forwarding. The net is closed off, but this host is still reachable on all ports. ;; reload|restart) $0 stop && sleep 3 && $0 start || return=$rc_failed ;; *) echo "Usage: $0 {start|stop|status|reload|restart}" exit 1 esac # Right, it's SuSE time again. # Inform the caller not only verbosely and set an exit status. test "$return" = "$rc_done" || exit 1 exit 0