#! /bin/bash
### BEGIN INIT INFO
# Provides:          uif
# Required-Start:    $network $syslog $remote_fs
# Required-Stop:     $network $syslog $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Universal Internet Firewall
# Description:       Start the firewall defined in /etc/uif/uif.conf.
### END INIT INFO
#
# Version:      @(#)/etc/init.d/uif  1.1.9  August-2018 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#

# RedHat specific settings - ignore for real systems ---------------------------
# chkconfig: - 60 95
# description: provides iptables packet filtering

. /lib/lsb/init-functions

PATH=/usr/sbin:/sbin:$PATH
UIF=/usr/sbin/uif

IPV6MODE=0

# Include firewall defaults if available
if [ -f /etc/default/uif ] ; then
	. /etc/default/uif
fi

# Include firefwall defaults from uif.d/ if available in /etc/defaults/
# Defaults included from /etc/default/uif.d/ will override settings from
# /etc/default/uif
if [ -d /etc/default/uif.d/ ] ; then
	for uif_default_override in `run-parts --list /etc/default/uif.d/`; do
		. $uif_default_override
	done
fi

#THIS IS DEFAULT ANYWAY#[ -z "$OPTIONS" ] && OPTIONS="-c /etc/uif/uif.conf"

# Binaries installed?
if [ ! -f /sbin/iptables ] && [ ! -f /usr/sbin/iptables ]; then
	log_failure_msg "uif: iptables not found - aborting"
	exit 1
fi

if [ $IPV6MODE = 1 ] && ( [ ! -f /sbin/ip6tables ] && [ ! -f /usr/sbin/iptables ] ); then
	log_failure_msg "uif: ip6tables not found - aborting"
	exit 1
fi

# uif installed? Without this script makes no sense...
[ -f $UIF ] || exit 1


# As the name says. If the kernel supports modules, it'll try to load
# the ones listed in "MODULES".
load_modules() {
	[ -f /proc/modules ] || return
	LIST=`/sbin/lsmod|awk '!/Module/ {print $1}'`

	for mod in $MODULES; do
		echo $LIST | grep -q $mod || modprobe $mod || /bin/true
	done
}


case "$1" in

start)
	log_daemon_msg "Starting uif"
	logger "Starting uif"
	[ -f /proc/modules ] && { log_progress_msg "modules"; load_modules; }

	log_progress_msg "IPv4-rules"
	EMSG=`$UIF $OPTIONS 2>&1`
	RET4=$?
	if [ $RET4 -ne 0 ]; then

		logger "Starting uif failed: $EMSG"

		[ -n "$MAILTO" ] && \
		echo -e "Hi. This is your firewall script - which has failed" \
		"to execute in a proper way.\nHere is the error message:\n" \
		"\n$EMSG\n\nPlease fix to be sure..." | mail -s "Firewall script failure" $MAILTO

		log_end_msg $RET4
		echo
		echo -e "Error message: $EMSG\n"
		exit 1
	fi
	if [ $IPV6MODE = 1 ] ; then
		log_progress_msg "IPv6-rules"
		EMSG=`$UIF -6 $OPTIONS 2>&1`
		RET6=$?
		if [ $RET6 -ne 0 ]; then

			logger "Starting uif failed: $EMSG"

			[ -n "$MAILTO" ] && \
			echo -e "Hi. This is your IPv6 firewall script - which has failed" \
			"to execute in a proper way.\nHere is the error message:\n" \
			"\n$EMSG\n\nPlease fix to be sure..." | mail -s "Firewall script failure" $MAILTO

			log_end_msg $RET6
			echo
			echo -e "Error message: $EMSG\n"
			exit 1
		fi
	else
		RET6=0;
	fi

	log_end_msg $(($RET4+$RET6))
	;;

stop)
	log_daemon_msg "Stopping uif"
	logger "Stopping uif"
	if [ $IPV6MODE = 1 ] ; then
		log_progress_msg "IPv4"
	fi
	$UIF -d
	if [ $IPV6MODE = 1 ] ; then
		log_progress_msg "IPv6"
		$UIF -6 -d
	fi
	log_end_msg 0
	;;

