Skip to main content
RunBook Academy

OPNsenseX · Aliases and Floating RulesAliases and floating rules

Floating rule direction and quick — order, shadowing and intent

Intermediate⏱ ~13 minpfctl

What you'll learn

  • Describe the direction options on a floating rule and their evaluation effect
  • Choose quick vs non-quick deliberately for a floating rule
  • Explain pre-sequence and post-sequence positioning and when each applies
  • Diagnose shadowing and ordering problems in the generated ruleset

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14

Not yet marked complete on this device.

A floating rule is a multi-interface rule. Its power comes from three knobs that per-interface rules do not expose: Direction (in/out/any), Quick (stop-on-match vs continue), and Sequence (pre-sequence vs default vs post-sequence). The combination of these determines where in the generated ruleset the rule injects and how it interacts with the per-interface rules around it. Misuse of any of them produces shadowing — a rule whose match is silently overridden by another rule above it.

This lesson covers each knob in depth and the production traps that follow from misuse.

Direction: in, out, any

The Direction field on a floating rule is the most distinctive. It determines which packets on the listed interface(s) the rule matches.

  • In. Match packets arriving on the listed interface(s), regardless of destination.
  • Out. Match packets leaving on the listed interface(s), regardless of source.
  • Any. Match packets in either direction on the listed interface(s).

The default Direction is in. Most floating rules are inbound, which matches how per-interface rules are framed.

Read-only / Safepfctl -s rules (direction)
$ pfctl -s rules | grep -E 'quick on igb1'
@110 block drop in quick on igb1 inet all
@115 pass out quick on igb1 inet all

Illustrative output

A common floating rule use case that exploits direction: a rule with Interface(s): any, Direction: in matches every packet entering any interface. The same rule with Direction: out matches every packet leaving any interface. The Direction is what distinguishes them.

Quick: stop-on-match vs continue

The Quick toggle is the same as on per-interface rules, but the implications for floating rules are different.

A floating rule with quick and a broad match shadowing a per-interface rule is the most common floating-rule mistake. The floating rule, because it injects at multiple interfaces, can match packets that a specific per-interface rule below was meant to handle.

A floating rule without quick does not decide; evaluation continues. This is the basis of two useful patterns:

  • Log-only floating rules. A floating rule with action pass (or match), quick disabled, and logging enabled.
  • Tag-based rules. A floating rule that adds a tag (match tag <name>) to packets matching its criteria.
Read-only / Safepfctl -s rules (log-only)
$ pfctl -s rules | grep -E '@92[0-9]|@93[0-9]'
@920 match in on igb0 inet proto tcp from any to any port = 22
@925 pass in quick on igb0 inet proto tcp from <management_ips> to any port = 22
@930 pass in quick on igb0 inet proto tcp from any to any port = 22

Illustrative output

Sequence: pre, default, post

The Sequence field controls the relative position of the floating rule’s injection points. Three options:

  • Pre-sequence. The floating rule is injected at the very top of the per-interface ruleset, before any per-interface rule.
  • Default (no explicit sequence). The floating rule is injected in its GUI list order, relative to other rules in the floating rules list.
  • Post-sequence. The floating rule is injected at the very bottom of the per-interface ruleset, after every per-interface rule.

The pre-sequence position is for rules that must apply before any interface logic. The post-sequence position is for rules that should evaluate only if no per-interface rule matched.

How floating rules interact with per-interface rules

The generated ruleset interleaves floating rules and per-interface rules in the position determined by GUI ordering and sequence. The full evaluation order for a packet on a given interface is:

  1. Pre-sequence floating rules that include the interface.
  2. Per-interface rules on the interface, in GUI order.
  3. Default-position floating rules that include the interface, in their GUI list order.
  4. Post-sequence floating rules that include the interface.
  5. The implicit default block at the bottom.

For each rule, first-match-wins applies (assuming quick is enabled, which it is by default). The packet is evaluated against this ordered list, and the first rule that matches decides.

Shadowing traps

Three shadowing patterns appear in production:

  • Pre-sequence broad permit. A pre-sequence floating rule that permits any → any on every interface.
  • Floating rule above a more specific per-interface block. A floating rule that permits LAN → any is above a per-interface block on LAN for LAN → 10.0.0.0/8.
  • Log-only floating rule with a too-narrow match. A log-only rule that does not match the packets the operator expected to see.

The verification step is always the same: pfctl -s rules shows the generated ruleset; pfctl -s state shows the live matches; a targeted test packet shows what the firewall actually did.

Quick reference

KnobOptionsEffect
DirectioninMatch packets arriving on the listed interface(s)
DirectionoutMatch packets leaving on the listed interface(s)
DirectionanyMatch packets in either direction
QuickenabledStop evaluation on match (first-match-wins)
QuickdisabledContinue evaluation; last matching rule decides
SequencepreInject before per-interface rules on the listed interfaces
SequencedefaultInject in GUI list order, intermixed with per-interface rules
SequencepostInject after per-interface rules on the listed interfaces

Production patterns

Three patterns show up repeatedly:

Global anti-spoof at pre-sequence

A pre-sequence floating rule that blocks RFC 1918 sources from arriving on the WAN.

Logging at post-sequence

A post-sequence floating rule with match action and logging enabled. Every packet that reached post-sequence (i.e. no per-interface rule matched) generates a log entry.

Multi-interface service rule at default

A default-position floating rule permitting SSH from management IPs on LAN, DMZ, and GUEST.

Summary

  • Direction (in/out/any) determines which packets on the listed interface(s) the floating rule matches.
  • Quick stops evaluation on match. Non-quick floating rules are useful for log-only and tag-based patterns.
  • Sequence (pre/default/post) controls the relative position of the rule’s injection point.
  • Pre-sequence floating rules evaluate first; post-sequence last; default in GUI order.
  • Shadowing happens when a floating rule matches broadly above a more specific rule.
  • A config apply triggered by a floating-rule change resets the state table.

Knowledge check · 4 questions

  1. Q1. You need a floating rule that records every packet arriving on any interface that does not match a per-interface rule, without affecting the decision. Which configuration is correct?

  2. Q2. A pre-sequence floating rule with quick enabled that permits any traffic from any source to any destination on every interface is a safe default for a production firewall.

  3. Q3. Which of the following are valid uses of the Direction field on a floating rule? Select all that apply.

  4. Q4. You add a default-position floating rule that permits HTTPS from any source on the LAN interface. Below it on the LAN interface rules list is a per-interface block for HTTPS from a specific source subnet. The block never matches. What is the most likely explanation?

Passing score: 75%. Answers are checked in this browser.