#! /bin/sh - # -*- mode:sh -*- # $Id: $ # Copyright (c) 2007 Travis H. # # Standard GPL # Meant for Red Hat Linux and netfilter # set base filename for prepending to errors argv0=$(basename "$0") # usage="\ $argv0 [editor]" # TODO: allow specifying the time spec # TODO: allow specifying the working conf filename # TODO: allow specifying the new conf filename PATH=/usr/sbin:/sbin:/usr/local/sbin:$PATH # This is the canonical place for the iptables rules. ipt=/etc/sysconfig/iptables # This is always a backup of the last config safety was able to # verify. working=$ipt-working if test -e "$working" then : else echo <&2 Warning: $working does not exist, safety probably has never been run here, assuming $ipt is okay EOF cp "$ipt" "$working" fi # This is where we will store our new candidate new=$ipt-safety if test "$#" -gt 1 then EDITOR="$1" shift fi if test "$#" -ne 0 then echo "$usage" >&2 exit 1 fi # This is just used to flag that the at job ran. tmpfn="$(mktemp)" rm "$tmpfn" export new working pf tmpfn if cmp "$working" "$ipt" then test -e "$new" || cp "$ipt" "$new" ${EDITOR:-vi} $new || exit 1 else echo "Warning: $ipt is not the same as $working; probably last edit was not done with safety." >&2 echo "Thus, this time I will test it and you must run safety again to modify it." >&2 cp "$ipt" "$new" fi # Set up an at job to restore working configuration id="$( (echo iptables-restore $working; echo touch $tmpfn) | at now + 2 minutes 2>&1 | (read job id rest; echo $id) )" # Try out the new config iptables-restore "$new" echo -n "Is it everything you hoped for? (Y/n): " read response # TODO: Figure out what to do if at job ran, but # user says everything is okay. case "$response" in n*) echo "Okay, I will pretend this never happened." ;; *) echo "Installing new ruleset..." cp "$new" "$working" cp "$new" "$ipt" ;; esac at -r "$id" exit 0