Let's talk firewall rule order ...

Started by Patrick M. Hausen, January 29, 2026, 10:05:39 PM

Previous topic - Next topic
January 29, 2026, 10:05:39 PM Last Edit: January 29, 2026, 10:17:09 PM by Patrick M. Hausen
OK, I just noticed a thing after upgrading to 26.1 and using the new rule interface. I suspect the issue was present in previous versions in the same manner, I just did not notice it.

So rule order watched from the highest level is:

Floating > Interface group > Interface

This is well documented and has not changed ever I could remember. And I use it more or less extensively to get a maintainable structure and a low number of rules.

Floating:



I really do think that blocking ICMP echo is silly, that it's the most important debug tool of all in IP, so I generally allow it, even when other traffic across the same interfaces is forbidden.

Interface groups:

I have one interface group "Internal" which is all my interfaces but WAN and the one to the DSL modems's management interface. I have another group named "Restricted" which is the same as "Internal" but without LAN. These are the interfaces for which I block any "cross talk". LAN after floating and groups applied has a final "allow all" rule just like the default setup.

These are the rules for the "Restricted" group:



This allows essential services to the respective firewall interface plus Internet access to arbitrary services but no access to any other local network. If you look closely you recognise that this set of rules does not yet prohibit e.g. SMTP out to the Internet. It's only "allow" rules, so the first three simply do not match and then the last two still allow DNS, NTP and SMTP outbound.

But I take care of that in the "Internal" group:



Since my LAN is generally "allow all" but I still want to restrict DNS, NTP and SMTP, the block rules for these go into the "Internal" group. Remember, that contains all "Restricted" interfaces plus LAN.

Result:

This works. I just verified by disabling all "Internal" rules - SMTP from a host on a restricted interface to the Internet is open. Enable again - SMTP blocked.

Fine.

My question is: why?

Why are the group rules for the "Internal" group applied before the rules for the "Restricted" group? As is obviously the case? And how can I guarantee a certain order of certain groups, because I want block before allow? Is it the metric system ... er ... alphabetical sorting?

Kind regards,
Patrick
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

January 29, 2026, 10:14:21 PM #1 Last Edit: January 29, 2026, 11:13:06 PM by meyergru
Made me laugh, Patrick, because I have exactly the same distinction between "internal" and "restricted" (this one even with the same name).

As for your question: Look under Firewall: Groups, the interface group have an assigned "sequence" which I believe to determine the order.

Intel N100, 4* I226-V, 2* 82559, 16 GByte, 500 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

January 29, 2026, 10:17:52 PM #2 Last Edit: January 29, 2026, 11:24:22 PM by Patrick M. Hausen
Quote from: meyergru on January 29, 2026, 10:14:21 PMLook under Firewall: Groups, the interface group have an assigned "sequence" which I believe to determine the order.

I never noticed this exists. Bummer! Thanks!

They are both set to 0 - so it's alphabetical or order of creation or whatever, but at least now I know how to force a specific order.

EDIT:

I could not find that in the docs - lowest number wins. All automatic groups (IPsec, OpenVPN, WireGuard) are set to 10 by default, all user created ones to 0.

If I set "Internal" to 1 and "Restricted" to 2, outbound SMTP is still blocked, if I change "Internal" to 3, it's allowed.

*phew* What a rabbit hole :-)
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

Quote from: Patrick M. Hausen on January 29, 2026, 10:17:52 PM*phew* What a rabbit hole :-)

I wonder what percentage of people can still follow what we are talking about here... ;-)

Yet, I had only the typical "Block RESTRICTED to local networks" and "Allow any to internet" rules in the RESTRICTED group, which I switched out for explicit interface rules at some point. Unless you have a large number of VLANs, it seemed more explicit that way to me.
Intel N100, 4* I226-V, 2* 82559, 16 GByte, 500 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

Indeed the sequence order in the groups sets the order of those group rules when inherited into an Interface.

And you are right its not mentioned in docs just slightly hinted in
https://docs.opnsense.org/manual/how-tos/security-zones.html#setup-interface-groups

I have several groups created, cause I look at them as policies, and policies are inherited into Interfaces (I look at them as Zones). So when you do groups its necessarily to consider the sequence order because of

Quotegroups use 300000
This means 300000 + the sequence number in groups

https://docs.opnsense.org/manual/how-tos/security-zones.html#setup-interface-groups

At least that was my interpretation when doing the design.

Regards,
S.
Networking is love. You may hate it, but in the end, you always come back to it.

OPNSense HW
APU2D2 - deceased
N5105 - i226-V | Patriot 2x8G 3200 DDR4 | L 790 512G - VM HA(SOON)
N100   - i226-V | Crucial 16G  4800 DDR5 | S 980 500G - PROD

In my  setup I combining interface groups as security zones (similar Internal/Restricted model) with a multi‑layer DNS stack (dnscrypt‑proxy on localhost, Unbound as validating resolver and AdGuard Home on a separate VLAN), and we've just added Q‑Feeds domain/IP feeds on top.


Being able to control the group rule order via the sequence field is exactly what we need to keep the "global block policies" applied before the more permissive per‑zone rules without exploding the number of interface rules.

