#!/bin/bash
#
# GNU GENERAL PUBLIC LICENSE
# Version 2, June 1991
#
# See Also
# http://www.gnu.org/licenses/gpl-2.0.html
#
# Author: labunix@linux.jp
# Last Update 2012/04/08
# 
# support only debian lenny or squeeze
# [--make] option is filter only.
# 
set -e
echo $PATH | sed s/":"/"\n"/g | grep "^/usr/sbin\$" > /dev/null 2>&1 || \
  export PATH=/usr/sbin:${PATH}
echo $PATH | sed s/":"/"\n"/g | grep "^/sbin\$" > /dev/null 2>&1 || \
  export PATH=/sbin:${PATH}

export VERSION="0.1a"
export SFWSAVE=/etc/iptables-save
export SFWREVERSE=/etc/smallfirewall
# default iptables log,debug facility
export IPTABLESLOG=/var/log/iptables.log
# report log
export SFWTEMP=/var/log/sfwreport.tmp
export SFWLOG=/var/log/sfwreport.log

if [ `id -u` -ne 0 ];then
  echo "Sorry,Not Permit User!"
  exit 2
fi

function sfwerr() {
  echo $@
  exit 1
}

# command check
iptables --version > /dev/null 2>&1 || sfwerr "Not found iptables"
iptables-apply -h > /dev/null 2>&1 || sfwerr "Not found iptables-apply"
find /sbin /usr/sbin -name iptables-save -print | \
  grep iptables-save > /dev/null 2>&1 || \
  sfwerr "Not found iptables-save"
find /sbin /usr/sbin -name iptables-restore -print | \
  grep iptables-restore > /dev/null 2>&1 || \
  sfwerr "Not found iptables-save"

# if Not found, create /etc/smallfirewall
if [ ! -f ${SFWREVERSE} ];then
  touch ${SFWREVERSE}
  chmod 700 ${SFWREVERSE}
  test -f ${SFWREVERSE} || sfwerr "Can't Create ${SFWREVERSE}"
fi

# if Not found /var/log/iptables.log, use system default
if [ ! -f ${SFWLOG} ];then
  test -f /etc/redhat-release && export IPTABLESLOG=/var/log/messages
  # Other default
  export IPTABLESLOG=/var/log/syslog
fi

function sfwreset() {
  iptablescmd="$1"
  echo "${iptablescmd}" | grep iptables || \
    sfwerr "Not found iptables command,or use double quotation"
  $(${iptablescmd})
  iptables-apply -t 10 ${SFWSAVE} || \
    iptables-restore -c ${SFWSAVE}
}

function sfwreverse() {
  # use sfwreset function
  # for comment out,COMMIT,NULL line
  cat ${SFWSAVE} | grep -v "^\#\|^COMMIT\|^\$" | \
    # for only filter
    grep -v "^\*filter" | \
    # for Policy
    sed s/"^:"/"-P "/g | \
    # for all
    sed s/"^"/"iptables "/g | \
    # for counter
    sed s/" \[.*\]"//g > ${SFWREVERSE}
}

function smallfirewall() {
  iptables-save -c > ${SFWSAVE}
  sfwreverse > ${SFWREVERSE}
  echo "See ${SFWREVERSE}"
}

function sfwreport() {
  grep "IN=" ${IPTABLESLOG} | \
    sed s/".*IN="/"IN="/g | \
    sed s/"LEN=[0-9]* \|TOS=0x[0-9A-Fa-f]* \|PREC=0x[0-9A-Fa-f]* "//g | \
    sed s/"TTL=[0-9]* \|DF \|WINDOW=[0-9]* \|ACK \|PSH \|URGP=[0-9]* "//g | \
    sed s/"RES=0x[0-9]* \|SYN \|ID=[0-9]* \|MAC= "//g | \
    sed s/"CODE=[0-9]* \|SEQ=[0-9]* "//g | \
    sed s/" MAC=..:..:..:..:..:..:..:..:..:..:..:..:..:.. "//g > ${SFWTEMP}

  cat ${SFWTEMP} | sed s/"OUT=SRC="/"OUT= SRC="/g | \
    sed s/"IN= \|OUT= "//g | \
    sed s/"IN="/'INPUT -i '/g | \
    sed s/"OUT="/'OUTPUT -o '/g | \
    sed s/"SRC="/'-s '/g | \
    sed s/"DST="/'-d '/g | \
    sed s/"PROTO="/'-p '/g | \
    sed s/"SPT="/'--sport '/g | \
    sed s/"DPT="/'--dport '/g | \
    sed s/"TYPE="/'-m icmp --icmp-type '/g | \
    sed s/^/'iptables -A '/g | \
    sed s/"\$"/'-j ACCEPT'"&"/g > ${SFWLOG}
}

