18d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft#!/bin/bash 28d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft# 38d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft# iptables-apply -- a safer way to update iptables remotely 48d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft# 58d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft# Copyright © Martin F. Krafft <madduck@madduck.net> 68d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft# Released under the terms of the Artistic Licence 2.0 78d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft# 88d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftset -eu 98d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 108d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftPROGNAME="${0##*/}"; 118d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftVERSION=1.0 128d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 138d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftTIMEOUT=10 148d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 158d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfunction blurb() 168d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft{ 178d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft cat <<-_eof 188d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft $PROGNAME $VERSION -- a safer way to update iptables remotely 198d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft _eof 208d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft} 218d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 228d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfunction copyright() 238d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft{ 248d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft cat <<-_eof 258d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft $PROGNAME is C Martin F. Krafft <madduck@madduck.net>. 268d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 278d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft The program has been published under the terms of the Artistic Licence 2.0 288d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft _eof 298d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft} 308d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 318d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfunction about() 328d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft{ 338d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft blurb 348d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo 358d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft copyright 368d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft} 378d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 388d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfunction usage() 398d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft{ 408d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft cat <<-_eof 418d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft Usage: $PROGNAME [options] ruleset 428d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 438d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft The script will try to apply a new ruleset (as output by iptables-save/read 448d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft by iptables-restore) to iptables, then prompt the user whether the changes 458d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft are okay. If the new ruleset cut the existing connection, the user will not 468d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft be able to answer affirmatively. In this case, the script rolls back to the 478d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft previous ruleset. 488d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 498d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft The following options may be specified, using standard conventions: 508d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 518d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft -t | --timeout Specify the timeout in seconds (default: $TIMEOUT) 528d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft -V | --version Display version information 538d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft -h | --help Display this help text 548d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft _eof 558d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft} 568d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 578d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftSHORTOPTS="t:Vh"; 588d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftLONGOPTS="timeout:,version,help"; 598d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 608d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftOPTS=$(getopt -s bash -o "$SHORTOPTS" -l "$LONGOPTS" -n "$PROGNAME" -- "$@") || exit $? 618d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfor opt in $OPTS; do 628d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft case "$opt" in 638d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (-*) unset OPT_STATE;; 648d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (*) 658d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft case "${OPT_STATE:-}" in 668d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (SET_TIMEOUT) 678d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft eval TIMEOUT=$opt 688d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft case "$TIMEOUT" in 698d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft ([0-9]*) :;; 708d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (*) 718d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "E: non-numeric timeout value." >&2 728d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 1 738d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft ;; 748d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft esac 758d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft ;; 768d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft esac 778d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft ;; 788d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft esac 798d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 808d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft case "$opt" in 818d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (-h|--help) usage >&2; exit 0;; 828d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (-V|--version) about >&2; exit 0;; 838d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (-t|--timeout) OPT_STATE=SET_TIMEOUT;; 848d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (--) break;; 858d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft esac 868d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft shift 878d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftdone 888d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 89358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafftcase "$PROGNAME" in 90358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft (*6*) 91358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft SAVE=ip6tables-save 92358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft RESTORE=ip6tables-restore 93358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft DEFAULT_FILE=/etc/network/ip6tables 94358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft ;; 95358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft (*) 96358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft SAVE=iptables-save 97358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft RESTORE=iptables-restore 98358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft DEFAULT_FILE=/etc/network/iptables 99358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft ;; 100358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafftesac 101358650c0e280dad8c1292efbf856ac310004a52bMartin F. Krafft 1028d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftFILE="${1:-$DEFAULT_FILE}"; 1038d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1048d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftif [[ -z "$FILE" ]]; then 1058d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "E: missing file argument." >&2 1068d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 1 1078d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfi 1088d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1098d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftif [[ ! -r "$FILE" ]]; then 1108d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "E: cannot read $FILE" >&2 1118d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 2 1128d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfi 1138d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1148d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftCOMMANDS=(tempfile "$SAVE" "$RESTORE") 1158d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1168d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfor cmd in "${COMMANDS[@]}"; do 1178d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft if ! command -v $cmd >/dev/null; then 1188d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "E: command not found: $cmd" >&2 1198d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 127 1208d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft fi 1218d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftdone 1228d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1238d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftumask 0700 1248d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1258d458beec463e0b16467ee4649d4575377854fd7Martin F. KrafftTMPFILE=$(tempfile -p iptap) 1268d458beec463e0b16467ee4649d4575377854fd7Martin F. Kraffttrap "rm -f $TMPFILE" EXIT 1 2 3 4 5 6 7 8 10 11 12 13 14 15 1278d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1288d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftif ! "$SAVE" >"$TMPFILE"; then 1298d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft if ! grep -q ipt /proc/modules 2>/dev/null; then 1308d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "E: iptables support lacking from the kernel." >&2 1318d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 3 1328d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft else 1338d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "E: unknown error saving current iptables ruleset." >&2 1348d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 4 1358d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft fi 1368d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfi 1378d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1388d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft[ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban stop 1398d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1408d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftecho -n "Applying new ruleset... " 1418d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftif ! "$RESTORE" <"$FILE"; then 1428d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "failed." 1438d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "E: unknown error applying new iptables ruleset." >&2 1448d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 5 1458d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftelse 1468d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo done. 1478d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftfi 1488d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1498d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftecho -n "Can you establish NEW connections to the machine? (y/N) " 1508d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1518d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftread -n1 -t "${TIMEOUT:-15}" ret 2>&1 || : 1528d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftcase "${ret:-}" in 1538d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (y*|Y*) 1548d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo 1558d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo ... then my job is done. See you next time. 1568d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft ;; 1578d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft (*) 1588d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft if [[ -z "${ret:-}" ]]; then 1598d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "apparently not..." 1608d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft else 1618d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo 1628d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft fi 1638d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo "Timeout. Something happened (or did not). Better play it safe..." 1648d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo -n "Reverting to old ruleset... " 1658d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft "$RESTORE" <"$TMPFILE"; 1668d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft echo done. 1678d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft exit 255 1688d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft ;; 1698d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftesac 1708d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1718d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft[ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban start 1728d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1738d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafftexit 0 1748d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft 1758d458beec463e0b16467ee4649d4575377854fd7Martin F. Krafft# vim:noet:sw=8 176