print)
	echo "Printing rules based on your current configuration"
	$UIF $OPTIONS -pt
	if [ $IPV6MODE = 1 ] ; then
		$UIF -6 $OPTIONS -pt
	fi

	;;

test|test4)
	if [ $IPV6MODE = 1 ] ; then
		echo -n "IPv4 Test: "
	fi
	echo -n "Activating IPv4 ruleset for $TIMEOUT seconds: modules, "
	trap 'echo "aborted, IPv4 rules restored"; exit 0' SIGINT
	load_modules

	echo -n "IPv4 rules - active, waiting - "
	EMSG=`$UIF -T $TIMEOUT $OPTIONS`
	if [ $? -eq 0 ]; then
		echo ok
		exit 0
	fi
	echo failed
	echo -e "Error message: $EMSG\n"
	;;
test6)
	if [ $IPV6MODE = 1 ] ; then
		echo -n "IPv6 Test: "
		echo -n "Activating IPv6 ruleset for $TIMEOUT seconds: modules, "
		trap 'echo "aborted, IPv6 rules restored"; exit 0' SIGINT
		load_modules

		echo -n "IPv6 rules - active, waiting - "
		EMSG=`$UIF -6 -T $TIMEOUT $OPTIONS`
		if [ $? -eq 0 ]; then
			echo ok
			exit 0
		fi
		echo failed
	echo -e "Error message: $EMSG\n"
	fi
	;;

status)
	if [ "`id -u`" != "0" ]; then
		echo "Can't retrieve status information. You need to be root."
		exit 1
	fi
	if [ $IPV6MODE = 1 ] ; then
		echo "IPv4 STATUS:"
	fi
	# Simple rule listing
	echo -e "\nRule listing:\n"
	iptables-save | sed "/^#/d"

	# Show accounting data
	if [ -n "$ACCOUNTPREFIX" ]; then
		echo -e "\n\nCurrent accounting information:\n"
		iptables -vnx -L 2>&1 | sed "/pkts/d" | sed -ne "/^Chain $ACCOUNTPREFIX/N" -e "s/\n/ /p" | \
			sed "s/[ ][ ]*/ /g" | awk '{ print $2"\t"$6" Bytes"; }'
	fi
	if [ $IPV6MODE = 1 ] ; then
		echo "IPv6 STATUS:"
		# Simple rule listing
		echo -e "\nRule listing:\n"
		ip6tables-save | sed "/^#/d"

		# Show accounting data
		if [ -n "$ACCOUNTPREFIX" ]; then
			echo -e "\n\nCurrent accounting information:\n"
			ip6tables -vnx -L 2>&1 | sed "/pkts/d" | sed -ne "/^Chain $ACCOUNTPREFIX/N" -e "s/\n/ /p" | \
			    sed "s/[ ][ ]*/ /g" | awk '{ print $2"\t"$6" Bytes"; }'
		fi
	fi
	# Show last 10 policy violations
	if [ -n "$LOGPREFIX" ]; then
		if [ $IPV6MODE = 1 ] ; then
			echo -e "\n\nLast 10 policy violations (IPv4 & IPv6 combined):"
		else
			echo -e "\n\nLast 10 policy violations (IPv4 only):"
		fi
		dmesg | grep "`hostname`.* $LOGPREFIX .*:" 2> /dev/null | tail -n 10
	fi

	echo -e "\n\n"
	;;


restart|reload|force-reload)
	$0 start
	;;

flush)
	echo -n "Flushing IPv4 packet counters: "
	iptables -Z &> /dev/null
	if [ $? -eq 0 ]; then
		echo ok
	else
		echo failed
	fi
	if [ $IPV6MODE = 1 ] ; then
		echo -n "Flushing IPv6 packet counters: "
		ip6tables -Z &> /dev/null
		if [ $? -eq 0 ]; then
			echo ok
		else
			echo failed
		fi
	fi

	;;

*)
	echo "Usage: $0 {start|stop|status|restart|reload|flush|print}"
	exit 1
esac

exit 0
