#!/bin/sh

### BEGIN INIT INFO
# Provides:          firewall
# Required-Start:    $network $local_fs
# Required-Stop:     $network $local_fs
# Default-Start:     S 2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Provides basic firewall settings
# Description:       Provides basic firewall settings
#                    It is called from the boot, halt and reboot scripts.
### END INIT INFO

# ----------------------------------------------------------------------------
# firewall     Configures Linux firewall using iptables
#
#
# chkconfig: 345 09 92
# description: Configure Linux IP firewalling, natting, and forwarding
# ----------------------------------------------------------------------------
#
# Copyright (C) 2002, 2001 Jamin W. Collins
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# ----------------------------------------------------------------------------
# Version:     0.93
# Released:    2005.09.06. (YYYY.MM.DD., see: http://cowaro.com/Date/Endeavour.html)
# Author:      Jamin W. Collins
# Web Site:    http://www.asgardsrealm.net/linux/firewall
# E-Mail:      firewall@asgardsrealm.net
# ----------------------------------------------------------------------------
# v0.91		2005.09.06. Patches applied by Gabor Funk [funk.gabor@hunetkft.hu]
#	 patch:	Jacob S - "trusted connection" patch [version 0.90-p1]
#		Sat, 08 Jan 2005 14:54:42 -0800
#		http://www.mail-archive.com/firewall@asgardsrealm.net/msg00262.html
#	 patch:	Pete Barnwell "A Few To-DOs" (check_system routines)
#		Sat, 04 Oct 2003 17:59:39 -0700
#		http://www.mail-archive.com/firewall@asgardsrealm.net/msg00206.html
# v0.92		2010.08.27. added INIT INFO, removed some extra spaces [Gabor Funk]
# v0.93		2011.06.27. changed NAT/DROP [invalid] rules to FILTER/DROP
# ----------------------------------------------------------------------------
#
# This script is based on various different script files that I've
# stumbled acrossed while learning Linux.  The purpose of this script
# is simply to provide an easy to use configurable Firewall/NAT
# solution.
#
# Some of the scripts that have influenced this are:
#  - custom ipchains script (written by Gordon Messmer)
#  - RH 7.1's default iptables and ipchains scripts
#
# I would like to seriously thank Gordon Messmer for his ipchains
# script.  This script was of considerable use in getting my first
# firewall up and running.  Much of this script has been directly
# influenced by his ipchains firewall.
#
# I would like to thank the following people for their testing and
# contributions to this script:
#
#  David Kurn  david@daku.org
#
# Feel free to use and distribute this script if you find it of use.
# I simply ask that you leave these comments intact in doing so.
#
# Suggestions are always welcome.
#
# TODO:
#  - Security Audit (is firewall secure during restart condition?)


# Source functions
#. /etc/rc.d/init.d/functions

# Source configuration
. /etc/firewall.conf

# ----------------------------------------------------------------------------

success() {
# added as simple means of removing dependency on RH's function script
echo -n " - OK"

}

failure() {
# added as simple means of removing dependency on RH's function script
echo -n " - FAILED"
}

passed() {
# added as simple means of removing dependency on RH's function script
echo -n " - PASSED"
}

