From e7d95c1a62d7cb51cbb20e5dbab04ea8981f3e69 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sat, 18 Apr 2026 03:11:53 -0400 Subject: [PATCH] Improve handling of the firewall. added enable or disable to the menu based on the current state. --- .includes/firewall.sh | 63 +++++++++++++++++++++++++++++++++++++++---- .includes/nginx.sh | 8 ++---- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/.includes/firewall.sh b/.includes/firewall.sh index b5b06fe..c8b1c4a 100644 --- a/.includes/firewall.sh +++ b/.includes/firewall.sh @@ -12,6 +12,34 @@ ufw_status_output() { sudo "${sudoFlags[@]}" ufw status 2>&1 } +firewall_reboot_required() { + [[ ! -d "/lib/modules/$(uname -r)" ]] +} + +ensure_firewall_backend_ready() { + if firewall_reboot_required; then + msgbox "The running kernel does not match the installed modules. Reboot this server before managing the firewall." + return 1 + fi + + return 0 +} + +firewall_enabled() { + local statusText="" + + if ! ufw_installed; then + return 1 + fi + + if ! ensure_firewall_backend_ready; then + return 1 + fi + + statusText="$(ufw_status_output)" + [[ "$statusText" =~ ^Status:[[:space:]]+active$ ]] +} + ensure_ufw() { if ufw_installed; then return 0 @@ -27,7 +55,7 @@ ensure_ufw() { return 1 fi - msgbox "ufw installed." + msgbox "ufw installed. The firewall is not active until you choose Enable firewall." return 0 } @@ -118,6 +146,7 @@ allow_ssh_port() { local sshPort="" ensure_ufw || return 1 + ensure_firewall_backend_ready || return 1 sshPort="$(resolve_ssh_port)" || { msgbox "Firewall change cancelled because the SSH port could not be confirmed." return 1 @@ -128,8 +157,16 @@ allow_ssh_port() { enable_firewall() { ensure_ufw || return 1 + ensure_firewall_backend_ready || return 1 allow_ssh_port || return 1 + # `sudoFlags` is initialized by the main launcher before sourcing this file. + # shellcheck disable=SC2154 + if ! sudo "${sudoFlags[@]}" ufw --force enable; then + msgbox "Failed to enable ufw." + return 1 + fi + # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 if sudo "${sudoFlags[@]}" systemctl enable --now ufw; then @@ -137,12 +174,20 @@ enable_firewall() { return 0 fi - msgbox "Failed to enable ufw." + msgbox "ufw rules were enabled, but the ufw service failed to enable at boot." return 1 } disable_firewall() { ensure_ufw || return 1 + ensure_firewall_backend_ready || return 1 + + # `sudoFlags` is initialized by the main launcher before sourcing this file. + # shellcheck disable=SC2154 + if ! sudo "${sudoFlags[@]}" ufw --force disable; then + msgbox "Failed to disable ufw." + return 1 + fi # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 @@ -151,7 +196,7 @@ disable_firewall() { return 0 fi - msgbox "Failed to disable ufw." + msgbox "ufw rules were disabled, but the ufw service state could not be updated." return 1 } @@ -160,6 +205,7 @@ open_custom_port() { local protocolChoice="" ensure_ufw || return 1 + ensure_firewall_backend_ready || return 1 portNumber="$(inputbox "Enter the port number to open.")" || return 1 if ! valid_port "$portNumber"; then msgbox "Enter a valid port number from 1 to 65535." @@ -226,6 +272,7 @@ close_port() { local ruleValue="" ensure_ufw || return 1 + ensure_firewall_backend_ready || return 1 while IFS= read -r ruleValue; do [[ -n "$ruleValue" ]] && removableRules+=("$ruleValue") done < <(list_simple_allow_rules | sort -n -t / -k 1,1) @@ -253,6 +300,7 @@ view_firewall_status() { local statusText="" ensure_ufw || return 1 + ensure_firewall_backend_ready || return 1 tempFile="$(mktemp)" # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 @@ -263,9 +311,14 @@ view_firewall_status() { } while true; do + if firewall_enabled; then + firewallToggleLabel="Disable firewall" + else + firewallToggleLabel="Enable firewall" + fi + firewallChoice="$(menulist \ - "Enable firewall" \ - "Disable firewall" \ + "$firewallToggleLabel" \ "Allow SSH" \ "Open port" \ "Close port" \ diff --git a/.includes/nginx.sh b/.includes/nginx.sh index 6a618c8..364d7e8 100644 --- a/.includes/nginx.sh +++ b/.includes/nginx.sh @@ -57,9 +57,9 @@ web_ports_open() { fi while IFS= read -r statusLine; do - if [[ "$statusLine" =~ ^[[:space:]]*80/tcp[[:space:]]+ALLOW[[:space:]]+Anywhere([[:space:]]*\(v6\))?[[:space:]]*$ ]]; then + if [[ "$statusLine" =~ ^[[:space:]]*80/tcp([[:space:]]+\(v6\))?[[:space:]]+ALLOW([[:space:]]+IN)?[[:space:]]+Anywhere([[:space:]]+\(v6\))?[[:space:]]*$ ]]; then hasHttp="Yes" - elif [[ "$statusLine" =~ ^[[:space:]]*443/tcp[[:space:]]+ALLOW[[:space:]]+Anywhere([[:space:]]*\(v6\))?[[:space:]]*$ ]]; then + elif [[ "$statusLine" =~ ^[[:space:]]*443/tcp([[:space:]]+\(v6\))?[[:space:]]+ALLOW([[:space:]]+IN)?[[:space:]]+Anywhere([[:space:]]+\(v6\))?[[:space:]]*$ ]]; then hasHttps="Yes" fi done < <( @@ -125,10 +125,6 @@ prompt_clacks_header() { local nameEntry="" local clacksHeader="" - if [[ "$(yesno "Would you like to add an optional X-Clacks-Overhead header for all nginx sites?")" != "Yes" ]]; then - return 1 - fi - msgbox "X-Clacks-Overhead is an optional tribute header inspired by Terry Pratchett's Clacks. Websites use it to remember names with values such as GNU Terry Pratchett. For more information, please see: ${clacksInfoUrl}" rawNames="$(inputbox "Enter a comma-separated list of names for the X-Clacks-Overhead header, or leave blank to skip.")" || return 1 if [[ -z "${rawNames//[[:space:]]/}" ]]; then