#!/bin/sh

# Debug option
# set -x

# Set whether to use tc filter or iptables for classifying
CLASSIFIER='iptables'      # replace with 'filter' if necessary

# Paths
AWK='/usr/bin/awk'
GREP='/bin/grep'
IPTABLES='/sbin/iptables'
LSMOD='/sbin/lsmod'
MODPROBE='/sbin/modprobe'

# Declare some constants
EXT_IF='eth0'
INT_IF='eth1'
EXT_IP=`/sbin/ifconfig $EXT_IF | grep 'inet addr' | awk '{split($2,a,":"); print a[2]}'`
INT_LAN='192.168.1.0/24'

# Define our users
INT_U_1='192.168.1.11'
INT_U_2='192.168.1.12'
INT_U_3='192.168.1.13'
INT_U_4='192.168.1.14'

fw_start() {

   # Enable forwarding
   echo 1 > /proc/sys/net/ipv4/ip_forward
   
   # Load some required (and a few optional) kernel modules
   if [ -z "` $LSMOD | $GREP ip_tables | $AWK {'print $1'} `" ]; then
      $MODPROBE ip_tables
   fi
   if [ -z "` $LSMOD | $GREP ip_conntrack | $AWK {'print $1'} `" ]; then
      $MODPROBE ip_conntrack
   fi
   if [ -z "` $LSMOD | $GREP ip_conntrack_ftp | $AWK {'print $1'} `" ]; then
      $MODPROBE ip_conntrack_ftp
   fi
   if [ -z "` $LSMOD | $GREP ip_conntrack_irc | $AWK {'print $1'} `" ]; then
      $MODPROBE ip_conntrack_irc
   fi
   if [ -z "` $LSMOD | $GREP iptable_nat | $AWK {'print $1'} `" ]; then
      $MODPROBE iptable_nat
   fi
   if [ -z "` $LSMOD | $GREP ip_nat_ftp | $AWK {'print $1'} `" ]; then
      $MODPROBE ip_nat_ftp
   fi
   if [ -z "` $LSMOD | $GREP ip_nat_irc | $AWK {'print $1'} `" ]; then
      $MODPROBE ip_nat_irc
   fi
   
   # Enable Route Verification
   for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
      echo 0 > $f
   done
   
   # Flush any existing rules
   $IPTABLES -F
   $IPTABLES -F -t nat
   $IPTABLES -F -t mangle
   $IPTABLES -X
   $IPTABLES -Z
   
   # Set default policy
   $IPTABLES -P INPUT DROP
   $IPTABLES -P OUTPUT ACCEPT
   $IPTABLES -P FORWARD DROP
   
   $IPTABLES -A INPUT -i lo -j ACCEPT      # loopback interface
   $IPTABLES -A INPUT -p ICMP -j ACCEPT      # ping
   $IPTABLES -A INPUT -p tcp --dport 22 -j ACCEPT      # SSH
   $IPTABLES -A INPUT -i $INT_IF -s $INT_LAN -j ACCEPT
   
   $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
   
   # Users 1 to 4 and default rule for all others. Upload and download respectively.
   case $CLASSIFIER in
      iptables)
         $IPTABLES -t mangle -A POSTROUTING -s $INT_U_1 -j CLASSIFY --set-class 1:11
         $IPTABLES -t mangle -A POSTROUTING -d $INT_U_1 -j CLASSIFY --set-class 2:11
         $IPTABLES -t mangle -A POSTROUTING -s $INT_U_2 -j CLASSIFY --set-class 1:12
         $IPTABLES -t mangle -A POSTROUTING -d $INT_U_2 -j CLASSIFY --set-class 2:12
         $IPTABLES -t mangle -A POSTROUTING -s $INT_U_3 -j CLASSIFY --set-class 1:13
         $IPTABLES -t mangle -A POSTROUTING -d $INT_U_3 -j CLASSIFY --set-class 2:13
         $IPTABLES -t mangle -A POSTROUTING -s $INT_U_4 -j CLASSIFY --set-class 1:14
         $IPTABLES -t mangle -A POSTROUTING -d $INT_U_4 -j CLASSIFY --set-class 2:14
         ;;
   filter)
         $IPTABLES -t mangle -A FORWARD -s $INT_U_1 -j MARK --set-mark 111
         $IPTABLES -t mangle -A FORWARD -d $INT_U_1 -j MARK --set-mark 211
         $IPTABLES -t mangle -A FORWARD -s $INT_U_2 -j MARK --set-mark 112
         $IPTABLES -t mangle -A FORWARD -d $INT_U_2 -j MARK --set-mark 212
         $IPTABLES -t mangle -A FORWARD -s $INT_U_3 -j MARK --set-mark 113
         $IPTABLES -t mangle -A FORWARD -d $INT_U_3 -j MARK --set-mark 213
         $IPTABLES -t mangle -A FORWARD -s $INT_U_4 -j MARK --set-mark 114
         $IPTABLES -t mangle -A FORWARD -d $INT_U_4 -j MARK --set-mark 214
         ;;
   esac
   
   $IPTABLES -A FORWARD -i $INT_IF -s $INT_LAN -j ACCEPT
   $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
   
   $IPTABLES -t nat -A POSTROUTING -s $INT_LAN -o $EXT_IF -j SNAT --to $EXT_IP

}

fw_stop() {

   echo 0 > /proc/sys/net/ipv4/ip_forward

   # Flush any existing rules
   $IPTABLES -F 
   $IPTABLES -F -t nat
   $IPTABLES -F -t mangle
   $IPTABLES -X 
   $IPTABLES -Z
   
   # Set default policy
   $IPTABLES -P INPUT ACCEPT
   $IPTABLES -P OUTPUT ACCEPT
   $IPTABLES -P FORWARD ACCEPT

}

fw_restart() {

   fw_start

}

case "$1" in

  start)

    echo -n "Starting firewall: "
    fw_start
    echo "done"
    ;;

  stop)

    echo -n "Stopping firewall: "
    fw_stop
    echo "done"
    ;;

  restart)

    echo -n "Restarting firewall: "
    fw_restart
    echo "done"
    ;;

  *)

    echo "Usage: /etc/init.d/firewall.sh {start|stop|restart}"
    ;;

esac

exit 0