check_system() {
# Purpose: Ensure that we have what is necessary before continuing

   # Gather kernel information
   KERNELMAJ=`uname -r | sed                   -e 's,\..*,,'`
   KERNELMIN=`uname -r | sed -e 's,[^\.]*\.,,' -e 's,\..*,,'`

   # Check to see if the kernel major number is 2 or better
   if [ "$KERNELMAJ" -lt 2 ] ; then
      # kernel major number is too old
      echo "Kernel major number is too low."
      echo "Need a kernel >= 2.3.x."
      exit 1
   fi
   # If kernel major is 2 then is minor less than 3?
   if [ "$KERNELMAJ" -eq 2 -a "$KERNELMIN" -lt 3 ] ; then
      # kernel is too old
      echo "Kernel minor number is too low."
      echo "Need a kernel >= 2.3.x."
      exit 1
   fi

   #Check for ipchains running by looking for its module
   if [ 1 = `/sbin/lsmod | grep -c ipchains` 2>/dev/null ]; then
      # iptables and ipchains can not co-exist we must exit
# Need better manner of handling this.
      echo "Opps, ipchains module appears to be loaded."
      echo "Unload ipchains module and rerun."
      exit 1
   fi

    #Check to see if there are any other than system default interfaces
    # (3 standard, + pppx)
    if [ `ls /proc/sys/net/ipv4/conf | wc -l` -gt 4 ]; then

     #Check for ip forwarding
     if [ 1 != "`cat /proc/sys/net/ipv4/ip_forward`" ]; then
        echo "Routing has not been enabled." >&2
        if [ -e /etc/sysctl.conf ] ; then
           echo "Set net.ipv4.ip_forward and" >&2
           echo "  net.ipv4.ip_always_defrag = 1 "   >&2
           echo "  in /etc/sysctl.conf" >&2
        else
           echo "Please set FORWARD_IPV4=\"yes\" " >&2
           echo "  in /etc/sysconfig/network" >&2
        fi
        echo "  or use your network configuration tool" >&2
        echo "  to enable ip forwarding." >&2
        exit 1
     fi
    else echo "Cannot find internal interface - assuming firewall only config"
    fi

   #Check for spoofing protection
    if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then
     for f in /proc/sys/net/ipv4/conf/*/rp_filter
       do
        if [ 1 != "`cat $f`" ]; then
          echo "No Spoofing Protection - Set " $f " = 1"
        fi
       done
    else
       echo "Kernel does not have spoofing protection support"
       exit 1
    fi

   # Check to see if all of the requested interfaces are found
    for EXT_INTERFACE in $EXT_INTERFACES;
     do
      if [ ! -e /proc/sys/net/ipv4/conf/$EXT_INTERFACE ]; then
        echo "Requested interface " $EXT_INTERFACE" does not exist"
        exit 1
      fi
     done

   # if we made it this far, then things are good
   # make sure that ip_tables is loaded

   # Check for iptables capability in kernel
    if [ ! -e /proc/net/ip_tables_names ]; then
     echo "No iptables Capability Loaded - Checking for module..."
      if [ -e /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/ip_tables.o ]; then
       echo "Module found - loading....."
       /sbin/modprobe ip_tables
      else
       echo "Kernel has no capability for iptables - giving up!"
       exit 1
      fi
    fi
}

logging() {
# rules to log all traffic about to be dropped
   echo -n "Enabling dropped packet logging:"
   $IPTABLES -t filter -A INPUT -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Filter-INPUT " && \
   $IPTABLES -t filter -A OUTPUT -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Filter-OUTPUT " && \
   $IPTABLES -t filter -A FORWARD -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Filter-FORWARD " && \
   $IPTABLES -t nat -A PREROUTING -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Nat-PREROUTING " && \
   $IPTABLES -t nat -A POSTROUTING -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Nat-POSTROUTING " && \
   $IPTABLES -t nat -A OUTPUT -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Nat-OUTPUT " && \
   $IPTABLES -t mangle -A PREROUTING -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Mangle-PREROUTING " && \
   $IPTABLES -t mangle -A OUTPUT -j LOG \
      --log-level info --log-prefix "$LOGGING_PREFIX Mangle-OUTPUT " && \
   success $"Enabling dropped packet logging:" || \
   failure $"Enabling dropped packet logging:"
   echo ""
}

drop_all () {
# Purpose: Drop all connections (panic button)
   echo -n $"Changing target policies to DROP: "
   $IPTABLES -P INPUT DROP && \
   $IPTABLES -P OUTPUT DROP && \
   $IPTABLES -P FORWARD DROP && \
   $IPTABLES -t mangle -P PREROUTING DROP && \
   $IPTABLES -t mangle -P OUTPUT DROP && \
   success $"Changing target policies to DROP" || \
   failure $"Changing target policies to DROP"
   echo ""
}

list_rules () {
# Purpose: list current rules
   case "$1" in
      filter)
         echo $"Table: filter"
         $IPTABLES -nv --list
         echo ""
      ;;
      nat)
         echo $"Table: nat"
         $IPTABLES -t nat -nv --list
         echo ""
      ;;
      mangle)
         echo $"Table: mangle"
         $IPTABLES -t mangle -nv --list
         echo ""
      ;;
      *)
         echo $"Table: filter"
         $IPTABLES -nv --list
         echo ""
         echo $"Table: nat"
         $IPTABLES -t nat -nv --list
         echo ""
         echo $"Table: mangle"
         $IPTABLES -t mangle -nv --list
         echo ""
   esac
}

flush_rules () {
# Purpose: Clear all current rules and chains

   # Get list of all chains
   EXISTING_CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`

   # Flush rules on all chains
   echo -n "Flushing all current rules:"
   for EXISTING_CHAIN in $EXISTING_CHAINS; do 
      $IPTABLES -t $EXISTING_CHAIN -F; done && \
      success $"Flushing all current rules:" || \
      failure $"Flushing all current rules:"
   echo ""

   # Remove all user defined chains
   echo -n "Removing user defined chains:"
   for EXISTING_CHAIN in $EXISTING_CHAINS; do 
      $IPTABLES -t $EXISTING_CHAIN -X; done && \
      success $"Removing user defined chains:" || \
      failure $"Removing user defined chains:"
   for EXISTING_CHAIN in $EXISTING_CHAINS; do 
      $IPTABLES -t $EXISTING_CHAIN -Z; done
   echo ""
}

reset_policies () {
# Purpose:
   echo -n $"Resetting built-in chains to the default ACCEPT policy:"
   $IPTABLES -P INPUT ACCEPT && \
   $IPTABLES -P OUTPUT ACCEPT && \
   $IPTABLES -P FORWARD ACCEPT && \
   $IPTABLES -t nat -P PREROUTING ACCEPT && \
   $IPTABLES -t nat -P POSTROUTING ACCEPT && \
   $IPTABLES -t nat -P OUTPUT ACCEPT && \
   $IPTABLES -t mangle -P PREROUTING ACCEPT && \
   $IPTABLES -t mangle -P OUTPUT ACCEPT && \
   success $"Resetting built-in chains to the default ACCEPT policy" || \
   failure $"Resetting built-in chains to the default ACCEPT policy"
   echo ""
}

create_rules() {
# Starting point for all new rules

   allow_internal_networks
   allow_responses
   allow_localhost
   allowed_port
   port_forwards
   port_forwards_src
   masq_networks
   allow_gateway 
   trusted_connections
   trusted_interfaces
   forward_networks
   allowed_protocols
   dmz_networks
   blocking
}

allow_internal_networks() {
#<ALLOW INTERNAL NETWORKS OUT>
   for INT_NET in $INT_NETWORKS; do
      echo -n "Allowing $INT_NET traffic out:"
      $IPTABLES -t mangle -A PREROUTING -s $INT_NET -j ACCEPT && \
      $IPTABLES -t mangle -A OUTPUT -s $INT_NET -j ACCEPT && \
      $IPTABLES -t nat -A OUTPUT -s $INT_NET -j ACCEPT && \
      $IPTABLES -t filter -A OUTPUT -s $INT_NET -j ACCEPT && \
#     $IPTABLES -t nat -A POSTROUTING -s $INT_NET -j ACCEPT && \
      success $"Allowing $INT_NET traffic out:" || \
      failure $"Allowing $INT_NET traffic out:"
      echo ""
   done
#</ALLOW INTERNAL NETWORKS OUT>
}

allow_responses() {
#<ALLOW RESPONSES>
   # Allow responses in
   echo -n "Allowing response traffic:"
   $IPTABLES -t filter -I INPUT -m state \
      --state ESTABLISHED,RELATED -j ACCEPT && \
   $IPTABLES -t mangle -I PREROUTING -m state \
      --state ESTABLISHED,RELATED -j ACCEPT && \
   $IPTABLES -t mangle -I OUTPUT -m state \
      --state ESTABLISHED,RELATED -j ACCEPT && \
   $IPTABLES -t filter -I OUTPUT -m state \
      --state ESTABLISHED,RELATED -j ACCEPT && \
   success $"Allowing response traffic:" || \
   failure $"Allowing response traffic:"
   echo ""
#</ALLOW RESPONSES>
}

allow_localhost() {
#<LOCALHOST>
   # Allow for localhost messaging
   echo -n "Allowing localhost communications:"
   $IPTABLES -t mangle -A OUTPUT -s localhost -d localhost -j ACCEPT && \
   $IPTABLES -t nat -A OUTPUT -s localhost -d localhost  -j ACCEPT && \
   $IPTABLES -t filter -A OUTPUT -s localhost -d localhost -j ACCEPT && \
   $IPTABLES -t nat -A POSTROUTING -s localhost -d localhost -j ACCEPT && \
   $IPTABLES -t mangle -A PREROUTING -s localhost -d localhost -j ACCEPT && \
   $IPTABLES -t filter -A INPUT -s localhost -d localhost -j ACCEPT && \
   success $"Allowing localhost communications:" || \
   failure $"Allowing localhost communications:"
   echo ""
#</LOCALHOST>
}

allowed_port() {
#<ALLOWED PORTS>
   for PORT in $ALLOWED_PORTS; do
      # allowing tcp
      echo -n "Allowing connections to port $PORT:"
      $IPTABLES -t nat -A PREROUTING -p tcp --dport $PORT -j ACCEPT && \
      $IPTABLES -t filter -A INPUT -p tcp --dport $PORT -j ACCEPT && \
      $IPTABLES -t mangle -A PREROUTING -p tcp --dport $PORT -j ACCEPT && \
      # allowing udp
      $IPTABLES -t nat -A PREROUTING -p udp --dport $PORT -j ACCEPT && \
      $IPTABLES -t filter -A INPUT -p udp --dport $PORT -j ACCEPT && \
      $IPTABLES -t mangle -A PREROUTING -p udp --dport $PORT -j ACCEPT && \
      success $"Allowing connections to port $PORT:" || \
      failure $"Allowing connections to port $PORT:"
      echo ""
   done

   for PORT in $ALLOWED_PORTS_UDP; do
      # allowing udp
      echo -n "Allowing connections to udp port $PORT:"
      $IPTABLES -t nat -A PREROUTING -p udp --dport $PORT -j ACCEPT && \
      $IPTABLES -t filter -A INPUT -p udp --dport $PORT -j ACCEPT && \
      $IPTABLES -t mangle -A PREROUTING -p udp --dport $PORT -j ACCEPT && \
      success $"Allowing connections to udp port $PORT:" || \
      failure $"Allowing connections to udp port $PORT:"
      echo ""
   done

   for PORT in $ALLOWED_PORTS_TCP; do
      # allowing tcp
      echo -n "Allowing connections to tcp port $PORT:"
      $IPTABLES -t nat -A PREROUTING -p tcp --dport $PORT -j ACCEPT && \
      $IPTABLES -t filter -A INPUT -p tcp --dport $PORT -j ACCEPT && \
      $IPTABLES -t mangle -A PREROUTING -p tcp --dport $PORT -j ACCEPT && \
      success $"Allowing connections to tcp port $PORT:" || \
      failure $"Allowing connections to tcp port $PORT:"
      echo ""
   done
#</ALLOWED PORTS>
}

port_forwards() {
#<PORT FORWARDS>
   for PORT_FORWARD in $PORT_FORWARDS ; do

      # seperate Local and Remote
      EXT_F=`echo $PORT_FORWARD | cut -f1 -d-`
      INT_F=`echo $PORT_FORWARD | cut -f2 -d-`

      # seperate IP and Port for both Local and Remote
      E_IP=`echo $EXT_F | sed "s/(.*)//g"`
      E_PORT=`echo $EXT_F | sed "s/.*(\|)//g"`
      I_IP=`echo $INT_F | sed "s/(.*)//g"`
      I_PORT=`echo $INT_F | sed "s/.*(\|)//g"`

      echo -n "Forwarding $EXT_F to $INT_F:"
      $IPTABLES -t filter -I FORWARD -p tcp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t filter -I FORWARD -p udp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t nat -I POSTROUTING -p tcp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t nat -I POSTROUTING -p udp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t mangle -I PREROUTING -p tcp -d $E_IP \
         --dport $E_PORT -j ACCEPT && \
      $IPTABLES -t mangle -I PREROUTING -p udp -d $E_IP \
         --dport $E_PORT -j ACCEPT && \
      $IPTABLES -t nat -I PREROUTING -p tcp -d $E_IP --dport $E_PORT \
         -j DNAT --to-destination "$I_IP:$I_PORT" && \
      $IPTABLES -t nat -I PREROUTING -p udp -d $E_IP --dport $E_PORT \
         -j DNAT --to-destination "$I_IP:$I_PORT" && \

# logic here for internal clients attempting to connnect
# to external IP and port that have been forwarded internally.
      for INT_NETWORK in $INT_NETWORKS; do
         $IPTABLES -t nat -I POSTROUTING -p tcp -d $I_IP \
            -s $INT_NETWORK --dport $I_PORT \
            -j SNAT --to $INT_IP && \
         $IPTABLES -t nat -I POSTROUTING -p udp -d $I_IP \
            -s $INT_NETWORK --dport $I_PORT \
            -j SNAT --to $INT_IP 
      done
      success $"Forwarding $EXT_F to $INT_F:" || \
      failure $"Forwarding $EXT_F to $INT_F:"
      echo ""
   done
#</PORT FORWARDS>
}

port_forwards_src() {
#<PORT FORWARDS SRC>
   for PORT_FORWARD_SRC in $PORT_FORWARDS_SRC ; do

      # seperate Source, Local and Remote
      SRC_IP=`echo $PORT_FORWARD_SRC | cut -f1 -d'|'`
      EXT_F=`echo $PORT_FORWARD_SRC | cut -f2 -d'|' | cut -f1 -d-`
      INT_F=`echo $PORT_FORWARD_SRC | cut -f2 -d'|' | cut -f2 -d-`

      # seperate IP and Port for both Local and Remote
      E_IP=`echo $EXT_F | sed "s/(.*)//g"`
      E_PORT=`echo $EXT_F | sed "s/.*(\|)//g"`
      I_IP=`echo $INT_F | sed "s/(.*)//g"`
      I_PORT=`echo $INT_F | sed "s/.*(\|)//g"`

      echo -n "Forwarding $EXT_F to $INT_F from $SRC_IP:"
      $IPTABLES -t filter -I FORWARD -p tcp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t filter -I FORWARD -p udp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t nat -I POSTROUTING -p tcp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t nat -I POSTROUTING -p udp -d $I_IP \
         --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t mangle -I PREROUTING -p tcp -d $E_IP \
         --dport $E_PORT -j ACCEPT && \
      $IPTABLES -t mangle -I PREROUTING -p udp -d $E_IP \
         --dport $E_PORT -j ACCEPT && \
      $IPTABLES -t nat -I PREROUTING -p tcp \
         -s $SRC_IP -d $E_IP --dport $E_PORT \
         -j DNAT --to-destination "$I_IP:$I_PORT" && \
      $IPTABLES -t nat -I PREROUTING -p udp \
         -s $SRC_IP -d $E_IP --dport $E_PORT \
         -j DNAT --to-destination "$I_IP:$I_PORT" && \

# logic here for internal clients attempting to connnect
# to external IP and port that have been forwarded internally.
#      for INT_NETWORK in $INT_NETWORKS; do
#         $IPTABLES -t nat -I POSTROUTING -p tcp -d $I_IP \
#            -s $INT_NETWORK --dport $I_PORT \
#            -j SNAT --to $INT_IP && \
#         $IPTABLES -t nat -I POSTROUTING -p udp -d $I_IP \
#            -s $INT_NETWORK --dport $I_PORT \
#            -j SNAT --to $INT_IP
#      done
      success $"Forwarding $EXT_F to $INT_F from $SRC_IP:" || \
      failure $"Forwarding $EXT_F to $INT_F from $SRC_IP:"
      echo ""
   done
#</PORT FORWARDS SRC>
}

masq_networks() {
#<MASQ NETWORKS>
   for INT_NET in $INT_NETWORKS; do
      if [ 1 = "$SQUID_ENABLED" ]; then
         echo -n "Enabling SQUID redirect for $INT_NET:"
         for EXT_INTERFACE in $EXT_INTERFACES; do
            $IPTABLES -t nat -A PREROUTING -i ! $EXT_INTERFACE \
               -s $INT_NET -p tcp --dport 80 \
               -j REDIRECT --to-port $SQUID_PORT
            $IPTABLES -t filter -A INPUT -s $INT_NET -p tcp \
               --dport $SQUID_PORT -j ACCEPT
         done && \
         success $"Enabling SQUID redirect for $INT_NET:" ||
         failure $"Enabling SQUID redirect for $INT_NET:"
         echo ""
      fi
      echo -n "Masq'ing $INT_NET:"
      $IPTABLES -t filter -I FORWARD -s $INT_NET -j ACCEPT && \
      $IPTABLES -t nat -A PREROUTING -s $INT_NET -j ACCEPT && \
      $IPTABLES -t nat -A POSTROUTING -s $INT_NET -j MASQUERADE && \
      success $"Masq'ing $INT_NET:" || \
      failure $"Masq'ing $INT_NET:"
      echo ""
   done
   $IPTABLES -I FORWARD -m state \
      --state ESTABLISHED,RELATED -j ACCEPT

#</MASQ NETWORKS>
}

allow_gateway() {
#<ALLOW GATEWAY>
   for EXT_INTERFACE in $EXT_INTERFACES; do
      echo -n "Allowing Gateway out $EXT_INTERFACE"
      $IPTABLES -t mangle -A OUTPUT -o $EXT_INTERFACE -j ACCEPT && \
      $IPTABLES -t nat -A OUTPUT -o $EXT_INTERFACE -j ACCEPT && \
      $IPTABLES -t filter -A OUTPUT -o $EXT_INTERFACE -j ACCEPT && \
      $IPTABLES -t nat -A POSTROUTING -o $EXT_INTERFACE -j ACCEPT && \
      success $"Allowing Gateway out $EXT_INTERFACE" || \
      failure $"Allowing Gateway out $EXT_INTERFACE"
      echo ""
   done

   # Allow packets going out 'lo' to and from external IP
   # these are packets from the firewall to the firewall
   echo -n "Allowing Gateway to connect to self"
   $IPTABLES -t mangle -A OUTPUT -o lo -s $EXT_IP \
      -d $EXT_IP -j ACCEPT && \
   $IPTABLES -t nat -A OUTPUT -o lo -s $EXT_IP \
      -d $EXT_IP -j ACCEPT && \
   $IPTABLES -t filter -A OUTPUT -o lo -s $EXT_IP \
      -d $EXT_IP -j ACCEPT && \
   $IPTABLES -t nat -A POSTROUTING -o lo -s $EXT_IP \
      -d $EXT_IP -j ACCEPT && \
   success $"Allowing Gateway to connect to self" || \
   failure $"Allowing Gateway to connect to self"
   echo ""
#</ALLOW GATEWAY>
}

trusted_connections() {
#<TRUSTED CONNECTIONS>
   for TRUSTED_CONNECTION in $TRUSTED_CONNECTIONS ; do

      # seperate Local and Remote
      EXT_F=`echo $TRUSTED_CONNECTION | cut -f1 -d-`
      INT_F=`echo $TRUSTED_CONNECTION | cut -f2 -d-`

      # seperate IP and Port for both Local and Remote
      E_IP=`echo $EXT_F | sed "s/(.*)//g"`
      E_PORT=`echo $EXT_F | sed "s/.*(\|)//g"`
      I_IP=`echo $INT_F | sed "s/(.*)//g"`
      I_PORT=`echo $INT_F | sed "s/.*(\|)//g"`

      echo -n "Allowing connections from $EXT_F to $INT_F:"
      # allowing tcp
      $IPTABLES -t nat -A PREROUTING -p tcp -s $E_IP \
         -d $I_IP --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t filter -A INPUT -p tcp -s $E_IP \
         -d $I_IP --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t mangle -A PREROUTING -p tcp -s $E_IP \
         -d $I_IP --dport $I_PORT -j ACCEPT && \
      # allowing udp
      $IPTABLES -t nat -A PREROUTING -p udp -s $E_IP \
         -d $I_IP --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t filter -A INPUT -p udp -s $E_IP \
         -d $I_IP --dport $I_PORT -j ACCEPT && \
      $IPTABLES -t mangle -A PREROUTING -p udp -s $E_IP \
         -d $I_IP --dport $I_PORT -j ACCEPT && \
      success $"Allowing connections to port $PORT:" || \
      failure $"Allowing connections to port $PORT:"
      echo ""
   done
#</TRUSTED CONNECTIONS>
}

trusted_interfaces() {
#<TRUSTED INTERFACES>
   for TRUSTED_INT in $TRUSTED_INTERFACES; do
      $IPTABLES -t mangle -A PREROUTING -i $TRUSTED_INT -j ACCEPT
      $IPTABLES -t nat -A PREROUTING -i $TRUSTED_INT -j ACCEPT
      $IPTABLES -t filter -A INPUT -i $TRUSTED_INT -j ACCEPT
   done
#</TRUSTED INTERFACES>
}

forward_networks() {
#<FORWARD NETWORKS> (needed for IPSEC?)
   for ARG_FWD_NET in $FORWARD_NETS; do
      SRC_FWD_NET=`echo $ARG_FWD_NET | cut -f1 -d-`
      DEST_FWD_NET=`echo $ARG_FWD_NET | cut -f2 -d-`

      echo -n $"Routing between $SRC_FWD_NET and $DEST_FWD_NET:"
      $IPTABLES -t mangle -I PREROUTING -s $SRC_FWD_NET \
         -d $DEST_FWD_NET -j ACCEPT && \
      $IPTABLES -t mangle -I PREROUTING -s $DEST_FWD_NET \
         -d $SRC_FWD_NET -j ACCEPT && \
      $IPTABLES -t nat -I PREROUTING -s $SRC_FWD_NET \
         -d $DEST_FWD_NET -j ACCEPT && \
      $IPTABLES -t nat -I PREROUTING -s $DEST_FWD_NET \
         -d $SRC_FWD_NET -j ACCEPT && \
      $IPTABLES -t filter -I FORWARD -s $SRC_FWD_NET \
         -d $DEST_FWD_NET -j ACCEPT && \
      $IPTABLES -t filter -I FORWARD -s $DEST_FWD_NET \
         -d $SRC_FWD_NET -j ACCEPT && \
      $IPTABLES -t nat -I POSTROUTING -s $SRC_FWD_NET \
         -d $DEST_FWD_NET -j ACCEPT && \
      $IPTABLES -t nat -I POSTROUTING -s $DEST_FWD_NET \
         -d $SRC_FWD_NET -j ACCEPT && \
      success $"Routing between $SRC_FWD_NET and $DEST_FWD_NET:" || \
      failure $"Routing between $SRC_FWD_NET and $DEST_FWD_NET:"
      echo ""
   done
#</FORWARD NETWORKS>
}

dmz_networks() {
#<DMZ_NETWORKS>
   for NETWORK in $DMZ_NETWORKS; do
      echo -n $"Creating DMZ for $NETWORK:"

      # Allow traffice from DMZ to DMZ
      $IPTABLES -t mangle -I PREROUTING -s $NETWORK -d $NETWORK \
         -j ACCEPT && \

      # block anything that is not Established, but originating from
      # a host on a DMZ network
      $IPTABLES -t mangle -I PREROUTING -s $NETWORK \
         -m state --state INVALID,NEW -j DROP && \
      $IPTABLES -t mangle -I PREROUTING -s $NETWORK \
         -m state --state INVALID,NEW -j LOG \
         --log-level info --log-prefix "$LOGGING_PREFIX DMZ-mangle "  && \
      $IPTABLES -t nat -I PREROUTING -s $NETWORK \
         -m state --state INVALID,NEW -j DROP && \
      $IPTABLES -t nat -I PREROUTING -s $NETWORK \
         -m state --state INVALID,NEW -j LOG \
         --log-level info --log-prefix "$LOGGING_PREFIX DMZ-nat " && \
      success $"Creating DMZ for $NETWORK:" || \
      failure $"Creating DMZ for $NETWORK:"
      echo ""
   done
#</DMZ_NETWORK>
}

allowed_protocols() {
#<ALLOWED_PROTOCOLS>
   for ALLOWED_PROTOCOL in $ALLOWED_PROTOCOLS; do
      # seperate IP and Port for both Local and Remote
      IP=`echo $ALLOWED_PROTOCOL | sed "s/(.*)//g"`
      PROTO=`echo $ALLOWED_PROTOCOL | sed "s/.*(\|)//g"`

      echo -n $"Allowing protocol $PROTO connections from $IP:"
      $IPTABLES -t mangle -I PREROUTING -s $IP \
         -p $PROTO -j ACCEPT && \
      $IPTABLES -t nat -I PREROUTING -s $IP \
         -p $PROTO -j ACCEPT && \
      $IPTABLES -t filter -I INPUT -s $IP \
         -p $PROTO -j ACCEPT && \
      success $"Allowing protocol $PROTO connections from $IP:" || \
      failure $"Allowing protocol $PROTO connections from $IP:"
      echo ""
   done
#</ALLOWED_PROTOCOLS>
}

blocking() {
#<BLOCKING>
   $IPTABLES -t nat -N block_nat
   $IPTABLES -t nat -I PREROUTING -j block_nat

   $IPTABLES -t mangle -N block_mangle
   $IPTABLES -t mangle -I PREROUTING -j block_mangle

   for BLOCKED_MAC in $BLOCKED_MACS; do
      echo -n $"Blocking MAC $BLOCKED_MAC:"
      $IPTABLES -t filter -I INPUT -m mac --mac-source $BLOCKED_MAC -j DROP && \
      $IPTABLES -t mangle -A block_mangle -m mac --mac-source $BLOCKED_MAC \
         -j DROP && \
      success $"Blocking MAC $BLOCKED_MAC:" || \
      failure $"Blocking MAC $BLOCKED_MAC:"
      echo ""
   done

   for BLOCKED_SRC_IP in $BLOCKED_SRC_IPS; do
      echo -n $"Blocking IP $BLOCKED_SRC_IP:"
      $IPTABLES -t filter -I INPUT -s $BLOCKED_SRC_IP -j DROP && \
      $IPTABLES -t mangle -A block_mangle -s $BLOCKED_SRC_IP -j DROP && \
      success $"Blocking IP $BLOCKED_SRC_IP:" || \
      failure $"Blocking IP $BLOCKED_SRC_IP:"
      echo ""
   done

   for BLOCKED_DST_IP in $BLOCKED_DST_IPS; do
      echo -n $"Blocking IP $BLOCKED_DST_IP:"
      $IPTABLES -t filter -I INPUT -d $BLOCKED_DST_IP -j DROP && \
      $IPTABLES -t mangle -A block_mangle -d $BLOCKED_DST_IP -j DROP && \
      success $"Blocking IP $BLOCKED_DST_IP:" || \
      failure $"Blocking IP $BLOCKED_DST_IP:"
      echo ""
   done

   # Block outgoing requests to specified ports
   for EXT_INTERFACE in $EXT_INTERFACES; do
      for PORT in $BLOCKED_OUTGOING_PORTS; do
         echo -n $"Blocking outgoing connections to port $PORT"
         $IPTABLES -t nat -I POSTROUTING -p tcp -o $EXT_INTERFACE \
	    --dport $PORT -j DROP && \
         $IPTABLES -t nat -I POSTROUTING -p udp -o $EXT_INTERFACE \
	    --dport $PORT -j DROP && \
         success $"Blocking outgoing connections to port $PORT" || \
         failure $"Blocking outgoing connections to port $PORT"
	 echo ""
      done
   done

   # Drop requested destination ports without logging 
   for EXT_INTERFACE in $EXT_INTERFACES; do
      for BLOCKED_PORT in $BLOCKED_PORTS; do
         echo -n \
            $"Blocking port(s) $BLOCKED_PORT on $EXT_INTERFACE:"
         $IPTABLES -t filter -I INPUT -p udp -i $EXT_INTERFACE \
            --dport $BLOCKED_PORT -j DROP && \
         $IPTABLES -t filter -I INPUT -p tcp -i $EXT_INTERFACE \
            --dport $BLOCKED_PORT -j DROP && \
         $IPTABLES -t mangle -I block_mangle -p udp -i $EXT_INTERFACE \
            --dport $BLOCKED_PORT -j DROP && \
         $IPTABLES -t mangle -I block_mangle -p tcp -i $EXT_INTERFACE \
            --dport $BLOCKED_PORT -j DROP && \
         success $"Blocking port(s) $BLOCKED_PORT on $EXT_INTERFACE:" || \
         failure $"Blocking port(s) $BLOCKED_PORT on $EXT_INTERFACE:"
         echo ""
      done
   done
#</BLOCKING>
}

prestart(){
   if [ -n "$PRESTART" ]; then
      echo -n "Executing $PRESTART" && \
      $PRESTART && \
      success "Executing $PRESTART" ||  \
      failure "Executing $PRESTART"
      echo ""
   fi
}

poststart(){
   if [ -n "$POSTSTART" ]; then
      echo -n "Executing $POSTSTART" && \
      $POSTSTART && \
      success "Executing $POSTSTART" ||  \
      failure "Executing $POSTSTART"
      echo ""
   fi
}

prestop(){
   if [ -n "$PRESTOP" ]; then
      echo -n "Executing $PRESTOP" && \
      $PRESTOP && \
      success "Executing $PRESTOP" ||  \
      failure "Executing $PRESTOP"
      echo ""
   fi
}

poststop(){
   if [ -n "$POSTSTOP" ]; then
      echo -n "Executing $POSTSTOP" && \
      $POSTSTOP && \
      success "Executing $POSTSTOP" ||  \
      failure "Executing $POSTSTOP"
      echo ""
   fi
}

prerestart(){
   if [ -n "$PRERESTART" ]; then
      echo -n "Executing $PRERESTART" && \
      $PRERESTART && \
      success "Executing $PRERESTART" ||  \
      failure "Executing $PRERESTART"
      echo ""
   fi
}

postrestart(){
   if [ -n "$POSTRESTART" ]; then
      echo -n "Executing $POSTRESTART" && \
      $POSTRESTART && \
      success "Executing $POSTRESTART" ||  \
      failure "Executing $POSTRESTART"
      echo ""
   fi
}


# ----------------------------------------------------------------------------

# See how script was called
case "$1" in
   start)
      prestart
      check_system
      flush_rules
      drop_all
      create_rules
      # check logging variable
      if [ 1 = $LOGGING_ENABLED ]; then
         logging
      fi
      poststart
   ;;
   stop)
      prestop
      check_system
      flush_rules
      reset_policies
      poststop
   ;;
   status)
      check_system
      list_rules $2
   ;;
   panic)
      prestop
      check_system
      flush_rules
      drop_all
      poststop
   ;;
   panic-debug)
      check_system
      flush_rules
      drop_all
      logging
   ;;
   debug)
      prestart
      check_system
      flush_rules
      logging
      drop_all
      create_rules
      poststart
   ;;
   log)
      prestart
      check_system
      flush_rules
      drop_all
      create_rules
      logging
      poststart
   ;;
   restart)
      prerestart
      check_system
      flush_rules
      drop_all
      create_rules
      # check logging variable
      if [ 1 = $LOGGING_ENABLED ]; then
         logging
      fi
      postrestart
   ;;
   *)
      echo "	Usage:"
      echo "		$0 (start|stop|restart|log|panic|debug|panic-debug)"
      echo "		$0 status (filter|nat|mangle|*)"
      exit 1
   ;;

esac