function sfwwatch() {
  count=$(echo "$1"  | awk '{print $1+10}')
  (sleep ${count};pkill watch) &
  watch -d -n 1 'iptables -L -v -n | grep "DROP\|LOG\|Chain" | grep -v "^    0"'
}

# /etc/init.d/iptables install
function sfwinstall() {
  # sfwuninstall.info
  SFWINSTALLLOG=/var/log/sfwuninstall.info
  touch ${SFWINSTALLLOG} || exit 2

  # /etc/init.d/iptables
  test -f /etc/init.d/iptables && \
    mv /etc/init.d/iptables /etc/init.d/iptables.`date '+%Y%m%d_%H%M%S'`
  echo '#!/bin/bash
# Start/stop the iptables script.
#
### BEGIN INIT INFO
# Provides:          iptables
# Required-Start:    $remote_fs $syslog $time
# Required-Stop:     $remote_fs $syslog $time
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Custom background script
# Description:       iptables v1.4.2 for Squeeze
#                    Last Update:2012/02/23
#                    Author     :labunix@linux.jp
#                    filter [input|forward|output] table only
### END INIT INFO
#
# environment
#export PATH=/sbin:/usr/sbin:/bin:/usr/bin
set -e

if [ `id -u` -ne "0" ];then
  echo "Sorry,Not Permit User!"
  exit 1
fi

iptables -V > /dev/null || exit 1

function sfwerr() {
  echo $@
  iptables -F
  iptables -F -t nat
  iptables -X
  iptables -P INPUT ACCEPT
  iptables -P FORWARD ACCEPT
  iptables -P OUTPUT ACCEPT
  exit 1
}

# for save and restore
test -f /etc/iptables-save || touch /etc/iptables-save
test -f /etc/iptables-save || sfwerr "ERROR:Please Check /etc/iptables-save"

case $1 in
start)
  iptables-restore -c /etc/iptables-save || sfwerr "ERROR:Resotre error"
  ;;
stop)
  iptables -F
  iptables -F -t nat
  iptables -X
  iptables -P INPUT ACCEPT
  iptables -P FORWARD ACCEPT
  iptables -P OUTPUT ACCEPT
  ;;
reload|restart)
  iptables-save -c > /etc/iptables-save ||  sfwerr "ERROR:Save error"
  iptables -F
  iptables -F t nat
  iptables -X
  iptables -P INPUT ACCEPT
  iptables -P FORWARD ACCEPT
  iptables -P OUTPUT ACCEPT
  iptables-restore -c /etc/iptables-save || sfwerr "ERROR:Resotre error"
  ;;
status)
  iptables -L -v -n | grep "^Chain"
  ;;
*)
  echo "Usage: $0 {start|stop|reload|restart|status}"
  exit 2
  ;;
esac
exit 0

' > /etc/init.d/iptables
  chown root:root /etc/init.d/iptables
  chmod 755 /etc/init.d/iptables
  if [ -f /etc/debian_version ];then
    dpkg -l chkconfig | grep ^ii || echo "chkconfig" >> ${SFWINSTALLLOG}
    dpkg -l insserv | grep ^ii || echo "insserv" >> ${SFWINSTALLLOG}
    for list in `cat ${SFWINSTALLLOG}`;do
      apt-get install -y "$list"
    done
    insserv -v iptables
    chkconfig --list iptables | grep "2\:on" || \
      sfwerr "ERROR:chkconfig --list iptables"
  elif [ -f /etc/redhat-release ];then
    rpm -qa | grep chkconfig || echo "chkconfig" >> ${SFWINSTALLLOG}
    for list in `cat ${SFWINSTALLLOG}`;do
      yum install -y "$list"
    done
    chkconfig --list iptables | grep "2\:on" || \
      chkconfig --add iptables
    chkconfig --list iptables | grep "2\:on" || \
      sfwerr "ERROR:chkconfig --list iptables"
  fi
  test -x /etc/init.d/iptables && \
  /etc/init.d/iptables start || sfwerr "ERROR:/etc/init.d/iptables start"
  /etc/init.d/iptables status
}

