#! /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 # /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 IPCHAINS=`which ipchains` || IPCHAINS=/sbin/ipchains LOCALNET=192.168.1.0/24 EXTNET=147.87.65.0/24 DEFAULT_GW=147.87.65.250 # 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 $IPCHAINS -P forward DENY || return=$rc_failed $IPCHAINS -P output ACCEPT || return=$rc_failed $IPCHAINS -P input DENY || return=$rc_failed $IPCHAINS -F || return=$rc_failed # drop foreign traffic without logging $IPCHAINS -A input ! -d $MY_EXT_ADDR -i $MY_EXT_IF -j DENY # reject all ident traffic for faster responses $IPCHAINS -A input -p tcp -d 0/0 auth -j REJECT $IPCHAINS -A input -p udp -d 0/0 auth -j REJECT # allow local traffic $IPCHAINS -A input -s $MY_LOCAL_ADDR -i lo -j ACCEPT $IPCHAINS -A input -s $MY_EXT_ADDR -i lo -j ACCEPT $IPCHAINS -A input -s 127.0.0.1 -i lo -j ACCEPT $IPCHAINS -A output -s $MY_LOCAL_ADDR -i lo -j ACCEPT $IPCHAINS -A output -s $MY_EXT_ADDR -i lo -j ACCEPT $IPCHAINS -A output -s 127.0.0.1 -i lo -j ACCEPT # allow dhcp queries $IPCHAINS -A input -p udp -s 0.0.0.0 68 -d 255.255.255.255 67 -i $MY_LOCAL_IF -j ACCEPT $IPCHAINS -A output -p udp -s $MY_LOCAL_ADDR 67 -d 255.255.255.255 68 -i $MY_LOCAL_IF -j ACCEPT # anti spoofing - only allow traffic to/from addresses on the corresponding interface $IPCHAINS -A input -s ! $LOCALNET -i $MY_LOCAL_IF -l -j DENY $IPCHAINS -A output -d ! $LOCALNET -i $MY_LOCAL_IF -l -j DENY $IPCHAINS -A input -s $LOCALNET ! -i $MY_LOCAL_IF -l -j DENY $IPCHAINS -A input -d $LOCALNET ! -i $MY_LOCAL_IF -l -j DENY $IPCHAINS -A output -s $LOCALNET ! -i $MY_LOCAL_IF -l -j DENY $IPCHAINS -A output -d $LOCALNET ! -i $MY_LOCAL_IF -l -j DENY $IPCHAINS -A output ! -s $MY_EXT_ADDR -i $MY_EXT_IF -l -j DENY # accept outgoing packets from localnet, but not to EXTNET (i.e. protect HTA from us;-) for net in $EXTNET do $IPCHAINS -A input -s $LOCALNET -d $net -l -j DENY done # allow port 80 -> is redirected to 8080 (dansguardian), from there to 3128 $IPCHAINS -A input -p tcp -s $LOCALNET ! -d $LOCALNET 80 -y -l -i $MY_LOCAL_IF -j REDIRECT 8080 || return=$rc_failed $IPCHAINS -A input -p tcp -s $LOCALNET ! -d $LOCALNET 80 ! -y -i $MY_LOCAL_IF -j REDIRECT 8080 || return=$rc_failed # accept paccets directly at 8080 $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR 8080 -y -l -j ACCEPT $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR 8080 ! -y -j ACCEPT # masquerade outgoing packets from localnet $IPCHAINS -A forward -s $LOCALNET -d ! $LOCALNET -i $MY_EXT_IF -j MASQ || return=$rc_failed $IPCHAINS -A input -p udp -s $LOCALNET ! -d $LOCALNET -i $MY_LOCAL_IF -j ACCEPT $IPCHAINS -A input -p tcp -s $LOCALNET ! -d $LOCALNET -y -l -i $MY_LOCAL_IF -j ACCEPT $IPCHAINS -A input -p tcp -s $LOCALNET ! -d $LOCALNET ! -y -i $MY_LOCAL_IF -j ACCEPT # accept reply packets $IPCHAINS -A input -p udp ! -s $LOCALNET -d $MY_EXT_ADDR -i $MY_EXT_IF -j ACCEPT $IPCHAINS -A input -p tcp ! -s $LOCALNET -d $MY_EXT_ADDR ! -y -i $MY_EXT_IF -j ACCEPT # we allow some icmp messages for type in echo-request echo-reply destination-unreachable source-quench time-exceeded parameter-problem fragmentation-needed do $IPCHAINS -A input -p icmp -s $LOCALNET $type -i $MY_LOCAL_IF -j ACCEPT || return=$rc_failed $IPCHAINS -A input -p icmp -s 0/0 $type -d $MY_EXT_ADDR -i $MY_EXT_IF -j ACCEPT || return=$rc_failed done # the default gateway may send all icmp messages $IPCHAINS -A input -p icmp -s $DEFAULT_GW -d $MY_EXT_ADDR -i $MY_EXT_IF -j ACCEPT || return=$rc_failed # allow service requests to this host $IPCHAINS -A input -p udp -s $LOCALNET -d $MY_LOCAL_ADDR domain -j ACCEPT -l -i $MY_LOCAL_IF || return=$rc_failed $IPCHAINS -A input -p udp -s $LOCALNET -d $MY_LOCAL_ADDR ntp -j ACCEPT -i $MY_LOCAL_IF || return=$rc_failed $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR ntp -j ACCEPT -i $MY_LOCAL_IF || return=$rc_failed $IPCHAINS -A input -p udp -s $LOCALNET -d $MY_LOCAL_ADDR time -j ACCEPT -i $MY_LOCAL_IF || return=$rc_failed $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR time -y -j ACCEPT -i $MY_LOCAL_IF || return=$rc_failed $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR ssh -y -l -j ACCEPT -i $MY_LOCAL_IF || return=$rc_failed $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR ssh ! -y -j ACCEPT -i $MY_LOCAL_IF || return=$rc_failed # allow port 3128 (squid proxy) - this could be closed if we want all HTTP traffic # to go through 8080 (dansguardian) and not allow people to manually set their browser $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR 3128 -y -l -i $MY_LOCAL_IF -j ACCEPT || return=$rc_failed $IPCHAINS -A input -p tcp -s $LOCALNET -d $MY_LOCAL_ADDR 3128 ! -y -i $MY_LOCAL_IF -j ACCEPT || return=$rc_failed # timeout for masqueraded connections - else the session times out in 5 minutes # and users on tcp sessions would have to reconnect (see ipchains --help) $IPCHAINS -M -S 7200 30 160 # deny (and log) everything else $IPCHAINS -A input -l -j DENY || return=$rc_failed echo -e "$return" ;; stop|open) echo -n "Opening up firewall" $IPCHAINS -P input ACCEPT $IPCHAINS -F echo '1' > /proc/sys/net/ipv4/ip_forward $IPCHAINS -A forward -s $LOCALNET -d ! $LOCALNET -i $MY_EXT_IF -j MASQ || 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" $IPCHAINS -P input ACCEPT $IPCHAINS -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