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