#!/bin/ash

IPTABLES="/sbin/iptables"
IP6TABLES="/sbin/ip6tables"
log="/var/log/messages"
date=`date | sed "s/[A-Z]\{3\} [0-9]\{4\}//"`
loginfo="$date set_ssh_firewall_rules:"
sp_ssh_conf="/mnt/logs/etc/sp_ssh_conf"
brdrev=$(cat /var/run/boardrev)
razorl_rev_p2i=3

if [ -f "/var/run/RazorL" ] && [ "$brdrev" -lt "$razorl_rev_p2i" ] ; then
INET_IFACE="eth0";
else
INET_IFACE="eth0.32";
fi

initialize_ssh_pkts_chain() {

	$IPTABLES -F ssh_pkts

	#Following 2 rules create a 'recent' list of recently seen IP addresses.
	#If new SSH connection requests are made from the same IP in a short
	#interval, it is likely a DOS attack. The following rule allows 10 SSH
	#requests from the same IP within a minute and then drops new requests.

	$IPTABLES -A ssh_pkts -p TCP -i $INET_IFACE --dport 22 -m state \
	    --state NEW -m recent --set
	$IPTABLES -A ssh_pkts -p TCP -i $INET_IFACE --dport 22 -m state \
	    --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

	$IP6TABLES -F ssh_pkts
}

allow_pkts() {

	#Following rule rate-limits new incoming ssh connection requests to
	#an average of 20 per minute, with an initial burst of 20 connections
	$IPTABLES -A ssh_pkts -p TCP -i $INET_IFACE -s 0/0 --dport 22 --syn \
	    -m state --state NEW -m limit --limit 20/minute --limit-burst 20 -j ACCEPT

	$IP6TABLES -A ssh_pkts -p tcp -i $INET_IFACE -s 0/0 --dport 22 -j ACCEPT
}


# check if the file exists
if ! [ -e "$sp_ssh_conf" ]; then
	echo "$loginfo file $sp_ssh_conf not present " 1>>$log
	exit 1;
fi

# check if the values are not empty
is_access_spec_empty=$(grep -c "^ssh.access" $sp_ssh_conf)
if [ "$is_access_spec_empty" -eq 0 ]; then
	echo "$loginfo tuple value not present " 1>>$log
	exit 1;
fi

access_spec=$(awk '/^ssh.access/ {print $2}' $sp_ssh_conf)

initialize_ssh_pkts_chain

allow_all=$(grep -c "^ssh.access \*" $sp_ssh_conf)
if [ "$allow_all" -eq 1 ]; then
	allow_pkts
	exit 0;
fi

# allow all incoming SSH connections
if [ "$access_spec" = "all" -o "$access_spec" = "host=*" ]; then
	allow_pkts
	exit 0;
fi

# don't allow any incoming SSH connection
if [ "$access_spec" = "none" -o "$access_spec" = "-" -o "$access_spec" = "host=-" ]; then
	$IPTABLES -A ssh_pkts -p TCP -i $INET_IFACE -s 0/0 --dport 22 -j DROP
	$IP6TABLES -A ssh_pkts -p TCP -i $INET_IFACE -s 0/0 --dport 22 -j DROP
	exit 0;
fi

deny_access=$(echo $access_spec | grep -c "!=")
access_spec=$(echo $access_spec | awk -F '=' '/^host/ {print $2}')

IFS=','
for i in $access_spec
do
    is_ipv6_address=$(echo $i | grep -c ":")

	if [ "$is_ipv6_address" -eq 1 ]; then
		if [ "$deny_access" -eq 0 ]; then
			$IP6TABLES -A ssh_pkts -p tcp -i $INET_IFACE -s $i --dport 22 -j ACCEPT
		else
			$IP6TABLES -A ssh_pkts -p TCP -s $i --dport 22 -j DROP
		fi
	else
		if [ "$deny_access" -eq 0 ]; then
			$IPTABLES -A ssh_pkts -p TCP -i $INET_IFACE -s $i --dport 22 --syn -m state --state NEW \
			    -m limit --limit 20/minute --limit-burst 20 -j ACCEPT
		else
			$IPTABLES -A ssh_pkts -p TCP -i $INET_IFACE -s $i --dport 22 -j DROP
		fi
	fi
done

if [ "$deny_access" -eq 1 ]; then
	allow_pkts
fi

exit 0