Since the sequence field essentially controls policy precedence between interface groups, it might be worth surfacing this more clearly in the UI and docs.
For example, a short note or tooltip like "lower sequence = evaluated earlier (group rules are ordered by 300000 + sequence)" under Firewall → Groups would make it much easier for people using policy‑style groups (Internal/Restricted, IoT/Guest, etc.) to design their rulesets intentionally instead of discovering the behaviour by trial and error.

Quote from: Patrick M. Hausen on January 29, 2026, 10:05:39 PMThese are the rules for the "Restricted" group:

Thank you for sharing.
May I ask what the aliases for the local network IPv4 and IPv6 actually look like?

You cannot view this attachment.

In your opinion, you could also use the interface group restricted itself, something like this
source: restricted net
destination: restricted net ?

Supermicro M11SDV-4C-LN4F AMD EPYC 3151 4x 2.7GHz RAM 8GB DDR4-2666 SSD 250GB

Net4_Local: 192.168.0.0/16
Net6_Local: my static /56 I receive from Deutsche Telekom

What do you mean by that second question? I do not quite understand.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

January 30, 2026, 09:32:56 AM #8 Last Edit: January 30, 2026, 09:41:47 AM by meyergru
I found a problem with how the new rules scheme will be handled with Patrick's approach:

Imagine a typical "Allow any to !RFC1918" rule for any non-privileged VLAN. Actually, it would be better to have "!internal net" instead, which applies to both IPv4 and IPv6, BTW.

In Patrick's and my scheme, you would be tempted to move that to the end of the restricted group rule instead of at the end of each individual interface rules - as is shown in Patricks ruleset above.

However, when you want to make any exception to that general rule, e.g. if you have a monitoring client in one of your restricted networks, you would simply place them before that last interface rule. Since the group rules are prioritized higher, you would have to move such individual rules to the floating section to preceed the group rules if you were to have a general group rule.

As a side note, this has the disadvantage of forcing most of the specific rules to the floating section, although they apply only to one VLAN, which makes things less transparent, but it still works.

However, this scheme breaks once you do the migration to the new rules: Any such specific floating rule that applies to only one interface will move to the interface section, where it now does not preceed the group rules any more and thus does not work.

Therefore, it would still be better to leave the "general" rule in the individual interface rules: It makes things clearer and survives a rule migration.


Somehow I had a hunch that this "one interface only" switch in the new rules scheme would cause problems., because it mixes up the priorities.
Intel N100, 4* I226-V, 2* 82559, 16 GByte, 500 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

I do not have any block rule in the "Restricted" network group. Only allow rules. Keep in mind: "!something" does not imply anything being blocked, only restrict what is allowed. So any additional allow rules per interface of course apply.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

I see. Jumping to conclusions on my side, because I often did that via two rules, one blocking access to "internal net" and one allowing everyting else.
This was easier because you can then use a more concise rule description. But with only one "allow" rule, it works. One must remember to only use allow in the group rules.
Intel N100, 4* I226-V, 2* 82559, 16 GByte, 500 GByte NVME, ZTE F6005

1100 down / 800 up, Bufferbloat A+

But this rule "Allow any to !RFC1918" only allows access to Internet, it doesn't catch RFC1918 to RFC1918.
So an interface based rule will be still applied for RFC1918 to RFC1918.

Regards,
S.
Networking is love. You may hate it, but in the end, you always come back to it.

OPNSense HW
APU2D2 - deceased
N5105 - i226-V | Patriot 2x8G 3200 DDR4 | L 790 512G - VM HA(SOON)
N100   - i226-V | Crucial 16G  4800 DDR5 | S 980 500G - PROD

Quote from: Patrick M. Hausen on January 30, 2026, 09:25:42 AMWhat do you mean by that second question? I do not quite understand.

What I meant was that if I allow everything except my "restricted group net", I don't need to specify separate IPv4 and IPv6 interfaces in an alias. My problem is that I don't have a static IPv6 address from Telekom, even though it admittedly changes very rarely.
Supermicro M11SDV-4C-LN4F AMD EPYC 3151 4x 2.7GHz RAM 8GB DDR4-2666 SSD 250GB

January 30, 2026, 10:14:45 AM #13 Last Edit: January 30, 2026, 10:19:26 AM by RES217AIII
Quote from: meyergru on January 30, 2026, 09:32:56 AMSomehow I had a hunch that this "one interface only" switch in the new rules scheme would cause problems., because it mixes up the priorities.

I created a group with only wan or whatever (that worked). I assigned this group a sequence that took precedence over all other groups, so that it was applied before all other group rules.
Supermicro M11SDV-4C-LN4F AMD EPYC 3151 4x 2.7GHz RAM 8GB DDR4-2666 SSD 250GB

Quote from: RES217AIII on January 30, 2026, 10:06:24 AMWhat I meant was that if I allow everything except my "restricted group net", I don't need to specify separate IPv4 and IPv6 interfaces in an alias.

Those aliases are larger than my locally connected networks. They also apply to some VPN connections for example. And destination invert with multiple objects does not work as one might assume. That's why I have two rules. I don't want to use just "Internal net".
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)