manpages: do not include v4-only modules in ip6tables manpage
[jleu-iptables.git] / iptables-apply
blob5fec76b02b216699ecb66f67931ea7d498b5500e
1 #!/bin/bash
3 # iptables-apply -- a safer way to update iptables remotely
5 # Copyright © Martin F. Krafft <madduck@madduck.net>
6 # Released under the terms of the Artistic Licence 2.0
8 set -eu
10 PROGNAME="${0##*/}";
11 VERSION=1.0
13 TIMEOUT=10
14 DEFAULT_FILE=/etc/network/iptables
16 function blurb()
18 cat <<-_eof
19 $PROGNAME $VERSION -- a safer way to update iptables remotely
20 _eof
23 function copyright()
25 cat <<-_eof
26 $PROGNAME is C Martin F. Krafft <madduck@madduck.net>.
28 The program has been published under the terms of the Artistic Licence 2.0
29 _eof
32 function about()
34 blurb
35 echo
36 copyright
39 function usage()
41 cat <<-_eof
42 Usage: $PROGNAME [options] ruleset
44 The script will try to apply a new ruleset (as output by iptables-save/read
45 by iptables-restore) to iptables, then prompt the user whether the changes
46 are okay. If the new ruleset cut the existing connection, the user will not
47 be able to answer affirmatively. In this case, the script rolls back to the
48 previous ruleset.
50 The following options may be specified, using standard conventions:
52 -t | --timeout Specify the timeout in seconds (default: $TIMEOUT)
53 -V | --version Display version information
54 -h | --help Display this help text
55 _eof
58 SHORTOPTS="t:Vh";
59 LONGOPTS="timeout:,version,help";
61 OPTS=$(getopt -s bash -o "$SHORTOPTS" -l "$LONGOPTS" -n "$PROGNAME" -- "$@") || exit $?
62 for opt in $OPTS; do
63 case "$opt" in
64 (-*) unset OPT_STATE;;
65 (*)
66 case "${OPT_STATE:-}" in
67 (SET_TIMEOUT)
68 eval TIMEOUT=$opt
69 case "$TIMEOUT" in
70 ([0-9]*) :;;
71 (*)
72 echo "E: non-numeric timeout value." >&2
73 exit 1
75 esac
77 esac
79 esac
81 case "$opt" in
82 (-h|--help) usage >&2; exit 0;;
83 (-V|--version) about >&2; exit 0;;
84 (-t|--timeout) OPT_STATE=SET_TIMEOUT;;
85 (--) break;;
86 esac
87 shift
88 done
90 FILE="${1:-$DEFAULT_FILE}";
92 if [[ -z "$FILE" ]]; then
93 echo "E: missing file argument." >&2
94 exit 1
97 if [[ ! -r "$FILE" ]]; then
98 echo "E: cannot read $FILE" >&2
99 exit 2
102 case "${0##*/}" in
103 (*6*)
104 SAVE=ip6tables-save
105 RESTORE=ip6tables-restore
108 SAVE=iptables-save
109 RESTORE=iptables-restore
111 esac
113 COMMANDS=(tempfile "$SAVE" "$RESTORE")
115 for cmd in "${COMMANDS[@]}"; do
116 if ! command -v $cmd >/dev/null; then
117 echo "E: command not found: $cmd" >&2
118 exit 127
120 done
122 umask 0700
124 TMPFILE=$(tempfile -p iptap)
125 trap "rm -f $TMPFILE" EXIT 1 2 3 4 5 6 7 8 10 11 12 13 14 15
127 if ! "$SAVE" >"$TMPFILE"; then
128 if ! grep -q ipt /proc/modules 2>/dev/null; then
129 echo "E: iptables support lacking from the kernel." >&2
130 exit 3
131 else
132 echo "E: unknown error saving current iptables ruleset." >&2
133 exit 4
137 [ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban stop
139 echo -n "Applying new ruleset... "
140 if ! "$RESTORE" <"$FILE"; then
141 echo "failed."
142 echo "E: unknown error applying new iptables ruleset." >&2
143 exit 5
144 else
145 echo done.
148 echo -n "Can you establish NEW connections to the machine? (y/N) "
150 read -n1 -t "${TIMEOUT:-15}" ret 2>&1 || :
151 case "${ret:-}" in
152 (y*|Y*)
153 echo
154 echo ... then my job is done. See you next time.
157 if [[ -z "${ret:-}" ]]; then
158 echo "apparently not..."
159 else
160 echo
162 echo "Timeout. Something happened (or did not). Better play it safe..."
163 echo -n "Reverting to old ruleset... "
164 "$RESTORE" <"$TMPFILE";
165 echo done.
166 exit 255
168 esac
170 [ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban start
172 exit 0
174 # vim:noet:sw=8