{{Header}} __FORCETOC__
{{#seo:
|description=How to refactor the firewall script while ensuring no unintended nftables changes occur.
}}
{{intro|
How to refactor the firewall script while ensuring no unintended nftables changes occur.
}}
= Ensuring nftables Rules Remain Unchanged =
'''1.''' Store the current nftables rules in the file nftables-old
.
{{CodeSelect|code=
sudo nft --stateless list ruleset > nftables-old
}}
'''2.''' Do activities, wait, etc.
'''3.''' Store the current nftables rules in the file nftables-new
.
{{CodeSelect|code=
sudo nft --stateless list ruleset > nftables-new
}}
'''4.''' Compare nftables-old
and nftables-new
.
Use a console diff viewer:
{{CodeSelect|code=
diff nftables-old nftables-new
}}
Or use a graphical diff viewer:
{{CodeSelect|code=
meld nftables-old nftables-new
}}
= Ensuring nftables Rules Remain Unchanged During Firewall Refactoring =
'''1.''' Store the current nftables rules in the file nftables-old
.
{{CodeSelect|code=
sudo nft --stateless list ruleset > nftables-old
}}
'''2.''' Refactor the {{project_name_long}} firewall code.
'''3.''' {{Reload_Firewall}}
'''4.''' Store the current nftables rules in the file nftables-new
.
{{CodeSelect|code=
sudo nft --stateless list ruleset > nftables-new
}}
'''5.''' Compare nftables-old
and nftables-new
.
Use a console diff viewer:
{{CodeSelect|code=
diff nftables-old nftables-new
}}
Or use a graphical diff viewer:
{{CodeSelect|code=
meld nftables-old nftables-new
}}
= systemcheck nftables Test =
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 {{project_name_short}} project can realistically implement.''" (From [https://forums.whonix.org/t/bolt-on-for-whonix-firewall-best-place-to-put-files/2222 (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.
= Splitting the {{project_name_short}} Firewall Script for Better Readability =
''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:
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.