#!/usr/bin/env bash # # JbTecWiz Support Centre -- generated fix script # # Fault : A firewall change has no effect, or locks the machine out # Fix : Establish what is actually in force # Source: https://jbtecwiz.com/support/lnx-net-firewalld # # Run as : Root shell # Expect : 15 minutes # Risk : low # Reversible : yes # # WHEN THIS IS THE RIGHT FIX # Before changing anything. Two front ends fighting is the most common # cause of a rule that does nothing. # # HOW TO UNDO IT # Re-enable whichever service was previously in use. # # Walks the fix one step at a time and asks before each. Steps with no # command are yours to do -- it prints those and waits. DRYRUN=1 prints # without executing; UNATTENDED=1 does not ask. # # -------------------------------------------------------------------- # NO WARRANTY - USE AT YOUR OWN RISK # # This script is provided by JbTecWiz as-is and with no warranty of any # kind, express or implied. You run it entirely at your own risk. # # JbTecWiz accepts no liability for any loss or damage arising from its # use, including but not limited to data loss, downtime, or configuration # changes that turn out to be wrong for your system. # # You are responsible for reading this script before running it, for # satisfying yourself that it suits the machine in front of you, and for # having a working backup first. Some steps cannot be undone. # -------------------------------------------------------------------- set -uo pipefail DRYRUN="${DRYRUN:-0}" UNATTENDED="${UNATTENDED:-0}" failed=0 if [ "$(id -u)" -ne 0 ]; then echo " This fix is documented as needing root. Re-run with sudo." >&2 exit 3 fi rule() { printf "\n%s\n" "$(printf '-%.0s' $(seq 1 70))"; if [ $# -gt 0 ]; then echo "$1"; fi; } prose() { echo "$1" | fold -s -w 74 | sed "s/^/ /"; } # Returns 0 when the caller should run the command, 1 when it should not. # A manual step always returns 1 -- there is nothing for the caller to run. step() { # step [command lines...] local n="$1" dotext="$2" why="$3" mode="$4"; shift 4 rule " Step $n of 4" prose "$dotext" if [ -n "$why" ]; then echo; prose "$why"; fi if [ "$mode" = "manual" ]; then echo; echo " -> Do this yourself, then press Enter to carry on." if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r _; fi return 1 fi echo; printf " %s\n" "$@"; echo if [ "$DRYRUN" = "1" ]; then echo " (dry run -- not executed)"; return 1; fi if [ "$UNATTENDED" = "0" ]; then read -r -p " Run this step? [Y]es / [S]kip / [Q]uit " a case "$a" in [Qq]*) echo " Stopped at your request."; exit 0 ;; [Ss]*) echo " Skipped."; return 1 ;; esac fi return 0 } rule echo " A firewall change has no effect, or locks the machine out" echo " Establish what is actually in force" echo echo " Risk: low Reversible 15 minutes" echo prose 'No warranty. Use at your own risk - JbTecWiz accepts no liability. Read it before you run it, and have a backup.' rule echo if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r -p " Ready? [y/N] " go case "$go" in [Yy]*) ;; *) echo " Nothing was changed."; exit 0;; esac fi if step 1 'See which services are running.' 'More than one active here explains almost every "my rule does not work" report. Pick one, disable the others, and the confusion goes with them.' cmd 'systemctl is-active firewalld ufw nftables iptables 2>/dev/null'; then systemctl is-active firewalld ufw nftables iptables 2>/dev/null if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 1 failed. The rest of the fix may depend on it." >&2 fi fi if step 2 'Look at the real kernel ruleset, which is the only authority.' '' cmd 'sudo nft list ruleset | head -80'; then sudo nft list ruleset | head -80 if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 2 failed. The rest of the fix may depend on it." >&2 fi fi if step 3 'Check the legacy view as well, since some tools still write there.' '' cmd 'sudo iptables -S | head -40' 'sudo iptables -L -n -v --line-numbers | head -40'; then sudo iptables -S | head -40 sudo iptables -L -n -v --line-numbers | head -40 if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 3 failed. The rest of the fix may depend on it." >&2 fi fi if step 4 'Disable the front ends you are not using.' '' cmd 'sudo systemctl disable --now ufw' 'sudo systemctl enable --now firewalld'; then sudo systemctl disable --now ufw sudo systemctl enable --now firewalld if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 4 failed. The rest of the fix may depend on it." >&2 fi fi rule " Confirm it worked" prose 'One front end is active and nft list ruleset matches what it reports.' if [ "$DRYRUN" = "0" ]; then sudo firewall-cmd --list-all fi rule if [ "$failed" -gt 0 ]; then echo " Finished with $failed failed step(s)." echo " Read the full write-up at https://jbtecwiz.com/support/lnx-net-firewalld" else echo " Finished." fi echo prose 'To undo: Re-enable whichever service was previously in use.' rule