#!/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