From be0b18930f36f9ec198c688fd0bcbdb646f7a593 Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Mon, 2 Oct 2023 14:36:28 +0200 Subject: [PATCH] Firewall: Rules: Floating - add "Interface / Invert" to the list, which will invert the "on" clause of the rule. To prevent future tickets when selecting multiple interfaces and invert, we'll add a validation to only allow single inverts. When multiple interfaces are selected, these will render into separate rules in which case it might not be clear what the outcome would be, specifically when choosing something else than "pass" (pass lan,wan would lead to two rules which match either lan or wan, block lan, wan would lead to random behavior for example). For https://github.com/opnsense/core/issues/6902 --- .../app/library/OPNsense/Firewall/Rule.php | 3 +++ src/www/firewall_rules.php | 9 +++++++- src/www/firewall_rules_edit.php | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/opnsense/mvc/app/library/OPNsense/Firewall/Rule.php b/src/opnsense/mvc/app/library/OPNsense/Firewall/Rule.php index 079ba63c9..6c834459e 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Firewall/Rule.php +++ b/src/opnsense/mvc/app/library/OPNsense/Firewall/Rule.php @@ -326,6 +326,9 @@ abstract class Rule */ protected function parseInterface($value, $prefix = "on ", $suffix = "") { + if (!empty($this->rule['interfacenot'])) { + $prefix = "{$prefix} ! "; + } if (empty($value)) { return ""; } elseif (empty($this->interfaceMapping[$value]['if'])) { diff --git a/src/www/firewall_rules.php b/src/www/firewall_rules.php index 31a27baed..413e190a6 100644 --- a/src/www/firewall_rules.php +++ b/src/www/firewall_rules.php @@ -757,12 +757,17 @@ $( document ).ready(function() { if (empty($ifgroups) && $rule->ruleOrigin() == 'group'){ // group view, skip group section (groups can't be nested) $is_selected = false; - } elseif ($rule->getInterface() == $selected_if) { + } elseif ($rule->getInterface() == $selected_if && empty($rule->getRawRule()['interfacenot'])) { // interface view and this interface is selected $is_selected = true; } elseif ($selected_if == "FloatingRules" && $rule->ruleOrigin() == 'floating') { // floating view, skip floating $is_selected = false; + } elseif (!empty($rule->getRawRule()['interfacenot'])) { + // inverted interface, all but selected + if (!in_array($selected_if, explode(',', $rule->getInterface()))) { + $is_selected = true; + } } elseif (($rule->getInterface() == "" || strpos($rule->getInterface(), ",") !== false) && $selected_if == "FloatingRules") { // floating type of rule and "floating" view $is_selected = true; @@ -832,6 +837,7 @@ $( document ).ready(function() { + getRawRule()['interfacenot']) ? '!' : '';?> @@ -970,6 +976,7 @@ $( document ).ready(function() { + diff --git a/src/www/firewall_rules_edit.php b/src/www/firewall_rules_edit.php index 1324f65b5..ed03e85cc 100644 --- a/src/www/firewall_rules_edit.php +++ b/src/www/firewall_rules_edit.php @@ -102,6 +102,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { 'gateway', 'icmptype', 'icmp6-type', + 'interfacenot', 'interface', 'ipprotocol', 'log', @@ -217,6 +218,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); + if (!empty($pconfig['interfacenot']) && ( + (is_array($pconfig['interface']) && count($pconfig['interface']) != 1 ) || empty($pconfig['interface'])) + ) { + $input_errors[] = gettext("Inverting interfaces is only allowed for single targets to avoid mis-interpretations"); + } + if ($pconfig['ipprotocol'] == "inet46" && !empty($pconfig['gateway'])) { $input_errors[] = gettext("You can not assign a gateway to a rule that applies to IPv4 and IPv6"); } @@ -475,6 +482,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } } + $filterent['interfacenot'] = !empty($pconfig['interfacenot']); + // allow 0 in adaptive timeouts if (is_numericint($pconfig['adaptivestart']) && is_numericint($pconfig['adaptiveend'])) { $filterent['adaptivestart'] = $pconfig['adaptivestart']; @@ -851,6 +860,20 @@ include("head.inc"); + + + + + /> + + + + +