Blame bootstrap_ver/iptables/iptables-apply

Packit Service 1ec7f4
#!/bin/bash
Packit Service 1ec7f4
#
Packit Service 1ec7f4
# iptables-apply -- a safer way to update iptables remotely
Packit Service 1ec7f4
#
Packit Service 1ec7f4
# Copyright © Martin F. Krafft <madduck@madduck.net>
Packit Service 1ec7f4
# Released under the terms of the Artistic Licence 2.0
Packit Service 1ec7f4
#
Packit Service 1ec7f4
set -eu
Packit Service 1ec7f4
Packit Service 1ec7f4
PROGNAME="${0##*/}";
Packit Service 1ec7f4
VERSION=1.0
Packit Service 1ec7f4
Packit Service 1ec7f4
TIMEOUT=10
Packit Service 1ec7f4
Packit Service 1ec7f4
function blurb()
Packit Service 1ec7f4
{
Packit Service 1ec7f4
	cat <<-_eof
Packit Service 1ec7f4
	$PROGNAME $VERSION -- a safer way to update iptables remotely
Packit Service 1ec7f4
	_eof
Packit Service 1ec7f4
}
Packit Service 1ec7f4
Packit Service 1ec7f4
function copyright()
Packit Service 1ec7f4
{
Packit Service 1ec7f4
	cat <<-_eof
Packit Service 1ec7f4
	$PROGNAME is C Martin F. Krafft <madduck@madduck.net>.
Packit Service 1ec7f4
Packit Service 1ec7f4
	The program has been published under the terms of the Artistic Licence 2.0
Packit Service 1ec7f4
	_eof
Packit Service 1ec7f4
}
Packit Service 1ec7f4
Packit Service 1ec7f4
function about()
Packit Service 1ec7f4
{
Packit Service 1ec7f4
	blurb
Packit Service 1ec7f4
	echo
Packit Service 1ec7f4
	copyright
Packit Service 1ec7f4
}
Packit Service 1ec7f4
Packit Service 1ec7f4
function usage()
Packit Service 1ec7f4
{
Packit Service 1ec7f4
	cat <<-_eof
Packit Service 1ec7f4
	Usage: $PROGNAME [options] ruleset
Packit Service 1ec7f4
Packit Service 1ec7f4
	The script will try to apply a new ruleset (as output by iptables-save/read
Packit Service 1ec7f4
	by iptables-restore) to iptables, then prompt the user whether the changes
Packit Service 1ec7f4
	are okay. If the new ruleset cut the existing connection, the user will not
Packit Service 1ec7f4
	be able to answer affirmatively. In this case, the script rolls back to the
Packit Service 1ec7f4
	previous ruleset.
Packit Service 1ec7f4
Packit Service 1ec7f4
	The following options may be specified, using standard conventions:
Packit Service 1ec7f4
Packit Service 1ec7f4
	-t | --timeout	Specify the timeout in seconds (default: $TIMEOUT)
Packit Service 1ec7f4
	-V | --version	Display version information
Packit Service 1ec7f4
	-h | --help	Display this help text
Packit Service 1ec7f4
	_eof
Packit Service 1ec7f4
}
Packit Service 1ec7f4
Packit Service 1ec7f4
SHORTOPTS="t:Vh";
Packit Service 1ec7f4
LONGOPTS="timeout:,version,help";
Packit Service 1ec7f4
Packit Service 1ec7f4
OPTS=$(getopt -s bash -o "$SHORTOPTS" -l "$LONGOPTS" -n "$PROGNAME" -- "$@") || exit $?
Packit Service 1ec7f4
for opt in $OPTS; do
Packit Service 1ec7f4
	case "$opt" in
Packit Service 1ec7f4
		(-*) unset OPT_STATE;;
Packit Service 1ec7f4
		(*)
Packit Service 1ec7f4
			case "${OPT_STATE:-}" in
Packit Service 1ec7f4
				(SET_TIMEOUT)
Packit Service 1ec7f4
					eval TIMEOUT=$opt
Packit Service 1ec7f4
					case "$TIMEOUT" in
Packit Service 1ec7f4
						([0-9]*) :;;
Packit Service 1ec7f4
						(*)
Packit Service 1ec7f4
							echo "E: non-numeric timeout value." >&2
Packit Service 1ec7f4
							exit 1
Packit Service 1ec7f4
							;;
Packit Service 1ec7f4
					esac
Packit Service 1ec7f4
					;;
Packit Service 1ec7f4
			esac
Packit Service 1ec7f4
			;;
Packit Service 1ec7f4
	esac
Packit Service 1ec7f4
Packit Service 1ec7f4
	case "$opt" in
Packit Service 1ec7f4
		(-h|--help) usage >&2; exit 0;;
Packit Service 1ec7f4
		(-V|--version) about >&2; exit 0;;
Packit Service 1ec7f4
		(-t|--timeout) OPT_STATE=SET_TIMEOUT;;
Packit Service 1ec7f4
		(--) break;;
Packit Service 1ec7f4
	esac
Packit Service 1ec7f4
	shift
Packit Service 1ec7f4
done
Packit Service 1ec7f4
Packit Service 1ec7f4
case "$PROGNAME" in
Packit Service 1ec7f4
	(*6*)
