Skip to content

firewall: add default-policy to policy config v2 - #15944

Closed
lukashino wants to merge 4 commits into
OISF:mainfrom
lukashino:feat/8712-fw-default-policy-v2.2
Closed

firewall: add default-policy to policy config v2#15944
lukashino wants to merge 4 commits into
OISF:mainfrom
lukashino:feat/8712-fw-default-policy-v2.2

Conversation

@lukashino

@lukashino lukashino commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Follow-up of #15942

Add a default-policy setting that applies to all hooks below it. For any hook the most specific setting present wins.
The flat layout had no way to express a default covering only the packet hooks or only the app hooks, so both move under their own node: packet-filter becomes packet.filter and <proto> becomes app.<proto>.
Action scopes are now validated against the hook they reach. A global accept:tx arriving at a packet hook is a startup error instead of being applied silently.

Link to ticket: https://redmine.openinfosecfoundation.org/issues/8712

Describe changes:

  • new suricata.yaml policy config structure
  • policy hook validation and hints
  • multi-layer default policy for firewall policies

SV_BRANCH=OISF/suricata-verify#3252

To consider:
As we changed the config structure for default policies, we can consider adding upgrade checks.
But since the firewall mode is experimental in 8, I avoided any conversion checks from the previous versions to keep the code simpler.

Lukas Sismis added 4 commits July 28, 2026 18:28
AppProtoToString(ALPROTO_HTTP1) returns "http", so an HTTP/1 policy had to
be written as `http:` while its rule hooks were already spelled `http1:`.
Use the same name in both places.

Ticket: 8712
The policy config was a flat map mixing packet hooks and app-layer
protocols: `packet-filter` next to `dns`. There was no node that meant
"the packet hooks" or "the app-layer hooks", so a setting could not be
scoped to one group.

Move each group under its own node:

    packet-filter     -> packet.filter
    packet-pre-flow   -> packet.pre-flow
    packet-pre-stream -> packet.pre-stream
    <proto>.<hook>    -> app.<proto>.<hook>

Ticket: 8712
Every hook has a built-in default policy, but expressing anything other
than the built-in meant naming each hook explicitly. Add a
`default-policy` setting that covers all hooks below it, so unlisted
hooks still get a policy. For any hook the most specific setting present
wins:

    app.<proto>.<sub state>.<hook>
    app.<proto>.<sub state>.default-policy
    app.<proto>.default-policy
    app.default-policy
    default-policy
    built-in

The packet hooks follow the same pattern under `packet`.

Resolution moves into ResolveFirewallPolicy(), which walks the candidate
paths most-specific-first and stops at the first one that is configured.
A path that is present but empty is now a startup error rather than being
treated as unset.

DoParseAppSubStatePolicy() collapses into DoParseAppPolicy() as a sub state
hook only differs by an extra path segment. Path assembly and hook-name
normalisation move to helpers now that both are needed in more places.

Ticket: 8712
Not every action scope means something at every hook: `tx` is app-layer
only, `packet` is packet only. While a policy had to be written per hook
this was self-evident, but a `default-policy` reaches hooks the user never
named, so a single global setting can now arrive somewhere its scope makes
no sense.

Validate the resolved scope against the class of hook it is being applied
to and fail at startup if it does not fit, naming the config path and the
scopes that would be accepted there. A global `accept:tx` is now a startup
error instead of being applied silently at the packet hooks.

Ticket: 8712
@lukashino
lukashino marked this pull request as ready for review July 28, 2026 20:06
@lukashino
lukashino requested a review from jufajardini as a code owner July 28, 2026 20:06
Copilot AI review requested due to automatic review settings July 28, 2026 20:06
@lukashino
lukashino requested review from a team and victorjulien as code owners July 28, 2026 20:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Suricata’s firewall policy configuration (v2) to support hierarchical default-policy inheritance with “most specific wins”, restructures policy keys into packet.* and app.* namespaces, and adds startup-time validation to reject incompatible action scopes reaching a given hook class.

Changes:

  • Introduce hierarchical default-policy resolution for firewall hooks with packet/app subtree scoping.
  • Validate action scopes against the hook class (packet vs app) and emit clearer error hints on invalid scopes.
  • Update example configuration and firewall user guide docs to reflect the new packet / app policy layout.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
suricata.yaml.in Updates the example policy config layout and documents default-policy inheritance behavior.
src/detect.h Adds a small enum to classify firewall policy hook classes (packet vs app) for validation logic.
src/detect-parse.c Implements multi-level policy resolution and scope validation; refactors packet/app policy loading accordingly.
doc/userguide/firewall/firewall-example.rst Updates the HTTP example to the new firewall.policies.app.http1.* structure.
doc/userguide/firewall/firewall-design.rst Documents the new defaults structure, precedence rules, and scope-validation behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/detect-parse.c
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.61702% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.00%. Comparing base (8455efd) to head (ba26069).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #15944      +/-   ##
==========================================
- Coverage   83.03%   83.00%   -0.03%     
==========================================
  Files        1003     1003              
  Lines      276582   276602      +20     
==========================================
- Hits       229647   229602      -45     
- Misses      46935    47000      +65     
Flag Coverage Δ
fuzzcorpus 61.60% <0.00%> (+0.03%) ⬆️
livemode 18.48% <0.00%> (+<0.01%) ⬆️
netns 22.88% <62.41%> (-0.04%) ⬇️
pcap 45.41% <0.00%> (-0.05%) ⬇️
suricata-verify 67.09% <93.61%> (+0.01%) ⬆️
unittests 58.46% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@suricata-qa

Copy link
Copy Markdown

WARNING:

field baseline test %
SURI_TLPR1_stats_chk
.app_layer.flow.ftp_data 824 790 95.87%

Pipeline = 32727

@lukashino

Copy link
Copy Markdown
Contributor Author

follow-up in #15950

@lukashino lukashino closed this Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants