#!/bin/sh
# gateway
# This is a simple firewall rules to setup a masquerading gateway
# Sufficient for home, serving some casual clients.
# Not for a serious office !!!
#
# It is asume that the system uses VL standard configuration
# If eth1 is UP then eth0 = external, eth1 = internel OR
# else ppp0 = external, eth0 = internal
#
# GNU GPL (c) Eko M. Budi, 2004
#         (c) Vector Linux, 2004
#

# Masquerade must be yes if your internal network uses
# private IP address 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16
MASQUERADE="yes"

# The services we wish to allow to pass 
# from GREEN network (intranet) to RED network (internet).
# see /etc/services for ports definition
# empty means all ports, comma separated
TCPOUT="smtp,www,ssh,telnet,ftp,ftp-data,irc,http"
UDPOUT="domain"
ICMPOUT="8,3,11"

# The services we wish to allow to enter this host itself
# empty means all ports, comma separated
TCPIN="ssh,ftp,ftp-data"
UDPIN="domain"
ICMPIN="0,3,11"

# The Interfaces. Empty mean autodetect
GREEN_IF=""
RED_IF=""

########################################################################
# Do the business ...
. /etc/rc.d/functions

## Autodetect interface if necessary
if [ -z "$GREEN_IF" ] || [ -z "$RED_IF" ]; then
   ifconfig | grep -e "^eth0" > /dev/null 
   if [ ! $? = 0 ]; then
      echo No Interface, skipping .... # no ethernet, quit
      exit
   fi

   ifconfig | grep -e "^eth1" > /dev/null
   if [ $? = 0 ]; then
     GREEN_IF=eth1
     RED_IF=eth0
   else
     GREEN_IF=eth0
     RED_IF=ppp0
   fi
fi

IPT="/usr/sbin/iptables"
MODPROBE="/sbin/modprobe"

## load modules
$MODPROBE ip_tables
$MODPROBE iptable_filter
$MODPROBE iptable_nat
$MODPROBE ip_nat_ftp  
$MODPROBE ip_nat_irc 
$MODPROBE ip_conntrack  
$MODPROBE ip_conntrack_ftp  
$MODPROBE ip_conntrack_irc  

firewall_disable_forwarding()
{
  echo "0" > /proc/sys/net/ipv4/ip_forward 
}

firewall_enable_forwarding()
{
  echo "1" > /proc/sys/net/ipv4/ip_forward
  # Enable IP spoofing protection, turn on Source Address Verification
  for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
     echo 1 > $f
  done
  # Disable ICMP Redirect Acceptance
  for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do
     echo 0 > $f
  done
}

firewall_clear()
{
  ## Clear all rules
  $IPT -F 
  $IPT -F -t nat 
  $IPT -F -t mangle 
  $IPT -X 
}

firewall_default()
{
  $IPT -P INPUT DROP
  $IPT -P FORWARD DROP
  $IPT -P OUTPUT ACCEPT
}

# Create a new chain of protection
firewall_protection()
{
  $IPT -N PROTECTION

  # Enabling Syn flood protection
  $IPT -A PROTECTION -p tcp --syn -m limit --limit 1/s -j ACCEPT
 
  # Enabling Furtive port scanner protection
  $IPT -A PROTECTION -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
  
  # Enabling ping of death protection
  $IPT -A PROTECTION -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
}


# Rules for allowing traffic from the GREEN network to the RED network
# But drop the opposite
firewall_forward()
{
  if [ "$MASQUERADE" = "yes" ]; then
     $IPT -t nat -A POSTROUTING -o $RED_IF -j MASQUERADE
  else
  
  $IPT -A FORWARD -i $RED_IF -o $GREEN_IF -m state --state ESTABLISHED,RELATED -j ACCEPT
  $IPT -A FORWARD -f -j ACCEPT
  
  if [ "$TCPOUT" ]; then
     $IPT -A FORWARD -i $GREEN_IF -p tcp -m multiport --dports $TCPOUT -j ACCEPT
  else
     $IPT -A FORWARD -i $GREEN_IF -p tcp -j ACCEPT
  fi
  if [ "$UDPOUT" ]; then
     $IPT -A FORWARD -i $GREEN_IF -p udp -m multiport --dports $UDPOUT -j ACCEPT
  else
     $IPT -A FORWARD -i $GREEN_IF -p udp -j ACCEPT 
  fi
  if [ "$ICMPOUT" ]; then
     $IPT -A FORWARD -p icmp --icmp-types $ICMPOUT -j ACCEPT
  else
     $IPT -A FORWARD -p icmp -j ACCEPT
  fi
}

# Rules for accepting input to this gateway
firewall_input()
{
  $IPT -A INPUT -i lo -j ACCEPT 
  $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

  if [ "$TCPIN" ]; then
     $IPT -A INPUT -p tcp -m multiport --dports $TCPIN -j PROTECTION
  else
     $IPT -A INPUT -p tcp -j PROTECTION
  fi
  if [ "$UDPIN" ]; then
     $IPT -A INPUT -p udp -m multiport --dports $UDPIN -j PROTECTION
  else
     $IPT -A INPUT -p udp -j PROTECTION
  fi
  if [ "$ICMPIN" ]; then
     $IPT -A INPUT -p icmp --icmp-types $ICMPIN -j PROTECTION
  else
     $IPT -A INPUT -p icmp -j PROTECTION
  fi
}


firewall_start() {
  firewall_disable_forwarding
  firewall_clear
  firewall_default

  firewall_protection
  firewall_forward
  firewall_input
  
  firewall_enable_forwarding  
  return 0
}

firewall_stop()
{
  firewall_clear
  return 0
}

case "$1" in
  start)
    echo -n "Starting firewall of $RED_IF ..."
    firewall_start
    evaluate_retval
    ;;
  stop)
    echo -n "Stopping firewall of $RED_IF ..."
    firewall_stop
    evaluate_retval
    ;;
  reload)
    echo -n "Reloading firewall of $RED_IF ..."
    firewall_start
    evaluate_retval
    ;;  
  restart)
    $0 stop
    sleep 2
    $0 start
    ;;
  status)
    $IPT -L
    echo
    $IPT -t nat -L
    ;;
  *)  
    echo "Usage $0 {start|stop|restart|reload|status}"
esac

