#!/bin/sh

if [ -n "$DEBUG" ]; then
  echo "$0: Beginning $1"
fi

# Set this to your internal interface.  Everything else should be
# automatic.
intint="eth0"


PARANOID=1

if [ "$1" = "change" ]; then
  if [ "$IPADDR" = "$OLD_IPADDR" ]; then
    if [ -n "$VERBOSE" ]; then
      echo "$0: IP address unchanged; skipping."
    fi
    exit 0
  fi
fi

extint="${DEVICE}"
extip="${IPADDR}"
extmask="${NETMASK}"

for i in `/sbin/ifconfig "$intint" | grep '^ *inet'` 
do
  setting="`echo "$i" |sed -e 's/:.*$//' |tr '[A-Z]' '[a-z]'`"
  val="`echo "$i" |sed -e 's/^.*://'`"
  if [ -n "$setting" ]; then
    case "$setting" in
      addr)  intip="$val";;
      bcast) intbcast="$val" ;;  
      mask)  intmask="$val"; intnet="$intip/$intmask" ;;
    esac
  fi
done


case "$1" in
  up|change)

    if [ -n "$VERBOSE" ]; then
      echo "$0: Configuring firewall."
      echo "$0:     internal: $intint $intnet"
      echo "$0:     external: $extint $extip"
    fi

    if [ -z "${DEVICE}" -o -z "${IPADDR}" ]; then
      echo "$0: DEVICE or IPADDR not set!" 1>&2
      exit 2
    fi

    for mod in $MASQMODS
    do
      /sbin/modprobe "$mod"
    done
    
    if [ "`uname -m`" = "alpha" ]; then
      HZ=1024
    else
      HZ=100
    fi

    ICMP_MAXRATE=`expr $HZ / 3`
    echo "1" >/proc/sys/net/ipv4/ip_dynaddr  
    echo "1" >/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
    echo "$ICMP_MAXRATE" >/proc/sys/net/ipv4/icmp_destunreach_rate
    echo "$ICMP_MAXRATE" >/proc/sys/net/ipv4/icmp_paramprob_rate
    echo "$ICMP_MAXRATE" >/proc/sys/net/ipv4/icmp_timeexceed_rate
    echo "$ICMP_MAXRATE" >/proc/sys/net/ipv4/icmp_echoreply_rate
    echo "0" >/proc/sys/net/ipv4/conf/$extint/accept_redirects
    echo "0" >/proc/sys/net/ipv4/conf/$intint/accept_redirects
    echo "0" >/proc/sys/net/ipv4/conf/$extint/send_redirects
    echo "0" >/proc/sys/net/ipv4/conf/$intint/send_redirects
    echo "0" >/proc/sys/net/ipv4/conf/$extint/accept_source_route
    echo "0" >/proc/sys/net/ipv4/conf/$intint/accept_source_route

    if [ -n "$PARANOID" ]
    then
    
      # Reject by default.
      /sbin/ipchains -F input
      /sbin/ipchains -P input REJECT
    
      # Allow DHCP packets, even from martian addresses.
      /sbin/ipchains -b -A input -i $intint -s 0/0 67 -d 0/0 68 -p udp -j ACCEPT 
      /sbin/ipchains -b -A input -i $extint -s 0/0 67 -d 0/0 68 -p udp -j ACCEPT 

      # Block Martian packets
      /sbin/ipchains -A input -i $extint -s $intnet -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 127.0.0.0/8 -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 224.0.0.0/8 -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 10.0.0.0/8 -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 192.168.0.0/16 -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 169.254.0.0/16 -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 172.16.0.0/12 -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 255.255.255.255/32 -d 0.0.0.0/0 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s 0.0.0.0/32 -d 0.0.0.0/0 -l -j REJECT

      # Cisco land attack
      /sbin/ipchains -A input -i $extint -s $intip/32 -d $intip/32 -l -j REJECT
      /sbin/ipchains -A input -i $extint -s $extip/32 -d $extip/32 -l -j REJECT
      /sbin/ipchains -A input -i $intint -s $intip/32 -d $intip/32 -l -j REJECT
      /sbin/ipchains -A input -i $intint -s $extip/32 -d $extip/32 -l -j REJECT
 
      # Disallow some ICMP packets from coming in.
      # Redirect
      /sbin/ipchains -A input -i $extint -p icmp --dport 5 -l -j REJECT
      # Address mask request
      /sbin/ipchains -A input -i $extint -p icmp --dport 17 -l -j REJECT
      # Information request
      /sbin/ipchains -A input -i $extint -p icmp --dport 15 -l -j REJECT
      # Anything we've never heard of...
      /sbin/ipchains -A input -i $extint -p icmp --dport 18: -l -j REJECT

      # Specific blocked ports (Windows filesharing crap)
      /sbin/ipchains -A input -i $extint -p tcp --sport 137 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p tcp --sport 138 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p tcp --sport 139 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p tcp --sport 445 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --sport 137 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --sport 138 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --sport 139 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --sport 445 -l -j REJECT

      /sbin/ipchains -A input -i $extint -p tcp --dport 137 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p tcp --dport 138 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p tcp --dport 139 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p tcp --dport 445 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --dport 137 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --dport 138 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --dport 139 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --dport 445 -l -j REJECT

      # Local machines on local interface can go anywhere on the local network.
      # (but can't forge IP addresses)
      /sbin/ipchains -A input -i $intint -s $intnet -d 0.0.0.0/0 -j ACCEPT
  
      # Allow NTP to work
      /sbin/ipchains -A input -i $extint -p udp -d $extip/32 123 -j ACCEPT
      /sbin/ipchains -A input -i $extint -p tcp -d $extip/32 123 -j ACCEPT

      # Block any other special ports.
      /sbin/ipchains -A input -i $extint -p tcp --dport 0:1000 -l -j REJECT
      /sbin/ipchains -A input -i $extint -p udp --dport 0:1000 -l -j REJECT
 
      # Remote interface can go to permanent address
      /sbin/ipchains -A input -i $extint -s 0.0.0.0/0 -d $extip/32 -j ACCEPT
  
      # Allow anything from the loopback interface.
      /sbin/ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
  
      # Log and drop everything else.
      /sbin/ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
  
      # Outgoing Rules
  
      # Default to off.
      /sbin/ipchains -F output
      /sbin/ipchains -P output REJECT
  
      /sbin/ipchains -A output -i $extint -p tcp --sport 137 -l -j REJECT
      /sbin/ipchains -A output -i $extint -p tcp --sport 138 -l -j REJECT
      /sbin/ipchains -A output -i $extint -p tcp --sport 139 -l -j REJECT
      /sbin/ipchains -A output -i $extint -p tcp --sport 445 -l -j REJECT
      /sbin/ipchains -A output -i $extint -p udp --sport 137 -l -j REJECT
      /sbin/ipchains -A output -i $extint -p udp --sport 138 -l -j REJECT
      /sbin/ipchains -A output -i $extint -p udp --sport 139 -l -j REJECT
      /sbin/ipchains -A output -i $extint -p udp --sport 445 -l -j REJECT

      # Allow local interface to local net
      /sbin/ipchains -A output -i $intint -s 0.0.0.0/0 -d $intnet -j ACCEPT

      # Allow DHCP messages
      /sbin/ipchains -A output -i $intint -p udp --sport 67 --dport 68 -j ACCEPT
      /sbin/ipchains -A output -i $intint -p udp --sport 68 --dport 67 -j ACCEPT
  
      # Deny outgoing to local net on remote interface
      /sbin/ipchains -A output -i $extint -s 0.0.0.0/0 -d $intnet -l -j REJECT
  
      # Deny outgoing from local net on remote interface.
      # (it should be NAT'd)
      /sbin/ipchains -A output -i $extint -s $intnet -d 0.0.0.0/0 -l -j REJECT
  
      # Anything else is OK.
      /sbin/ipchains -A output -i $extint -s $extip/32 -d 0.0.0.0/0 -j ACCEPT
      /sbin/ipchains -A output -i $extint -j ACCEPT   
  
      # Loopback inteface is OK.
      /sbin/ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
  
      # Anything else
      /sbin/ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT

    fi # PARANOID

    # Forwarding


    # Start up masquerading
    /sbin/ipchains --no-warnings -F forward
    /sbin/ipchains --no-warnings -P forward DENY

    if [ -n "$PARANOID" ]; then

      /sbin/ipchains --no-warnings -A forward -i $intint -p tcp --dport 137 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p tcp --dport 138 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p tcp --dport 139 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p tcp --dport 445 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --dport 137 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --dport 138 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --dport 139 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --dport 445 -l -j REJECT

      /sbin/ipchains --no-warnings -A forward -i $extint -p tcp --dport 137 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p tcp --dport 138 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p tcp --dport 139 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p tcp --dport 445 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --dport 137 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --dport 138 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --dport 139 -l -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --dport 445 -l -j REJECT

      # Broadcast packets can't be forwarded
      /sbin/ipchains --no-warnings -A forward -i $intint -s 0.0.0.0/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -d 0.0.0.0/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -s 255.255.255.255/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -d 255.255.255.255/32 -j REJECT

      /sbin/ipchains --no-warnings -A forward -i $extint -s 0.0.0.0/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -d 0.0.0.0/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -s 255.255.255.255/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -d 255.255.255.255/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -s $intbcast/32 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -d $intbcast/32 -j REJECT

      # DHCP packets can't be forwarded
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --sport 67 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --sport 68 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --dport 67 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $intint -p udp --dport 68 -j REJECT

      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --sport 67 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --sport 68 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --dport 67 -j REJECT
      /sbin/ipchains --no-warnings -A forward -i $extint -p udp --dport 68 -j REJECT

    fi # PARANOID

;;
  
  down)

  ;;
  
  *)
    echo "Usage: $0 up|down|change"
    exit 1
  ;;
esac  

if [ -n "$DEBUG" ]; then
  echo "$0: Ending $1"
fi

exit 0
