huwfwall is a library to implement complex firewall rules and update them almost-atomically. It is written as includable bash file. * Design goals - terse, programmatic rule description - almost atomic updates of rulesets - check whole rulesets before applying them - print precise errors - support iptables, ip6tables and ebtables * Ruleset definition by example #+begin_src bash #!/bin/bash # include the library source huwfwall.sh # define your ruleset via a function function my_ruleset() { # append a rule # ,- for ipv4 and ipv6 # | ,- to chain input # | | ,- accepting ssh rule 46 input -p tcp --dport ssh -j ACCEPT # create a chain # ,- for ip6tables and ebtables (quite pointless) # | ,- named mychain rule 6e my_chain # jump to that chain from ipv6 chain forward; # chain name in jumps have to be prepended with ${v}_ rule 6 forward -j ${v}_my_chain } # call huwfwall with your ruleset as callback; # note that you can specify multiple rulesets which are tried in order # until one succeeds huwfwall "$1" my_ruleset #+end_src * Usage Make your rule definition executable and call it with one of the following parameters: - install :: Try to install the given rulesets in the specified order until one succeeds - check :: Test all rulesets by inserting there rules into unreference chains - print :: Print all *table commands that would be issued - gc :: Remove all unreferenced rules * Implementation huwfwall creates all rules in versioned, user-defined chains. E.g. instead of creating a rule in INPUT, it is created in 42_input with 42 being the current version. After all user-specified rules are loaded, they are made live by inserting an uncoditional jump to 42_input into the first slot of INPUT. After that old rules are cleared. No matter how long building the ruleset takes due to size and name resolution, the critical period (in which neither old nor new ruleset is fully established) only takes 13 calls to the *tables tools.