Subject: Re: admin script for ipfilter
To: Geert Hendrickx <ghen@NetBSD.org>
From: Darren Reed <darrenr@NetBSD.org>
List: tech-userlevel
Date: 12/27/2006 15:32:42
--6c2NcOVqGQ03X4Wi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Wed, Dec 27, 2006 at 11:16:50AM +0100, Geert Hendrickx wrote:
> On Wed, Dec 27, 2006 at 12:04:47AM +0000, Darren Reed wrote:
> > So...the attached script, "ipfadm", I'm curious for feedback on.
> >
> > The idea is to do "ipfadm enable ipfilter" or "ipfadm disable ipfilter"
> > and it updates the relevant rc.d config file for you.
> >
> > Ok, not catchy...
> >
> > What I hope is of more interest is doing "ipfadm ipfilter status",
> > where it will tell you if it is enabled, disabled, enabled but no rules,
> > or disabled but rules loaded.
> >
> > Feedback welcome.
>
> Why not generalise this to "rc.dadmin enable/disable/status XXX" to toggle
> arbitrary startup scripts? You could still add ipfilter-specific hooks (as
> well as for other rc.d scripts) for the "status" command.
So I went ahead and hacked on something to work vaguely in this
fashion... and it does so long as the last line of /etc/rc.d scripts
can be "skipped".
But in doing it, it also raised some questions:
- do all scripts support "start" ?
- do all scripts support "stop" ?
- do all scripts support "restart" ?
(ie. can you have a script that only does "start" or similar)
The requirements for change to support the rcadmin script are:
X_toggle=Y
where "Y" is the variable in rc.conf/wherever that you need to
change from "YES" to "NO to enable/disable. There's a problem
here if there' every more than one Y for X.
X_rcstart() { ... }
returns a string to be output, appened to the status message
For /etc/rc.d/ipfilter, these became:
ipfilter_toggle=ipfilter
ipfilter_rcstatus() {
running=`ipf -V 2>/dev/null|sed -ne 's/Running: \(.*\)/\1/p'`
if [ -z "$running" ] ; then
rules=
emsg="-not-in-kernel"
dmsg=
else
case $running in
yes)
emsg=
dmsg="-rules-loaded"
rules=`ipfstat -io 2>/dev/null`
if [ -z "$rules" ] ; then
rules=`ipfstat -aio 2>/dev/null`
if [ -z "$rules" ] ; then
emsg="-no-rules"
dmsg=
fi
fi
;;
no)
rules=
emsg="-not-running"
dmsg=
;;
esac
fi
return "${rules}"
}
Note that the _rcstatus() function is careful to not make any
inquiries about the rc.d view of whether or not it is enabled.
Darren
--6c2NcOVqGQ03X4Wi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=rcadmin
#!/bin/sh
#
RCD=/etc/rc.conf.d
prog=$0
if [ $# -lt 1 ] ; then
echo "$prog <subsystem> <command>"
exit 1
fi
sub=$1
shift
cmd=$1
while [ $# -gt 0 ] ; do
shift
done
. /etc/rc.d/${sub}
eval evar=\$`echo ${sub}_toggle`
usage() {
echo -n "rcadmin ${sub} <enable|disable|status"
if [ -n "$start_cmd" ] ; then
echo -n "|start"
fi
if [ -n "$stop_cmd" ] ; then
echo -n "|stop"
fi
if [ -n "$restart_cmd" ] ; then
echo -n "|restart"
fi
for i in $extra_commands; do
if [ "$i" != "status" ] ; then
echo -n "|$i"
fi
done
echo ">"
exit 1
}
enable() {
old=${RCD}/${sub}.old
new=${RCD}/${sub}
mkdir ${RCD}/${sub}.d
if [ $? -eq 0 ] ; then
if [ -f ${RCD}/${sub} ] ; then
cp ${RCD}/${sub} ${RCD}/${sub}.old
sed -e "s/^${evar} *\=.*/${evar}\=YES/" ${old} > ${new}
/bin/rm ${old}
else
echo "${evar}=YES" > ${RCD}/${sub}
chmod go-wx ${RCD}/${sub}
fi
rmdir ${RCD}/${sub}.d
fi
}
disable() {
old=${RCD}/${sub}.old
new=${RCD}/${sub}
mkdir ${RCD}/${sub}.d
if [ $? -eq 0 ] ; then
if [ -f ${RCD}/${sub} ] ; then
cp ${RCD}/${sub} ${RCD}/${sub}.old
sed -e "s/^${evar} *\=.*/${evar}\=NO/" ${old} > ${new}
/bin/rm ${old}
else
echo "$evar=NO" > ${RCD}/${sub}
chmod go-wx ${RCD}/${sub}
fi
rmdir ${RCD}/${sub}.d
fi
}
status() {
active=`/etc/rc.d/${sub} rcvar|sed -ne "s/^$""${evar}\=\(.*\)$/\1/p"`
case $active in
NO)
return 0
;;
YES)
return 1
;;
esac
return 2
}
rcstatus() {
dmsg="-but-running"
emsg="-not-running"
umsg="-state-running"
eval x=\$`echo ${sub}_running`
echo -n "${sub} "
status ${evar}
case $? in
0)
if [ -n "$x" ] ; then
echo "disabled${dmsg}"
else
echo "disabled"
fi
;;
1)
if [ -n "$x" ] ; then
echo "enabled"
else
echo "enabled${emsg}"
fi
;;
2)
if [ -n "$x" ] ; then
echo "unknown${umsg}"
else
echo "unknown-state"
fi
;;
esac
}
case ${cmd} in
status)
rcstatus
;;
start)
if [ -n "$start_cmd" ] ; then
/etc/rc.d/$1 start
else
echo "${prog} ${sub} ${cmd} - not supported"
exit 1
fi
;;
stop)
if [ -n "$stop_cmd" ] ; then
/etc/rc.d/$1 stop
else
echo "${prog} ${sub} ${cmd} - not supported"
exit 1
fi
;;
enable)
enable
;;
disable)
disable
;;
reload)
if [ -n "$reload_cmd" ] ; then
/etc/rc.d/$1 reload
else
echo "${prog} ${sub} ${cmd} - not supported"
exit 1
fi
;;
restart)
if [ -n "$restart_cmd" ] ; then
/etc/rc.d/$1 restart
else
echo "${prog} ${sub} ${cmd} - not supported"
exit 1
fi
;;
*)
usage
esac
exit 0
--6c2NcOVqGQ03X4Wi--