function sfwuninstall() {
  /etc/init.d/iptables stop
  if [ -f /etc/debian_version ];then
    insserv -r iptables
    chkconfig --list | grep iptables && sfwerr "Can't daemon delete"
    for list in `cat ${SFWINSTALLLOG}`;do
      apt-get remove "$list"
    done && rm -f ${SFWINSTALLLOG}
  elif [ -f /etc/redhat-release ];then
    if [ -f /etc/init.d/iptables.[0-9]*_[0-9]* ];then
      mv /etc/init.d/iptables.[0-9]*_[0-9]* /etc/init.d/iptables
    else
      chkconfig --del iptables
      chkconfig --list | grep iptables && sfwerr "Can't daemon delete"
      for list in `cat ${SFWINSTALLLOG}`;do
        yum remove "$list"
      done && rm -f ${SFWINSTALLLOG}
    fi
  fi
  if [ -z ${SFWINSTALLLOG} ];then
    rm -f ${SFWINSTALLLOG}
  else
    echo "please check,and delete ${SFWINSTALLLOG}"
  fi
}

if [ "$#" -le 0 ];then
  NULLOPT='-h'
fi
for sfwopt in $@ ${NULLOPT} ;do
  case ${sfwopt} in
    -c|--check)
      echo "if You want to Change,grep export $0"
      echo ""
      echo "PATH=${PATH}"
      echo "VERSION=${VERSION}"
      echo "SFWSAVE=${SFWSAVE}"
      echo "SFWREVERSE=${SFWREVERSE}"
      echo "SFWLOG=${SFWLOG}"
      echo "SFWTEMP=${SFWTEMP}"
      echo "IPTABLESLOG=${IPTABLESLOG}"
      ;;
    -i|--install)
      sfwinstall
      ;;
    --report)
      sfwreport
      echo "See /var/log/sfwreport.log"
      echo "and delete /var/log/sfwreport.tmp"
      ;;
    --make)
      smallfirewall
      ;;
    --test)
      shift
      SFWARG="$1"
      sfwreset "$SFWARG"
      break
      ;;
    -u|--uninstall)
      sfwuninstall
      ;;
    -w|--watch)
      shift
      SFWARG=$1
      sfwwatch ${SFWARG}
      echo ""
      echo "# Other command"
      echo "watch -d -n 1 'iptables -L -v -n '"
      echo "# or"
      echo "watch -d -n 1 'iptables -L -v -n | grep [port]'"
      break
      ;;
    -v|--version)
      echo ${VERSION}
    ;;
    -h|--help|*)
      echo "Usage $0 [-v|-c|-i|-u|--report|--smallfirewall|--test|-w|-h]"
      echo "      or [-v|--version] or [-c|--cechk]"
      echo "      or [-i|--install] or [-u|--uninstall]"
      echo "      or [--report] or [-h|--help]  or [--smallfirewall]"
      echo "         # arg option"
      echo "         [--test \"iptables-command\"]"
      echo "         [-w|--watch second]"
      echo ""
      echo "    example debuf facility log : /var/log/iptables.log"
      echo ""
      echo "$ vim /etc/rsyslog.conf"
      echo "###############"
      echo "#### RULES ####"
      echo "###############"
      echo "kern.debug  /var/log/iptables.log"
      echo ":syslogtag, contains, \"iptables\" ~"
      echo ""
      echo "$ sudo /etc/init.d/rsyslog restart"  
      echo "  -v|--version"
      echo "    version info"
      echo "  -c|--check"
      echo "    check file or directory path"
      echo "  -i|--install"
      echo "    install /etc/init.d/itables"
      echo "    rpm beta version"
      echo "  -u|--uninstall"
      echo "    uninstall /etc/init.d/iptables"
      echo "    if not use $0,check before uninstall env file,and delete it."
      echo "    rpm beta version"
      echo "    $0 --check"
      echo "  --report"
      echo "    report iptables command format"
      echo "    example : sort ${SFWLOG} | uniq -c | sort -k 1"
      echo "  --smallfirewall"
      echo "    /etc/iptables-save to /etc/smallfirewall script"
      echo "    support filter only"
      echo "  --test \"iptables command\""
      echo "    test mode itables command"
      echo "    example : "
      echo "  $0 --test \"iptables -A INPUT -i eth0 -p tcp --sport 22 -j ACCEPT\""
      echo "  -w|--watch [sec]"
      echo "    use watch command,default 10 second"
      echo "  -h|--help|*"
      echo "    this help messages"
      ;;
  esac
done
unset NULLOPT SFWARG
unset PATH VERSION SFWSAVE SFWREVERSE SFWLOG SFWTEMP IPTABLESLOG
exit 0

