new copy action bug with address conversion
-
Hi there,
just noticed in the 2.7-dev tests and checked back: seems also to hit 22.09/11 dev snapshots and even 22.05:
If one copies a rule to another interface with the new copy action button and hits
Enable Interface Address/Net conversion
, then a rule with destinationXY address
will get translated toYZ net
instead ofYZ address
. After copying and redirecting to the YZ interface tab, both source and destination arenet
instead of destination beingaddress
.copy
paste
-
In addition, there's another related "bug" or better called glitch:
as all rules are copied at the same time and instantly and the "tracker ID" of the rules is a derivation of a time() call, all rules created/copied that way share the same tracker ID and such have wrong states/bytes information in front of them. You have to edit them one by one and simply "save" over, so that every one gets a new tracker ID (with now() as timestamp) and thus get a unique tracking id for firewall rules and state analasys.
Just wanted to add that as it can be quite confusing and as the new copy feature introduced in 22.05 is a big hit with our clients, that got quite a few confused looks from the firewall staff when trying to troubleshoot rulesets
As a quick fix I'd try to simply count how much rules are getting copyied with the function, call now() or time() within PHP and just add +1 for every rule created so the trackerID is unique again. I think it was timestamp in miliseconds so the +1 should do no harm as no human can click that fast to hit the other numbers even when creating 20-30 rules in a row
-
quick correction: editing a rule doesn't change its tracking ID, you'd have to duplicate, save, delete the old one to "fix" the duplicacte ID problem.
-
I guess the problem is potentially here in
firewall_rules.php
. I'm missing a rewriting to "address" instead of "network" here.
Also all the rules - if multiple are selected - get the same(int)microtime(true)
.
An additional array_cnt of the$_POST['rule']
would be easy to add, then if >1 simply add +1 to microtime every time the foreach hits.} elseif (isset($_POST['dstif']) && !empty($_POST['dstif']) && isset($iflist[$_POST['dstif']]) && have_ruleint_access($_POST['dstif']) && is_array($_POST['rule']) && count($_POST['rule'])) { $confiflist = get_configured_interface_list(); foreach ($_POST['rule'] as $rulei) { $filterent = $a_filter[$rulei]; $filterent['tracker'] = (int)microtime(true); $filterent['interface'] = $_POST['dstif']; if ($_POST['convertif'] && ($if != $_POST['dstif']) && in_array($_POST['dstif'], $confiflist)) { if (isset($filterent['source']['network']) && ($filterent['source']['network'] == $if)) { $filterent['source']['network'] = $_POST['dstif']; } if (isset($filterent['destination']['network']) && ($filterent['destination']['network'] == $if)) { $filterent['destination']['network'] = $_POST['dstif']; } if (isset($filterent['source']['network']) && ($filterent['source']['network'] == ($if . 'ip'))) { $filterent['source']['network'] = $_POST['dstif'] . $ip; } if (isset($filterent['destination']['network']) && ($filterent['destination']['network'] == ($if . 'ip'))) { $filterent['destination']['network'] = $_POST['dstif'] . $ip; } } $a_filter[] = $filterent; } if (write_config(gettext("Firewall: Rules - copying selected firewall rules."))) { mark_subsystem_dirty('filter'); } header("Location: firewall_rules.php?if=" . htmlspecialchars($_POST['dstif'])); exit; }