
Dev/Firewall Refactoring
How to refactor the firewall script while ensuring no unintended nftables changes occur.
Ensuring nftables Rules Remain Unchanged[edit]
1. Store the current nftables rules in the file nftables-old
.
Click = Copy Copied to clipboard!
2. Do activities, wait, etc.
3. Store the current nftables rules in the file nftables-new
.
Click = Copy Copied to clipboard!
4. Compare nftables-old
and nftables-new
.
Use a console diff viewer:
Click = Copy Copied to clipboard!
Or use a graphical diff viewer:
Click = Copy Copied to clipboard!
Ensuring nftables Rules Remain Unchanged During Firewall Refactoring[edit]
1. Store the current nftables rules in the file nftables-old
.
Click = Copy Copied to clipboard!
2. Refactor the Kicksecure firewall code.
3. Reload Kicksecure Firewall.
If you are using Kicksecure inside Qubes, complete the following steps.
Qubes App Launcher (blue/grey "Q")
→ Kicksecure ProxyVM (commonly named kicksecure)
→ Reload Kicksecure Firewall
If you are using a graphical Kicksecure, complete the following steps.
Start Menu
→ Applications
→ System
→ Reload Kicksecure Firewall
If you are using a terminal-only Kicksecure, run. Click = Copy Copied to clipboard!
4. Store the current nftables rules in the file nftables-new
.
Click = Copy Copied to clipboard!
5. Compare nftables-old
and nftables-new
.
Use a console diff viewer:
Click = Copy Copied to clipboard!
Or use a graphical diff viewer:
Click = Copy Copied to clipboard!
systemcheck nftables Test[edit]
This feature does not exist yet.
- "systemcheck (which is somewhat a replacement for the lack of a test suite) could indeed be useful to check if the loaded nftables rules match a hardcoded nftables dump. Yes, with additional firewall add-ons, that would be challenging. These firewall add-ons could ship a dump that also gets verified (e.g., an
nftables-dumps.d
folder checked by systemcheck). However, managing multiple firewall add-ons with dumping might stretch what the Kicksecure project can realistically implement." (From (Forum) Bolt on for whonix_firewall - best place to put files?)
- systemcheck could use this nftables diff functionality to warn users about non-standard or unexpected rules. Similar to unwanted package detection, it could prompt users to run a command such as
nftables-save-whonix
to establish a new baseline. systemcheck would then pass unless further unexpected changes occurred, at which point it would issue another warning.
- systemcheck could use this nftables diff functionality to warn users about non-standard or unexpected rules. Similar to unwanted package detection, it could prompt users to run a command such as
Splitting the Kicksecure Firewall Script for Better Readability[edit]
From Patrick:
"I have been considering whether the firewall script should be split. Many sections are used by multiple packages, including the firewall and vpn-firewall. In the future, a corridor-gateway might also be introduced.
Sections that could be refactored into helper scripts:
error_handler
- Source config folder
- IPv4 DEFAULTS
- IPv4 PREPARATIONS
- IPv4 DROP INVALID INCOMING PACKETS
- IPv4 FORWARD
- IPv6
- Additional minor components (
nftables_cmd
)
These sections could be converted into shell functions and moved to helper scripts.
The risk of altering firewall rules during refactoring is minimal because changes can be verified.
However, the primary goal is to make the firewall scripts easier to read, not harder to audit. I am unsure whether keeping everything in one file or splitting it up would be simpler at this stage."
- Early files in the firewall configuration folder could contain Bash scripting in the form:
function ScriptFuncPreloadElement1() { script lines, e.g. $nftables_cmd ''blah'' }
- Optionally followed by inline execution within the same file:
ScriptFuncPreloadElement1 # (Within the same file == calling main().)
- This approach separates code definition from execution.
- "Another question with firewall code injection and pre/post hooks is when they should be dispatched. This depends on what functionality you want to implement."
- Example:
if [ "$(type -t firewall_input_hook_end)" = "function" ]; then firewall_input_hook_end fi
- However, this would only allow a single call per hook. Users would need to chain all calls within
whonix_firewall.d
. Perhaps using array variables instead, with code such as:
- However, this would only allow a single call per hook. Users would need to chain all calls within
firewall_input_hook_end[${#firewall_input_hook_end[@]}]=ScriptFuncPreloadElement1
- Users would need to manage the array order appropriately.
- Hooks within the firewall would then iterate through the array at the appropriate execution point.
Reference: (Forum) torrents, and being a good Tor citizen
Solution, part b demonstrates an example set of nftables rules that could be injected within the firewall. (Proof of concept only.)
Reference: (Forum) Favorite (Whonix?) Bash script boilerplate template?
- (Begins) a consolidation of a standard scripting framework.
See Also[edit]

We believe security software like Kicksecure needs to remain Open Source and independent. Would you help sustain and grow the project? Learn more about our 12 year success story and maybe DONATE!