Packit Service 1ec7f4
		SAVE=ip6tables-save
Packit Service 1ec7f4
		RESTORE=ip6tables-restore
Packit Service 1ec7f4
		DEFAULT_FILE=/etc/network/ip6tables
Packit Service 1ec7f4
		;;
Packit Service 1ec7f4
	(*)
Packit Service 1ec7f4
		SAVE=iptables-save
Packit Service 1ec7f4
		RESTORE=iptables-restore
Packit Service 1ec7f4
		DEFAULT_FILE=/etc/network/iptables
Packit Service 1ec7f4
		;;
Packit Service 1ec7f4
esac
Packit Service 1ec7f4
Packit Service 1ec7f4
FILE="${1:-$DEFAULT_FILE}";
Packit Service 1ec7f4
Packit Service 1ec7f4
if [[ -z "$FILE" ]]; then
Packit Service 1ec7f4
	echo "E: missing file argument." >&2
Packit Service 1ec7f4
	exit 1
Packit Service 1ec7f4
fi
Packit Service 1ec7f4
Packit Service 1ec7f4
if [[ ! -r "$FILE" ]]; then
Packit Service 1ec7f4
	echo "E: cannot read $FILE" >&2
Packit Service 1ec7f4
	exit 2
Packit Service 1ec7f4
fi
Packit Service 1ec7f4
Packit Service 1ec7f4
COMMANDS=(tempfile "$SAVE" "$RESTORE")
Packit Service 1ec7f4
Packit Service 1ec7f4
for cmd in "${COMMANDS[@]}"; do
Packit Service 1ec7f4
	if ! command -v $cmd >/dev/null; then
Packit Service 1ec7f4
		echo "E: command not found: $cmd" >&2
Packit Service 1ec7f4
		exit 127
Packit Service 1ec7f4
	fi
Packit Service 1ec7f4
done
Packit Service 1ec7f4
Packit Service 1ec7f4
umask 0700
Packit Service 1ec7f4
Packit Service 1ec7f4
TMPFILE=$(tempfile -p iptap)
Packit Service 1ec7f4
trap "rm -f $TMPFILE" EXIT HUP INT QUIT ILL TRAP ABRT BUS \
Packit Service 1ec7f4
		      FPE USR1 SEGV USR2 PIPE ALRM TERM
Packit Service 1ec7f4
Packit Service 1ec7f4
if ! "$SAVE" >"$TMPFILE"; then
Packit Service 1ec7f4
	if ! grep -q ipt /proc/modules 2>/dev/null; then
Packit Service 1ec7f4
		echo "E: iptables support lacking from the kernel." >&2
Packit Service 1ec7f4
		exit 3
Packit Service 1ec7f4
	else
Packit Service 1ec7f4
		echo "E: unknown error saving current iptables ruleset." >&2
Packit Service 1ec7f4
		exit 4
Packit Service 1ec7f4
	fi
Packit Service 1ec7f4
fi
Packit Service 1ec7f4
Packit Service 1ec7f4
[ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban stop
Packit Service 1ec7f4
Packit Service 1ec7f4
echo -n "Applying new ruleset... "
Packit Service 1ec7f4
if ! "$RESTORE" <"$FILE"; then
Packit Service 1ec7f4
	echo "failed."
Packit Service 1ec7f4
	echo "E: unknown error applying new iptables ruleset." >&2
Packit Service 1ec7f4
	exit 5
Packit Service 1ec7f4
else
Packit Service 1ec7f4
	echo "done."
Packit Service 1ec7f4
fi
Packit Service 1ec7f4
Packit Service 1ec7f4
echo -n "Can you establish NEW connections to the machine? (y/N) "
Packit Service 1ec7f4
Packit Service 1ec7f4
read -n1 -t "${TIMEOUT:-15}" ret 2>&1 || :
Packit Service 1ec7f4
case "${ret:-}" in
Packit Service 1ec7f4
	(y*|Y*)
Packit Service 1ec7f4
		echo
Packit Service 1ec7f4
		echo "... then my job is done. See you next time."
Packit Service 1ec7f4
		;;
Packit Service 1ec7f4
	(*)
Packit Service 1ec7f4
		if [[ -z "${ret:-}" ]]; then
Packit Service 1ec7f4
			echo "apparently not..."
Packit Service 1ec7f4
		else
Packit Service 1ec7f4
			echo
Packit Service 1ec7f4
		fi
Packit Service 1ec7f4
		echo "Timeout. Something happened (or did not). Better play it safe..."
Packit Service 1ec7f4
		echo -n "Reverting to old ruleset... "
Packit Service 1ec7f4
		"$RESTORE" <"$TMPFILE";
Packit Service 1ec7f4
		echo "done."
Packit Service 1ec7f4
		exit 255
Packit Service 1ec7f4
		;;
Packit Service 1ec7f4
esac
Packit Service 1ec7f4
Packit Service 1ec7f4
[ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban start
Packit Service 1ec7f4
Packit Service 1ec7f4
exit 0
Packit Service 1ec7f4
Packit Service 1ec7f4
# vim:noet:sw=8