Overlapping Interface Groups: firewall group rules processed in alphabetical order(?) of group names - undocumented
-
Nothing in the 2.4.5.p1 UI prevents or warns about adding one interface to multiple interface groups, but the documentation does not describe the order in which the Group rules will be processed, as if the assumption is that an interface will belong to at most one interface group.
By experimentation and examination of the contents of /tmp/rules.debug, it appears that interface group rule-sets appear in alphabetical order following the name of the interface group. For instance, the set of lines for the interface group "Guest_VLANS" appears above the set of lines for the interface group "Isolated_VLANS" because G<I alphabetically. Changing the name "Guest_VLANS" to "JGuest_VLANS" makes the rules appear in the other order because I<J alphabetically.
I think one of the following changes should be made:
(a) Overlapping interface groups should be forbidden by the UI because there is a fundamental problem with them.
(b) UI should allow users to assign a priority number to interface groups (integer 0-255, default 100 or 127), which determines the order the group's rules appear, relative to the rules of other interface groups. Lower numbers appear before higher numbers; groups with the same priority number are processed alphabetically, as they are now (important to prevent any breakage for installations which rely on this fact, perhaps without realizing it).
(c) Document current behavior. Bonus: warn user of alphabetical behavior when adding an interface to its second interface group.
Assuming there is no fundamental underlying problem with overlapping interface groups, one motivation to use them derives from the example names above:
Isolated_VLANS are internet-only VLANS, forbidden by fw rules to access internal hosts (all Private IPs). Guest_VLANS are used by visitors (not staff) and are given low priority by traffic shaping rules.
All Guest_VLANS are Isolated_VLANS, but there exist Isolated_VLANS which are not Guest_VLANS (that is, VLANS with high traffic priority but forbidden from accessing internal hosts).
Yes, all rule sets involving overlapping groups could be implemented with a larger number of non-overlapping groups (proof left as exercise for the reader), but overlapping groups can be conceptually simpler and they avoid the duplication of rules, both of which increase the risk of mistakes during maintenance. The simple example above doesn't seem like a big deal, but start multiplying the number of groups, which aren't always sub-groups like those above, and the number of duplications multiplies unreasonably.
-
Thinking more about this, I don't see use cases for overlapping interface groups when interface group rules have to be "quick" in the pf sense
.
So maybe overlapping groups are just a pitfall that should be forbidden, or at least warned about in the UI.
What would be useful are aliases for groups of interfaces which could be referenced in floating rules, in lieu of manually multi-selecting a group of interfaces, which requires a revision of every rule when adding-dropping one interface from the group. Interface-group aliases would also assign concise meaning to a long list of interfaces when reading a rule. This is actually a more powerful feature than non-quick interface group rules would be.
The Isolated / Guest example I described would be implemented:
Isolated: reject quick to Private_IPs
Guest: pass quick with low-priority queue
Isolated: pass quick with high-priority queueThis handles cases of hosts that are Guests but not Isolated and vice versa. Probably the third rule above would instead be applied to a third group called Non-Guests, so that conceptually "Isolated" means no access to internal resources and "Guest" means restricted traffic priority.
-
@msswift said in Overlapping Interface Groups: firewall group rules processed in alphabetical order(?) of group names - undocumented:
Thinking more about this, I don't see use cases for overlapping interface groups
I'd just like to chime in on this because I have recently been caught out by it.
I have two interface groups that contain (some) common interface members. The first group contains rules that are common to all of my local subnets, the second group contains rules that are common to just two of my subnets. It hadn't even occurred to me to check which order the groups would be processed in and it was only upon observing some of the rules in the second group not working as expected that I realised there was a problem.
I disagree with your statement that there are no use cases for multiple groups. Indeed, if you are careful with your implementation and don't make things too complex/deeply nested, having interfaces in multiple groups can be an extremely powerful and efficient system.
You state that there are pitfalls in such a setup, I assume you're talking about conflicting rules across multiple groups (please let me know if you have other pitfalls in mind) but this particular example could occur when using just a single group anyway.
Now I've realised this is going on I'm going to rename my higher tier group to ensure its rules are processed first, but I think it would be handy to either:
a) allow assigning a priority value to groups in order to manually enforce rule order
or
b) allow adding interface groups to groupsActually, in my setup I'd prefer option b) as my group nesting is hierarchical with the intended rule processing thus:
1 - Group A rules (interfaces 1, 2, 3, 4, 5)
2 - Group B rules (interaces 1 and 2)
3 - Individual interface rulesIf I could make interfaces 1 and 2 members of Group B and then make Group B a member of Group A, the rule processing order would be implicit.
That's my take anyway.
-
@reg_ed I haven't gone back and confirmed, but if the alphabetical order isn't a direct consequence of the way pf processes wildcard anchors such as 'spam/*' then it's a default chosen for consistency with it. I think implementing (a) or (b) woudn't be very hard, everything's in PHP and seems nicely "clean" to me, but there's significant overhead to getting a sufficiently firm grasp of pf, how pfsense is using it, how it's all coded up, setting up a dev environment and machine.... Literally today I'm about to pull an old Alix board out of a drawer just so I can experiment to fill in the gaps of BSD documentation, which is well written but sparse on details.
As I've dug deeper in pfsense, I've found several places where the conceptual overlay of pfsense onto underlying BSD tools breaks down without warning (documentation). I have a few posts in these forums I need to follow up on, but what I've learned is that to answer questions I have about pfsense behavior, look under the hood, rather than expect pfsense to make sense as itself. Besides this issue of interface groups, there is no positive concept in BSD dhcpd of 'no gateway' (dhcp option 3) and the pfsense 'none' flag is permitted in pools, where it (and other pfsense dhcp concepts) get into conceptual trouble with inheritance. And floating rules 'out' on WAN work nothing like expected, and yet 'both' rules work like 'out' rules should (plus a superfluous 'in' direction) which has got to be a contributing factor to why floating rules have a reputation as confusing and hard to get right.