1. Zen IT Technologies
  2. Technical notes
  3. The deny rule that never fires

The deny rule that never fires

Jonny Flaks, Founder & Principal Architect

Technical note in Network & Infrastructure

A control is requested, implemented and evidenced. The rule exists, it is specific, it says deny, and the screenshot went into the audit folder.

It has never matched a packet, and it never will. Not because the rule itself is wrong, but because of what sits above it.

Position is part of the meaning

Ordered firewall policies are evaluated according to the platform's rule-processing model, and an earlier matching rule can determine how traffic is handled before a later rule is ever reached. That mechanic is well understood. Almost nobody gets it wrong when they say it out loud.

What follows from it is easier to miss. A rule's behavior is not a property of the rule. It is a property of the rule and everything above it.

The same rule, with the same source, destination, service and action, can therefore be an enforced control in one position and inert in another. Ordering is semantics rather than housekeeping. Adding, moving or widening another rule can change what the firewall does even though no field inside the affected rule was touched.

This is a particularly dangerous class of firewall error: the intended control can remain fully visible in the configuration while being completely absent from effective behavior. A review based only on looking at that rule can therefore confirm a control the firewall never actually applies.

Three ways a rule stops mattering

Fully shadowed. Everything the rule would match is already matched by something above it, so the lower rule cannot be reached for that traffic. The security effect depends on how the earlier rule handles it. If a specific deny is shadowed by a broader permit, the intended restriction does not take effect. If a lower rule is covered by an earlier rule providing the same effective treatment, the lower rule may instead be redundant.

Partially shadowed. Some of the rule's match space is covered above and some is not. This can be harder to identify because the rule still fires. It has hits. It appears alive in reports based on match counts. But a portion of the traffic it was intended to handle is being processed elsewhere under another rule, action or security profile.

Redundant. The rule is already fully covered by earlier policy providing the same effective treatment. That may be harmless from a traffic-flow perspective, but it still matters. A rulebase carrying rules that do nothing becomes harder to reason about, and teaches administrators that what they are reading is not necessarily what is determining behavior.

The asymmetry worth keeping is that a shadowed permit costs precision, while a deny shadowed by a permit costs the control.

Nothing edited the rule that died

A rule can move from enforced to ineffective without anybody editing the rule itself. A common sequence looks like this. There is an incident. It is out of hours. Something important is broken. A broad permit is inserted higher in the policy to restore service. It works. The incident closes.

Several rules further down is a specific deny that formed the technical basis for a security or compliance requirement. That deny may now be unreachable. Its configuration is byte for byte what it was yesterday. Its source did not change. Its destination did not change. Its service did not change. Its action still says deny. The change that altered its effective behavior happened somewhere else.

There may be no event explicitly telling the administrator that the downstream rule has become unreachable. The policy change itself may be auditable. The subtlety is that the dependent rule's effective state changed indirectly.

Object groups can produce the same effect from another direction. A rule referencing an object group is only as narrow as the current contents of that group. Groups are often edited by somebody thinking about the object being added, not every policy that consumes that object. Adding one address, subnet or service can therefore widen the effective match space of several policies at once. The visible edit occurs in the object. The behavioral change occurs in the rules that reference it.

The edit that changed a rule's behavior was made somewhere other than the rule.

Why reading the list cannot find it

A human reading a policy list naturally reads individual rules. Determining whether a rule is actually reachable requires something different. You have to consider its match space against the effective match space of the rules above it across dimensions such as:

  • source
  • destination
  • service
  • protocol
  • application or identity where applicable
  • referenced object groups

With sixty rules and nested object groups, that quickly stops being a visual-review problem. It becomes a policy-evaluation problem being given to somebody with a scrollbar.

The failure can occur in both directions. A reviewer sees a control that is present in the configuration but ineffective in behavior. At the same time, nobody notices the rule whose behavior changed months earlier because another rule or object was modified.

That is why a periodic firewall review based primarily on reading the configuration can repeatedly miss this problem. The review instrument is not actually testing the behavior it claims to confirm.

Ask the device, do not read the list

The platforms named here provide mechanisms for asking the firewall which policy would handle a particular flow. FortiGate exposes a policy lookup, called the policy match tool in more recent FortiOS. PAN-OS has a security policy match test. Cisco ASA has packet-tracer. The names and the exact scope differ between platforms and between versions, so it is worth checking current vendor documentation for the device in front of you.

The important question is the same in each case. Given this source, destination, port and protocol, which rule would actually handle the traffic? That answer is considerably more useful than looking at the rule you expect to handle it.

Where a platform provides shadowed-rule, redundant-rule or policy-analysis capabilities, those can provide another useful check. Not every firewall exposes the same analysis, and not every one raises an alert when a rule becomes unreachable.

Hit counters can also help, with one important caution. A zero count is only meaningful if you understand the observation period. Counters may have been reset. The device may have rebooted. A genuinely unused rule and a recently reset counter can initially look identical. Where the platform records a meaningful last-used timestamp or equivalent usage information, that can provide additional context.

The check worth running

Name the three firewall rules you would point at if somebody asked how a specific security control is technically enforced. Most environments have a few. They are often deny rules.

For each one, use the platform's policy or packet-match test with traffic that the rule is supposed to catch. Read which rule the firewall says would actually handle the traffic.

If the answer is not the rule you named, stop treating the rule's presence in the configuration as evidence that the control is operating as intended. Then establish what policy or object causes the different match, and when that behavior began. That gives you the period during which the intended control may not have been operating as assumed.

A screenshot proves that a rule exists. It does not prove that a packet can ever reach it.

Companion technical note: Eleven VLANs and one flat network

Explore this expertise: Network & Infrastructure

All technical notes