#!/bin/bash
#Copyright 2003 William Stearns <wstearns@pobox.com>
#Released under the GPL.

Me='punishmapper'
MyVersion='0.3.3'
DefaultActions='LOG DROP'

[ -r /etc/firebricks/firebricks.conf ] &&			. /etc/firebricks/firebricks.conf
[ -r /etc/firebricks/$Me.conf ] &&				. /etc/firebricks/$Me.conf
[ -r ${FBLibDir:-'/usr/lib/firebricks/'}/firebrickslib ] &&	. ${FBLibDir:-'/usr/lib/firebricks/'}/firebrickslib
if [ -z "$FBLibVer" ]; then
	echo 'It looks like firebrickslib was not loaded, why?  Exiting' >&2
	exit 1
fi

for OneTask in $Tasks ; do
	case "$OneTask" in
	link)
		$IptablesBin -N $Me >/dev/null 2>&1
		$IptablesBin $AppIn INPUT -i \! lo						-j $Me
		$IptablesBin $AppIn FORWARD							-j $Me
		$IptablesBin $AppIn OUTPUT -o \! lo						-j $Me
		;;
	unlink)
		$IptablesBin -D INPUT -i \! lo							-j $Me
		$IptablesBin -D FORWARD								-j $Me
		$IptablesBin -D OUTPUT -o \! lo							-j $Me
		$IptablesBin -X $Me >/dev/null 2>&1
		;;
	create)
		echo "Starting $Me" >&2
		FlushOrNewChain $Me
		#If the source IP was seen sending nasty traffic in the last 60 seconds, drop this packet
		#even if this particular packet doesn't look malicious.
		#I'd like to check that the ttl of this packet matches the ttl of the malicious packet, but
		#we're registering destination addresses of sme unrechables; there's no way to extract the 
		#attacker's TTL from these.  Well, OK, there is if we look in the payload, but recent
		#doesn't do this.  --rttl removed for now.
		LogAs='punishmapper'	$Ipt -A $Me -m recent --name mapper --rcheck --seconds 60	$Tail
		;;
	destroy)
		echo "Stopping $Me" >&2
		DestroyChain $Me
		;;
	renamechain)
		TempChain="$Me-$RANDOM"
		echo "Replacing existing rules in $Me with new rules" >&2
		$IptablesBin -E $Me $TempChain
		;;
	replacelinks)
		if [ -z "$TempChain" ]; then
			echo "No temporary chain to relink in $Me replacelinks, replace operation incomplete." >&2
		elif ! $IptablesBin -L $Me -n >/dev/null 2>&1 ; then
			echo "No $Me chain in $Me, replace operation incomplete." >&2
		elif ! $IptablesBin -L $TempChain -n >/dev/null 2>&1 ; then
			echo "No $TempChain chain in $Me, replace operation incomplete." >&2
		elif [ "`$IptablesBin -L INPUT -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
			echo "Too few/many references to $TempChain in INPUT in $Me replacelinks, replace operation incomplete." >&2
		elif [ "`$IptablesBin -L FORWARD -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
			echo "Too few/many references to $TempChain in FORWARD in $Me replacelinks, replace operation incomplete." >&2
		elif [ "`$IptablesBin -L OUTPUT -n --line-numbers | grep $TempChain | wc -l`" -ne 1 ]; then
			echo "Too few/many references to $TempChain in OUTPUT in $Me replacelinks, replace operation incomplete." >&2
		else
			$IptablesBin -R INPUT `$IptablesBin -L INPUT -n --line-numbers | grep $TempChain | awk '{print $1}'` -i \! lo		-j $Me
			$IptablesBin -R FORWARD `$IptablesBin -L FORWARD -n --line-numbers | grep $TempChain | awk '{print $1}'`		-j $Me
			$IptablesBin -R OUTPUT `$IptablesBin -L OUTPUT -n --line-numbers | grep $TempChain | awk '{print $1}'` -o \! lo		-j $Me
			DestroyChain $TempChain
			unset TempChain
		fi
		;;
	status)
		if $IptablesBin -L $Me -n >/dev/null 2>&1 ; then
			echo "$Me created" >&2
		else
			echo "$Me destroyed" >&2
		fi
		;;
	version)
		echo "$Me $MyVersion, firebrickslib $FBLibVer" >&2
		;;
	help)
		DefaultHelp
		cat <<EOTEXT >&2
	The $Me module punishes people that have already violated one of
our security policies (they\'ve _already_ sent in syn/fin packets,
portscans, probes, etc.).  Their addresses are already in a kernel table
of offending source addresses, courtesy of the ipt_recent match module.
	This table is called after we\'ve checked for nasty traffic, but
before the normal allow rules.  We now treat any other packets from that
host as hostile and log and drop them.
	This is by no means a sure thing; we\'re implementing an
Intrusion Prevention system, with all its caveats and issues.  You may
wish to tread carefully with this one.
EOTEXT
		;;
	*)
		echo "Unknown action $Action in $Me, no action taken." >&2
		;;
	esac
done
