change_rules.sh revision 78408
1#!/bin/sh
2#
3# Copyright (c) 2000 Alexandre Peixoto
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/share/examples/ipfw/change_rules.sh 78408 2001-06-18 12:35:14Z ru $
28
29# Change ipfw(8) rules with safety guarantees for remote operation
30#
31# Invoke this script to edit ${firewall_script}. It will call ${EDITOR},
32# or vi(1) if the environment variable is not set, for you to edit
33# ${firewall_script}, asks for confirmation and then run
34# ${firewall_script}. You can then examine the output of ipfw list and
35# confirm whether you want the new version or not.
36#
37# If no answer is received in 30 seconds, the previous
38# ${firewall_script} is run, restoring the old rules (this assumes ipfw
39# flush is present in it).
40#
41# If the new rules are confirmed, they'll replace ${firewall_script} and
42# the previous ones will be copied to ${firewall_script}.{date}. A mail
43# will also be sent to root with the unified diffs of the rule change.
44#
45# Non-approved rules are kept in ${firewall_script}.new, and you are
46# offered the option of changing them instead of the present rules when
47# you call this script.
48#
49# It is suggested improving this script by using some version control
50# software.
51
52if [ -r /etc/defaults/rc.conf ]; then
53	. /etc/defaults/rc.conf
54	source_rc_confs
55elif [ -r /etc/rc.conf ]; then
56	. /etc/rc.conf
57fi
58
59EDITOR=${EDITOR:-/usr/bin/vi}
60
61get_yes_no() {
62	while true
63	do
64		echo -n "$1 (Y/N) ? " 
65		read -t 30 a
66		if [ $? != 0 ]; then
67			a="No";
68		        return;
69		fi
70		case $a in
71			[Yy]) a="Yes";
72			      return;;
73			[Nn]) a="No";
74			      return;;
75			*);;
76		esac
77	done
78}
79
80restore_rules() {
81	nohup sh ${firewall_script} >/dev/null 2>&1 
82	exit
83}
84
85if [ -f ${firewall_script}.new ]; then
86	get_yes_no "A new rules file already exists, do you want to use it"
87	[ $a = 'No' ] && cp ${firewall_script} ${firewall_script}.new
88else 
89	cp ${firewall_script} ${firewall_script}.new
90fi
91
92trap restore_rules SIGHUP
93
94${EDITOR} ${firewall_script}.new
95
96get_yes_no "Do you want to install the new rules"
97
98[ $a = 'No' ] && exit
99
100cat <<!
101The rules will be changed now. If the message 'Type y to keep the new
102rules' do not appear on the screen or the y key is not pressed in 30
103seconds, the former rules will be restored.
104The TCP/IP connections might be broken during the change. If so, restore
105the ssh/telnet connection being used.
106!
107
108nohup sh ${firewall_script}.new > /tmp/`basename ${firewall_script}`.out 2>&1;
109sleep 2;
110get_yes_no "Would you like to see the resulting new rules"
111[ $a = 'Yes' ] && ${EDITOR} /tmp/`basename ${firewall_script}`.out
112get_yes_no "Type y to keep the new rules"
113[ $a != 'Yes' ] && restore_rules
114
115DATE=`date "+%Y%m%d%H%M"`
116cp ${firewall_script} ${firewall_script}.$DATE
117mv ${firewall_script}.new ${firewall_script} 
118cat <<!
119The new rules are now default. The previous rules have been preserved in
120the file ${firewall_script}.$DATE
121!
122diff -F "^# .*[A-Za-z]" -u ${firewall_script}.$DATE ${firewall_script} | mail -s "`hostname` Firewall rule change" root
123
124