From 38a6069fbb86573258bcef746313f9273cab751f Mon Sep 17 00:00:00 2001 From: Andris PE Date: Wed, 29 May 2024 19:59:51 +0000 Subject: [PATCH 1/3] ruleset: make synflood lighter using ct meta Make synflood inteject as found in default setup quicker by using ct state attribute and avoiding packet data examination. Bytecode before: ``` // block A implicit [ meta load l4proto => reg 1 ] [ cmp eq reg 1 0x00000006 ] // block B V1 [ payload load 1b @ transport header + 13 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x00000017 ) ^ 0x00000000 ] [ cmp eq reg 1 0x00000002 ] // verdict [ immediate reg 0 jump -> syn_flood ] ``` After: ``` // block B V2 [ ct load state => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x00000008 ) ^ 0x00000000 ] [ cmp neq reg 1 0x00000000 ] // block A explicit [ meta load l4proto => reg 1 ] [ cmp eq reg 1 0x00000006 ] // verdict [ immediate reg 0 jump -> syn_flood ] ``` --- root/usr/share/firewall4/templates/ruleset.uc | 2 +- tests/01_configuration/01_ruleset | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/root/usr/share/firewall4/templates/ruleset.uc b/root/usr/share/firewall4/templates/ruleset.uc index 2bec4d9..11a2c9f 100644 --- a/root/usr/share/firewall4/templates/ruleset.uc +++ b/root/usr/share/firewall4/templates/ruleset.uc @@ -117,7 +117,7 @@ table inet fw4 { {% fw4.includes('chain-prepend', 'input') %} ct state vmap { established : accept, related : accept{% if (fw4.default_option("drop_invalid")): %}, invalid : drop{% endif %} } comment "!fw4: Handle inbound flows" {% if (fw4.default_option("synflood_protect") && fw4.default_option("synflood_rate")): %} - tcp flags & (fin | syn | rst | ack) == syn jump syn_flood comment "!fw4: Rate limit TCP syn packets" + ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" {% endif %} {% for (let rule in fw4.rules("input")): %} {%+ include("rule.uc", { fw4, zone: null, rule }) %} diff --git a/tests/01_configuration/01_ruleset b/tests/01_configuration/01_ruleset index 108dff9..a9ac327 100644 --- a/tests/01_configuration/01_ruleset +++ b/tests/01_configuration/01_ruleset @@ -113,7 +113,7 @@ table inet fw4 { iif "lo" accept comment "!fw4: Accept traffic from loopback" ct state vmap { established : accept, related : accept } comment "!fw4: Handle inbound flows" - tcp flags & (fin | syn | rst | ack) == syn jump syn_flood comment "!fw4: Rate limit TCP syn packets" + ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic" iifname "pppoe-wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic" jump handle_reject From aeb6cac0e9fe83fb08dd5de39eddb34c7bc62e37 Mon Sep 17 00:00:00 2001 From: Andris PE Date: Sat, 1 Jun 2024 18:49:15 +0300 Subject: [PATCH 2/3] Relocate rule to drop unneeded packets asap Somewhat similar to PR22 to discard packets as soon as it is known they need to be discarded. Proto first not viable in this place --- root/usr/share/firewall4/templates/ruleset.uc | 6 +++--- tests/01_configuration/01_ruleset | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/root/usr/share/firewall4/templates/ruleset.uc b/root/usr/share/firewall4/templates/ruleset.uc index 11a2c9f..8540193 100644 --- a/root/usr/share/firewall4/templates/ruleset.uc +++ b/root/usr/share/firewall4/templates/ruleset.uc @@ -116,9 +116,6 @@ table inet fw4 { {% fw4.includes('chain-prepend', 'input') %} ct state vmap { established : accept, related : accept{% if (fw4.default_option("drop_invalid")): %}, invalid : drop{% endif %} } comment "!fw4: Handle inbound flows" -{% if (fw4.default_option("synflood_protect") && fw4.default_option("synflood_rate")): %} - ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" -{% endif %} {% for (let rule in fw4.rules("input")): %} {%+ include("rule.uc", { fw4, zone: null, rule }) %} {% endfor %} @@ -437,6 +434,9 @@ table inet fw4 { chain mangle_input { type filter hook input priority mangle; policy accept; {% fw4.includes('chain-prepend', 'mangle_input') %} +{% if (fw4.default_option("synflood_protect") && fw4.default_option("synflood_rate")): %} + ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" +{% endif %} {% for (let rule in fw4.rules("mangle_input")): %} {%+ include("rule.uc", { fw4, zone: null, rule }) %} {% endfor %} diff --git a/tests/01_configuration/01_ruleset b/tests/01_configuration/01_ruleset index a9ac327..d748cc0 100644 --- a/tests/01_configuration/01_ruleset +++ b/tests/01_configuration/01_ruleset @@ -113,7 +113,6 @@ table inet fw4 { iif "lo" accept comment "!fw4: Accept traffic from loopback" ct state vmap { established : accept, related : accept } comment "!fw4: Handle inbound flows" - ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic" iifname "pppoe-wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic" jump handle_reject @@ -274,6 +273,7 @@ table inet fw4 { chain mangle_input { type filter hook input priority mangle; policy accept; + ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" } chain mangle_output { From c3f104f754aeb828dd82be33eba9fd3199f0c83e Mon Sep 17 00:00:00 2001 From: Andris PE Date: Wed, 5 Jun 2024 11:49:04 +0300 Subject: [PATCH 3/3] Revert "Relocate rule to drop unneeded packets asap" quite dumb to add extra checks before mainstream state plays This reverts commit aeb6cac0e9fe83fb08dd5de39eddb34c7bc62e37. --- root/usr/share/firewall4/templates/ruleset.uc | 6 +++--- tests/01_configuration/01_ruleset | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/root/usr/share/firewall4/templates/ruleset.uc b/root/usr/share/firewall4/templates/ruleset.uc index 8540193..11a2c9f 100644 --- a/root/usr/share/firewall4/templates/ruleset.uc +++ b/root/usr/share/firewall4/templates/ruleset.uc @@ -116,6 +116,9 @@ table inet fw4 { {% fw4.includes('chain-prepend', 'input') %} ct state vmap { established : accept, related : accept{% if (fw4.default_option("drop_invalid")): %}, invalid : drop{% endif %} } comment "!fw4: Handle inbound flows" +{% if (fw4.default_option("synflood_protect") && fw4.default_option("synflood_rate")): %} + ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" +{% endif %} {% for (let rule in fw4.rules("input")): %} {%+ include("rule.uc", { fw4, zone: null, rule }) %} {% endfor %} @@ -434,9 +437,6 @@ table inet fw4 { chain mangle_input { type filter hook input priority mangle; policy accept; {% fw4.includes('chain-prepend', 'mangle_input') %} -{% if (fw4.default_option("synflood_protect") && fw4.default_option("synflood_rate")): %} - ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" -{% endif %} {% for (let rule in fw4.rules("mangle_input")): %} {%+ include("rule.uc", { fw4, zone: null, rule }) %} {% endfor %} diff --git a/tests/01_configuration/01_ruleset b/tests/01_configuration/01_ruleset index d748cc0..a9ac327 100644 --- a/tests/01_configuration/01_ruleset +++ b/tests/01_configuration/01_ruleset @@ -113,6 +113,7 @@ table inet fw4 { iif "lo" accept comment "!fw4: Accept traffic from loopback" ct state vmap { established : accept, related : accept } comment "!fw4: Handle inbound flows" + ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic" iifname "pppoe-wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic" jump handle_reject @@ -273,7 +274,6 @@ table inet fw4 { chain mangle_input { type filter hook input priority mangle; policy accept; - ct state new meta l4proto tcp jump syn_flood comment "!fw4: Rate limit TCP syn packets" } chain mangle_output {