#!/bin/sh
#
# this file maintained at http://git.mdcc.cx/uruk.git
#
# Uruk control script.
# Copyright (C) 2002, 2003 Laurence J. Lane
# Copyright (C) 2003 - 2005, 2007, 2010 Joost van Baal
# Copyright (C) 2013 - 2016 Joost van Baal-Ilić
#
# This file is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
#
# You should have received a copy of the GNU GPL along with this file, see
# e.g. the file named COPYING. If not, see .
# Based upon /etc/init.d/iptables as shipped with the Debian iptables
# package by Laurence J. Lane
set -e
# do sanity check on uruk environment.
enable_uruk_check=true
## enable_uruk_check=false
# enable ipv6 support
enable_ipv6=true
# enable calling the unstable uruk-save script
enable_uruk_save=false
# set enable_autosave to "true" to autosave the active ruleset
# when going from start to stop
enable_autosave=true
# set enable_save_counters to "true" to save table counters with
# rulesets
enable_save_counters=true
# /etc/default/uruk can overrule
# enable_uruk_check, enable_ipv6, enable_autosave, enable_save_counters and PATH
# On Debian systems, configuration for init scripts is in /etc/default/
test -f /etc/default/uruk && . /etc/default/uruk
# On Red Hat systems, configuration for init scripts is in /etc/sysconfig/
test -f /etc/sysconfig/uruk && . /etc/sysconfig/uruk
# exit code
STATUS=0
initd="$0"
initd_abort_wrong_arg () {
cmd=$1
shift
echo "Aborting urukctl $cmd: wrong argument: $@"
exit 2
}
initd_have_a_cow_man () {
for i in $@; do
if ! command -v "$i" >/dev/null 2>&1; then
echo "Aborting urukctl: missing executable $i"
exit 5
fi
done
}
initd_clear () {
rm -f "$autosave"
echo -n "Clearing ${iptables_command} ruleset: default ACCEPT policy"
$iptables_save | sed "/-/d;/^#/d;s/DROP/ACCEPT/" | $iptables_restore
echo "."
}
initd_halt () {
rm -f $autosave
echo -n "Clearing ${iptables_command} ruleset: default DROP policy"
$iptables_save | sed "/-/d;/^#/d;s/ACCEPT/DROP/" | $iptables_restore
echo "."
}
initd_flush () {
# This will NOT flush the mangle or nat table. If we wanna do that, we'd have to do
# something like
#
# while read -r table;do iptables -t $table -F;done "$ruleset"
STATUS=$?
else
$iptables_save | sed '/^:/s@\[[0-9]\{1,\}:[0-9]\{1,\}\]@[0:0]@g' > "$ruleset"
STATUS=$?
fi
}
initd_save () {
rm -f $autosave
ruleset="$libdir/$@"
echo -n "Saving ${iptables_command} ruleset: save \"$@\""
initd_counters
echo "."
}
initd_autosave () {
if $enable_autosave && test -f $autosave; then
ruleset="$libdir/active"
echo -n "Autosaving ${iptables_command} ruleset: save \"active\""
initd_counters
echo "."
fi
}
initd_active_uruk_save () {
if test $iptables_command = ip6tables; then
echo -n "Saving IPv6 uruk rules as active ruleset"
uruk-save -6 > "$libdir/active"
STATUS=$?
echo "."
else
echo -n "Saving IPv4 uruk rules as active ruleset"
uruk-save > "$libdir/active"
STATUS=$?
echo "."
fi
initd_load active
dummy=$?
test "$STATUS" = 0 && STATUS=$dummy
}
initd_active () {
if $enable_uruk_save; then
initd_active_uruk_save
else
initd_flush
if test $iptables_command = ip6tables; then
echo -n "Loading IPv6 uruk rules"
# skip all iptables commands in uruk
URUK_IPTABLES=':' uruk
STATUS=$?
echo "."
else
echo -n "Loading IPv4 uruk rules"
# skip all ip6tables commands in uruk
URUK_IP6TABLES=':' uruk
STATUS=$?
echo "."
fi
initd_save active
dummy=$?
test "$STATUS" = 0 && STATUS=$dummy
fi
}
initd_start () {
if ! test -e "$libdir/inactive"; then
initd_save inactive
fi
initd_active
if $enable_autosave; then
touch $autosave
fi
}
initd_stop () {
# act sane if inactive state file missing
ruleset="$libdir/inactive"
if test -e $ruleset; then
initd_load inactive
rm $ruleset
else
echo "Uruk not running (no inactive file found)"
STATUS=0
fi
}
initd_status() {
initd_preload
tmpdir=`mktemp -d /tmp/uruk.$iptables_command.XXXXXXXXXX`
trap 'rm -rf $tmpdir' 0
# grep possibly matches nothing, force succesfull exit
$iptables_save | grep '^-' >$tmpdir/kernel || true
for rule in active inactive; do
eval status_$rule=
eval found_$rule=
if test -e $libdir/$rule; then
sed -n 's/^\[[0-9]\{1,\}:[0-9]\{1,\}\] //p' $libdir/$rule >$tmpdir/ruleset
if diff $tmpdir/ruleset $tmpdir/kernel >/dev/null; then
echo "Checking uruk ($iptables_command): $rule uruk rules loaded"
eval status_$rule=1
fi
eval found_$rule=1
fi
done
rm -r $tmpdir
# if running, active loaded; then rulesets existing as file: active inactive
# if "not running", inactive loaded; then active
if test "$found_active"; then
if test "$found_inactive"; then
# uruk is running, STATUS=0
STATUS=0
else
# uruk is not running
STATUS=3
fi
else
# uruk not running, unconfigured: "unknown"
STATUS=4
fi
}
usage () {
cat << END
$initd options:
start
save
create
load
reload
force-reload
stop
restart
status
clear
halt
flush
See the urukctl(8) manpage for details.
END
}
initd_main () {
initd_vars
case "$1" in
start)
initd_start
;;
stop)
initd_stop
;;
restart)
# Restart service (if running) or start service
$initd stop
$initd start
;;
force-reload)
for rule in active inactive; do
eval found_$rule=
if test -e $libdir/$rule; then
eval found_$rule=1
fi
done
if test "$found_active" -a "$found_inactive"; then
# uruk is running
initd_active
else
echo "Uruk is not running"
STATUS=0
fi
;;
status)
# If the status action is requested, the init script will
# return the following exit status codes.
#
# 0 program is running or service is OK
#(1 program is dead and /var/run pid file exists)
#(2 program is dead and /var/lock lock file exists)
# 3 program is not running
# 4 program or service status is unknown
# will set STATUS, used as exit code
initd_status
;;
# end of LSB required init arguments
reload)
for rule in active inactive; do
eval found_$rule=
if test -e $libdir/$rule; then
eval found_$rule=1
fi
done
if test "$found_active" -a "$found_inactive"; then
if $enable_uruk_save; then
initd_active_uruk_save
else
cat < "$libdir/active"
echo "."
else
echo -n "Saving IPv4 uruk rules as active ruleset"
uruk-save > "$libdir/active"
echo "."
fi
else
cat </dev/null; then
echo "Fails to run ${iptables_command}."
exit 4
fi
}
check_uruk() {
initd_have_a_cow_man uruk >/dev/null
uruk_config="/etc/uruk/rc"
# check for existence of uruk rc file.
if ! test -r $uruk_config; then
echo "No file $uruk_config present."
exit 6
fi
# check for sanity of uruk rc file.
if grep -q URUK_IS_UNCONFIGURED $uruk_config; then
echo "Uruk is unconfigured. Please create a sane file $uruk_config. See uruk(8)."
exit 6
fi
}
# check command line args
case "$1" in
start|stop|restart|force-reload|status|reload|clear|halt|flush|save|create|load)
# pass
;;
*)
usage
initd_abort_wrong_arg "$*"
;;
esac
if $enable_uruk_check; then
check_uruk
fi
iptables_command=iptables initd_main $*
if $enable_ipv6; then
iptables_command=ip6tables initd_main $*
fi
exit $STATUS