#!/bin/bash
IPTABLES="/sbin/iptables"
CONFIG_DIR="/root/knock/"
CHAIN_NAME=$1
CONFIG_FILE="${CONFIG_DIR}$1"

#overrideable in config file
IFACE='eth0'
CURRENT_PORT=1
ENDING_PORT=65534
TARGET_PORT=22
TIME=60

ABUSE_PERIOD=180
ABUSE_HITCOUNT=20

# file exists
if [[ ! -f ${CONFIG_FILE} ]]; then
	echo " $CONFIG_FILE does not exist"
	exit 1 
fi

# syntax
if ! source ${CONFIG_FILE} ; then
	echo "$CONFIG_FILE failed a sanity check"
	exit 1
fi

# Helper function very usefull for debug
ipt(){ 
	if !($IPTABLES "$@"); then
		echo "$IPTABLES $@" ;
		echo "abnormal termination"
		exit 1
	fi;
# debug	
	if [[ $DEBUG == "ON" ]]; then	
		echo $@
	fi;
}

# found in emerge.sh not tested
sort() {
	LC_ALL=C /bin/sort "$@"
}  

#first, delete (possibly) existing rules 
$IPTABLES -i $IFACE -D INPUT -p tcp --syn -j $CHAIN_NAME 2>/dev/null
$IPTABLES -F $CHAIN_NAME 2>/dev/null
$IPTABLES -X $CHAIN_NAME 2>/dev/null

#check if not just delete
if [[ $2 == "del" ]]; then 
  echo "$CHAIN_NAME deleted"
  exit 0
fi

#create new chain
ipt -N $CHAIN_NAME

#first, send all incoming traffic to this chain
ipt -i $IFACE -I INPUT 1 -p tcp --syn -j $CHAIN_NAME

#########################################################
# fill chain 					 	#
#########################################################
#NAMES=""
for a in $PORTS; do
	NAME="$CHAIN_NAME$a"
	PORT=$((a - 1))
	ipt -A $CHAIN_NAME -p tcp --syn --dport $CURRENT_PORT:$PORT -m recent --set --name ABUSE
#	ipt -A $CHAIN_NAME -p tcp --syn --dport $a -m recent --remove --name $a
	ipt -A $CHAIN_NAME -p tcp --syn --dport $a -m recent --set --name $NAME
#	NAMES="$NAMES --name $a"
	CURRENT_PORT=$((a + 1))
done;
#check last range 

ipt -A $CHAIN_NAME -p tcp --dport $CURRENT_PORT:$ENDING_PORT -m recent --set --name ABUSE

# check for abusers
ipt -A $CHAIN_NAME -p tcp --dport $TARGET_PORT -m recent --rcheck --seconds $ABUSE_PERIOD --hitcount $ABUSE_HITCOUNT --name ABUSE -j RETURN

# check all names presents
for a in $PORTS; do
	NAME="$CHAIN_NAME$a"
	ipt -A $CHAIN_NAME -p tcp --dport $TARGET_PORT -m recent ! --rcheck --seconds $TIME --name $NAME -j RETURN 
done;
# finaly allow target port
ipt -A $CHAIN_NAME -p tcp --dport $TARGET_PORT -j ACCEPT


