From b54f462272c3a68a1a733a9037dc7c109c54499d Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 7 Feb 2022 11:08:20 +0100 Subject: [PATCH] fw4: parse traffic rules before forwarding rules Parse traffic rules before inter-zone-forwarding rules to ensure that those rules end up in the correct order within the rendered ruleset. Traffic rules must preceede zone forwarding rules, like they did in firewall3. Fixes: FS#4258 Signed-off-by: Jo-Philipp Wich --- root/usr/share/ucode/fw4.uc | 10 +- tests/01_configuration/02_rule_order | 232 +++++++++++++++++++++++++++ 2 files changed, 237 insertions(+), 5 deletions(-) create mode 100644 tests/01_configuration/02_rule_order diff --git a/root/usr/share/ucode/fw4.uc b/root/usr/share/ucode/fw4.uc index 932637e..eeef02e 100644 --- a/root/usr/share/ucode/fw4.uc +++ b/root/usr/share/ucode/fw4.uc @@ -661,18 +661,18 @@ return { // - // Build list of forwardings + // Build list of rules // - this.cursor.foreach("firewall", "forwarding", f => self.parse_forwarding(f)); + map(filter(this.state.ubus_rules, r => (r.type == "rule")), r => self.parse_rule(r)); + this.cursor.foreach("firewall", "rule", r => self.parse_rule(r)); // - // Build list of rules + // Build list of forwardings // - map(filter(this.state.ubus_rules, r => (r.type == "rule")), r => self.parse_rule(r)); - this.cursor.foreach("firewall", "rule", r => self.parse_rule(r)); + this.cursor.foreach("firewall", "forwarding", f => self.parse_forwarding(f)); // diff --git a/tests/01_configuration/02_rule_order b/tests/01_configuration/02_rule_order new file mode 100644 index 0000000..1a94495 --- /dev/null +++ b/tests/01_configuration/02_rule_order @@ -0,0 +1,232 @@ +Testing that `config rule` rules are rendered before `config forwarding` ones +and that rules are rendered in the order they're declared. + +-- Testcase -- +{% + include("./root/usr/share/firewall4/main.uc", { + TRACE_CALLS: "stderr", + + getenv: function(varname) { + switch (varname) { + case 'ACTION': + return 'print'; + } + } + }) +%} +-- End -- + +-- File uci/helpers.json -- +{} +-- End -- + +-- File uci/firewall.json -- +{ + "zone": [ + { + "name": "lan", + "network": "lan", + "auto_helper": 0 + }, + { + "name": "wan", + "network": "wan", + "auto_helper": 0 + } + ], + "forwarding": [ + { + "src": "lan", + "dest": "wan" + } + ], + "rule": [ + { + "name": "Deny rule #1", + "proto": "any", + "src": "lan", + "dest": "wan", + "src_ip": [ "192.168.1.2" ], + "target": "drop" + }, + { + "name": "Deny rule #2", + "proto": "icmp", + "src": "lan", + "dest": "wan", + "src_ip": [ "192.168.1.3" ], + "target": "drop" + } + ] +} +-- End -- + +-- Expect stdout -- +table inet fw4 +flush table inet fw4 + +table inet fw4 { + # + # Set definitions + # + + + # + # Defines + # + + define lan_devices = { "br-lan" } + define lan_subnets = { 10.0.0.0/24, 192.168.26.0/24, 2001:db8:1000::/60, fd63:e2f:f706::/60 } + define wan_devices = { "eth1" } + define wan_subnets = { 10.11.12.0/24 } + + # + # User includes + # + + include "/etc/nftables.d/*.nft" + + + # + # Filter rules + # + + chain input { + type filter hook input priority filter; policy drop; + + iifname "lo" accept comment "!fw4: Accept traffic from loopback" + + ct state established,related accept comment "!fw4: Allow inbound established and related flows" + iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic" + iifname "eth1" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic" + } + + chain forward { + type filter hook forward priority filter; policy drop; + + ct state established,related accept comment "!fw4: Allow forwarded established and related flows" + iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic" + iifname "eth1" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic" + } + + chain output { + type filter hook output priority filter; policy drop; + + oifname "lo" accept comment "!fw4: Accept traffic towards loopback" + + ct state established,related accept comment "!fw4: Allow outbound established and related flows" + oifname "br-lan" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic" + oifname "eth1" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic" + } + + chain handle_reject { + meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic" + reject with icmpx type port-unreachable comment "!fw4: Reject any other traffic" + } + + chain input_lan { + jump drop_from_lan + } + + chain output_lan { + jump drop_to_lan + } + + chain forward_lan { + ip saddr 192.168.1.2 counter jump drop_to_wan comment "!fw4: Deny rule #1" + meta l4proto icmp ip saddr 192.168.1.3 counter jump drop_to_wan comment "!fw4: Deny rule #2" + jump accept_to_wan comment "!fw4: Accept lan to wan forwarding" + jump drop_to_lan + } + + chain drop_from_lan { + iifname "br-lan" counter drop comment "!fw4: drop lan IPv4/IPv6 traffic" + } + + chain drop_to_lan { + oifname "br-lan" counter drop comment "!fw4: drop lan IPv4/IPv6 traffic" + } + + chain input_wan { + jump drop_from_wan + } + + chain output_wan { + jump drop_to_wan + } + + chain forward_wan { + jump drop_to_wan + } + + chain accept_to_wan { + oifname "eth1" counter accept comment "!fw4: accept wan IPv4/IPv6 traffic" + } + + chain drop_from_wan { + iifname "eth1" counter drop comment "!fw4: drop wan IPv4/IPv6 traffic" + } + + chain drop_to_wan { + oifname "eth1" counter drop comment "!fw4: drop wan IPv4/IPv6 traffic" + } + + + # + # NAT rules + # + + chain dstnat { + type nat hook prerouting priority dstnat; policy accept; + } + + chain srcnat { + type nat hook postrouting priority srcnat; policy accept; + } + + + # + # Raw rules (notrack & helper) + # + + chain raw_prerouting { + type filter hook prerouting priority raw; policy accept; + } + + chain raw_output { + type filter hook output priority raw; policy accept; + } + + + # + # Mangle rules + # + + chain mangle_prerouting { + type filter hook prerouting priority mangle; policy accept; + } + + chain mangle_postrouting { + type filter hook postrouting priority mangle; policy accept; + } + + chain mangle_input { + type filter hook input priority mangle; policy accept; + } + + chain mangle_output { + type filter hook output priority mangle; policy accept; + } + + chain mangle_forward { + type filter hook forward priority mangle; policy accept; + } +} +-- End -- + +-- Expect stderr -- +[call] ctx.call object method args +[call] ctx.call object method args <{ "type": "firewall" }> +[call] fs.open path mode +[call] fs.popen cmdline mode +-- End -- -- 2.30.2