You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+90-21Lines changed: 90 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,91 @@
2
2
3
3
All notable changes to the Apotropaios Firewall Manager are documented here.
4
4
5
+
## [1.1.10] - 2026-03-29
6
+
7
+
### Automatic Rule Expiry and Proactive Alerts
8
+
-**Background expiry monitor (`_expiry_monitor_loop`):** Runs every 30 seconds while the interactive menu is active. Auto-deactivates expired temporary rules without requiring manual intervention. Writes terminal alerts to `/dev/tty` for rules within 10 minutes of expiring, including rule ID, description, and time remaining.
9
+
-**Inline expiry alerts (`_menu_check_expiry_alerts`):** Every time the main menu renders, scans for near-expiry (< 10 minutes) and already-expired temporary rules. Displays color-coded warnings inline in the menu with guidance to extend via the Rule Expiry Watcher.
10
+
-**Per-iteration expiry check:**`rule_check_expired()` now runs on every main menu loop iteration in addition to the background monitor, ensuring expired rules are deactivated within seconds of returning to the main menu.
11
+
-**Clean lifecycle:** Monitor starts on menu entry (`_expiry_monitor_start`), stops on exit (`_expiry_monitor_stop`), and is registered with the framework's cleanup stack (`error_register_cleanup`) for signal-safe termination.
12
+
-**Double-start guard:**`_expiry_monitor_start()` checks if a monitor is already running before launching a second instance.
13
+
14
+
## [1.1.9] - 2026-03-29
15
+
16
+
### Bug Fixes
17
+
-**Firewalld status showed only default zone:**`fw_firewalld_status()` used `firewall-cmd --list-all` which displays only the default zone. Replaced with `--get-active-zones` + `--list-all-zones` to show full configuration across all zones.
18
+
-**Firewalld config submenu zone selector hung:**`_firewalld_select_zone()` ran inside `$()` command substitution which creates a subshell — the `read` from `/dev/tty` inside a subshell had I/O issues causing the prompt to not display and the function to appear to hang. Fix: rewrote with nameref parameter (no subshell). Also added cancel keyword detection (`q`/`quit`/`cancel`/`back`/`b`) — previously "q" passed through as a zone name to `firewall-cmd` producing "Error: INVALID_ZONE: q".
19
+
-**UFW rule creation failed without destination port:** Simple syntax path produced `ufw allow comment apotropaios:UUID` which UFW rejected (requires at least a port). Root cause: same as previous firewalld fix — no guard for port-less rules. Fix: forced extended syntax path (`ufw allow in proto tcp from any to any`) when no destination port is given. Extended syntax handles protocol-only rules correctly.
20
+
-**UFW error logging:** Replaced `2>/dev/null` with stderr capture on add/remove operations. Failed rules now log the actual `ufw` error message.
21
+
22
+
## [1.1.8] - 2026-03-28
23
+
24
+
### Firewalld Full Zone Support
25
+
-**Dynamic zone selection in rule wizard:** Replaced freeform text input with numbered zone list from `firewall-cmd --get-zones`. Default zone highlighted. Accepts zone number or name. Falls back to text input if firewall-cmd unavailable.
26
+
-**Reset function cleans all zones:**`fw_firewalld_reset()` now iterates all available zones instead of hardcoding "public". Removes ports and rich rules from every zone before reload.
27
+
-**Config submenu zone-aware (6→8 options):** Options 4 (services), 5 (rich rules), 6 (full config), and 7 (runtime vs permanent) now prompt for zone selection via `_firewalld_select_zone()` helper. New option 8: Change default zone. All queries use `--zone=` parameter.
28
+
-**`_firewalld_select_zone()` helper:** Reusable zone picker used by both the config submenu and the rule wizard. Shows numbered list with default zone marker.
29
+
30
+
### iptables Config Submenu Table Selection
31
+
-**Option 5 rewritten:** "Show active table summary" (filter-only) replaced with "Show rules in table" — presents numbered table selector (filter/nat/mangle/raw/security) then shows full rules for the selected table
32
+
-**Option 7 added:** "Show all tables (full)" — iterates all 5 tables with full `iptables -L -n --line-numbers` output per table. Previous option 6 (chain policies summary) retained for quick overview.
33
+
34
+
## [1.1.7] - 2026-03-28
35
+
36
+
### Bug Fixes
37
+
-**Immutable snapshot verify false positive:**`immutable_verify()` reported "All snapshots verified" when no snapshots existed. Root cause: function returned 0 (success) when `checked=0` and `failed=0`, and menu interpreted return 0 as verified. Fix: function now detects empty snapshot directory/no integrity files and returns 2 with explicit "No immutable snapshots exist" message. Menu handles all 3 return codes (0=verified, 1=failed, 2=none exist).
38
+
-**Immutable snapshot list empty state:**`immutable_list()` now shows "No immutable snapshots exist" when the directory is empty, instead of printing a header with count 0 and no entries.
39
+
-**Rule creation confirmation invisible:**`util_confirm()` wrote the "Apply this rule?" prompt to stderr while all wizard prompts wrote to stdout. In the menu context, the stderr prompt was invisible — the user saw a hang after the summary, and pressing Enter triggered the default "n" → "Rule creation cancelled." Fix: replaced `util_confirm` with `_wizard_read` for the confirmation step, keeping all prompts on stdout.
40
+
-**Expired rules check reported "Done":** Menu option 9 (Check expired rules) printed "Done" regardless of whether expired rules existed. Now prints "No expired rules." (green) when none found, or "Processed expired rules." when some were deactivated.
41
+
-**Firewalld rich rule builder missing protocol element:** Rules created without a destination port produced invalid rich rules like `rule family="ipv4" accept` (no filtering element). Root cause: the builder only added protocol for ICMP, not for tcp/udp/sctp. Fix: added `protocol value="${protocol}"` element for all non-port, non-all protocols. Also forced the rich rule path for all port-less rules (the simple `--add-port` path silently did nothing without a port).
42
+
-**Firewalld error logging:** Replaced `2>/dev/null` with stderr capture on all three `firewall-cmd` invocations (add rich rule, add port, remove rule). Failed rules now log the actual error message.
43
+
44
+
### Rule Creation Wizard Cancel Support
45
+
-**`_wizard_read()` helper:** New cancel-aware input function detects `q`, `quit`, `cancel`, `back`, or `b` (case-insensitive) at any wizard prompt
46
+
- All 29 input prompts across all 5 backend paths (including the final confirmation) route through `_wizard_read()` — no partial rules are created on cancellation
47
+
- Cancel hint shown at wizard start: "Type q, quit, cancel, or back at any prompt to abort"
48
+
- Cancellation prints "Rule creation cancelled." and returns cleanly to the Rule Management menu
49
+
50
+
## [1.1.6] - 2026-03-28
51
+
52
+
### Interactive Mode Flag
53
+
-**`--interactive`:** New global CLI flag provides explicit separation between interactive menu mode and direct CLI command execution
54
+
- Mutually exclusive with `--non-interactive` (clear error: "mutually exclusive") and CLI commands (clear error: "cannot be combined with a command")
55
+
- Three ways to launch menu (priority order): `--interactive` (preferred), `menu` subcommand (backward compatible), no arguments (backward compatible)
56
+
- Help system updated with Operation Modes section explaining both modes
57
+
-`_show_usage()` updated with Operation Modes display and `--interactive` in global options and examples
58
+
59
+
### ShellCheck Compliance
60
+
-**SC2015:** Replaced 4 `A && B || C` patterns with proper if/then/else (backup.sh, firewalld.sh, menu_main.sh)
-**Security scan refinement:** CI pattern scan rewritten with file-based eval exclusions (audited files: security.sh, errors.sh, utils.sh) and context-aware command substitution filtering
71
+
-**`softprops/action-gh-release@v2`:** Remains at v2 (no Node 24 build available); `FORCE_JAVASCRIPT_ACTIONS_TO_NODE24` env var ensures compatibility
72
+
73
+
### Packaging Expansion
74
+
-**`make dist-venv`:** New target generates portable virtual environment package with `activate.sh` and `bin/apotropaios` wrapper
75
+
-**`make release`:** New unified target builds all 3 packages (runtime, full, venv) with single SHA256SUMS.txt
76
+
-**`dist-full` fix:** Now generates its own SHA256SUMS.txt (was using `>>` append which failed standalone)
77
+
-**release.yml:** Updated to use `make release`, attaches all 3 packages, adds checksum verification step
78
+
-**Makefile:** 40 targets (was 38)
79
+
80
+
### Testing (380 tests — all passing)
81
+
- CLI: 34 (was 29 — 5 new `--interactive` flag validation tests)
82
+
- Unit: 234, Integration: 98, Security: 48
83
+
84
+
### Documentation
85
+
- README.md rewritten to 1,070+ lines matching production-quality reference standard
86
+
- CODE_OF_CONDUCT.md expanded to 441 lines (responsible use policy, contributor rights, appeal process, IP provisions)
87
+
- LICENSE merged to 412 lines with 12 supplementary sections (firewall disclaimer, assumption of risk, export compliance)
88
+
- All repository URLs updated to `Sandler73/Apotropaios-Firewall-Manager`
89
+
5
90
## [1.1.5] - 2026-03-27
6
91
7
92
### Security Audit Fixes (4 Critical, 6 High — all resolved)
@@ -20,30 +105,14 @@ All notable changes to the Apotropaios Firewall Manager are documented here.
20
105
-**H5: `make security-scan` had false positives.** Rewrote all 6 checks to capture grep output to variable before testing (fixed `head -5` returning 0 on empty input). Also excluded log sanitization patterns and log_info messages from triggers. Now reports 4 passed, 2 legitimate warnings.
-**BUG-010:** Fixed critical regression from H3 audit fix — `sanitize_input()` whitelist `tr -cd` class had misplaced hyphen (`/-+`) causing GNU `tr` to fail and return empty string on ALL inputs. Every menu selection returned "Invalid option." Fix: hyphen moved to last position in tr class (`%-`). Removed `\n\t` from single-quoted string (were literal backslash+n, not actual newline/tab).
30
115
31
-
### ShellCheck Compliance
32
-
-**SC2015:** Replaced 4 `A && B || C` patterns with proper if/then/else (backup.sh, firewalld.sh, menu_main.sh)
0 commit comments