From d747ee0f83ce0f576a43b30f1545bcfa7464f186 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 5 Jul 2023 16:13:16 +0200 Subject: [PATCH] minifirewall: add safe-restart and safe-start commands --- minifirewall/files/check_minifirewall | 5 +- minifirewall/files/minifirewall | 87 +++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/minifirewall/files/check_minifirewall b/minifirewall/files/check_minifirewall index bfd5bfc7..fc034de4 100644 --- a/minifirewall/files/check_minifirewall +++ b/minifirewall/files/check_minifirewall @@ -106,6 +106,7 @@ main() { fi fi else + append_details "minifirewall is stopped" summary_critical "minifirewall is stopped, but enabled in alert5 or systemd" fi else @@ -131,10 +132,6 @@ main() { fi fi - [ "${return}" -ge 0 ] && header="OK" - [ "${return}" -ge 1 ] && header="WARNING" - [ "${return}" -ge 2 ] && header="CRITICAL" - printf "%s\n\n%s\n" "${summary}" "${details}" exit "${return}" diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall index 2272a4b0..b1b659de 100755 --- a/minifirewall/files/minifirewall +++ b/minifirewall/files/minifirewall @@ -111,6 +111,10 @@ STATE_FILE_DIFF='/var/run/minifirewall_state_diff' ACTIVE_CONFIG='/var/run/minifirewall_active_config' ACTIVE_CONFIG_DIFF="${ACTIVE_CONFIG}.diff" +SAFETY_LOCK='/var/run/minifirewall_safety.lock' +SAFETY_OUTPUT='/var/run/minifirewall_safety.out' +SAFETY_TIMER=30 + LOGGER_BIN=$(command -v logger) # No colors by default @@ -123,8 +127,10 @@ CYAN='' WHITE='' BOLD='' RESET='' + # check if stdout is a terminal... if [ -t 1 ]; then + INTERACTIVE=1 # see if it supports colors... ncolors=$(tput colors) @@ -141,7 +147,10 @@ if [ -t 1 ]; then BOLD=$(tput bold) RESET='\e[m' fi +else + INTERACTIVE=0 fi +readonly INTERACTIVE ## pseudo dry-run : ## Uncomment and call these functions instead of the real iptables and ip6tables commands @@ -155,6 +164,9 @@ fi # } ## Beware that commands executed from included files are not modified by this trick. +is_interactive() { + test "${INTERACTIVE}" = "1" +} remove_colors() { sed -r 's/\x1B\[(;?[0-9]{1,3})+[mGK]//g' } @@ -1143,6 +1155,58 @@ reset() { syslog_info "reset" printf "${GREEN}${BOLD}${PROGNAME} reset${RESET}\n" } + +stop_if_locked() { + count=0 + + while [ ${count} -lt ${SAFETY_TIMER} ] && [ -f "${SAFETY_LOCK}" ]; do + count=$(( count + 1 )) + sleep 1 + done + + if [ -f "${SAFETY_LOCK}" ]; then + syslog_error "safety lock is still here after ${SAFETY_TIMER} seconds, we need to stop" + + stop + + syslog_info "remove safety lock" + rm -f "${SAFETY_LOCK}" + else + syslog_info "safety lock is not there anymore, life goes on" + fi +} + +safe_start() { + # start the firewall + start + + # create the lock file + syslog_info "add safety lock" + touch "${SAFETY_LOCK}" + + # run the special background command + nohup "${0}" stop-if-locked > "${SAFETY_OUTPUT}" 2>&1 & + + if is_interactive; then + syslog_info "safe-restart in interactive mode ; if safety lock (${SAFETY_LOCK}) is not removed in the next ${SAFETY_TIMER} seconds, minifirewall will be stopped." + # Ask for input + confirm_default="I'm locked out, please stop the firewall" + # printf "If the restart has locked you out you might see this but you shouldn't be able to type anything.\n" + printf "Minifirewall will be stopped in ${SAFETY_TIMER} seconds if you do nothing.\n" + printf "Remove \`${SAFETY_LOCK}' or type anything to keep minifirewall started: " + + read -r confirm + + if [ ! -f "${SAFETY_LOCK}" ]; then + printf "Safety lock is not there anymore.\nYou've probably been rescued by the safety checks.\n" + elif [ "${confirm}" != "${confirm_default}" ]; then + rm -f "${SAFETY_LOCK}" && printf "OK. Safety lock is removed.\n" + fi + else + syslog_info "safe-restart in non-interactive mode ; if safety lock (${SAFETY_LOCK}) is not removed in the next ${SAFETY_TIMER} seconds, minifirewall will be stopped." + fi +} + show_version() { cat <