A RULE snippet that said "log": "1" used to sync without logging. NetDefense sent twelve settings of the rule to OPNsense (its identity and enabled flag among them) and dropped the rest without a word. A PREPEND rule had a quieter version of the same problem: it was meant to come before the firewall’s own rules, but on OPNsense 26.7 it landed after them, behind the default “allow LAN to any” rules, so a PREPEND block rule could sit there never deciding anything.
Both are fixed. A RULE snippet can set any field of OPNsense’s rule model, an ALIAS snippet any field of an alias, and PREPEND and APPEND now work inside each OPNsense 26.7 rule section. The release is live: agent 1.23.0, ndcli 1.38.0, the web app and the control plane.
If your snippet files live in git and CI applies them with ndcli or the API, read on. The same file can now behave differently on a firewall, and a few files that were accepted before are refused.
TL;DR
- Any field of a rule or alias can be set, under its OPNsense API name. A field the snippet leaves out is set to OPNsense’s default at every sync.
- PREPEND rules come ahead of the device’s own rules in their section, unless OPNsense refuses to re-save one of those rules. To make room, the device’s own rules can get higher sequence numbers: same order, every move reported.
- At save, values in RULE, ALIAS and UNBOUND snippets must be strings, and every rule needs an
action. Snippets already stored aren’t re-checked. - At sync, a misspelled field fails that rule or alias, and a device on an agent older than 1.23.0 is refused outright when it would apply the snippet only in part.
- The first sync that reaches a firewall after it upgrades to 1.23.0 re-places rules even if no template changed.
What you can set now
Use the field’s name from OPNsense’s API: log, quick, statetype or gateway on a rule, proto, updatefreq or interface on an alias. Which fields exist depends on the OPNsense release each firewall runs. Pulling a rule or alias you built by hand in the OPNsense interface remains the quickest way to see the names and values.
The field contract, the value forms and the full list of result codes are in Snippets; this post covers what changes for you.
Where PREPEND and APPEND rules land
OPNsense 26.7 evaluates rules section by section: floating rules, then interface-group rules, then single-interface rules. NetDefense now orders inside each section: PREPEND rules first, then the device’s own rules, then APPEND rules. Among themselves, PREPEND rules keep their priority order, and so do APPEND rules.
A fresh OPNsense 26.7 has its default LAN allow rules at sequence 1 and 11, so there is often no free number ahead of them. To make room, NetDefense may raise the sequence number of the device’s own rules in that section. It keeps their order, changes nothing else about them, and reports every move in the sync result as a renumbered item with the old and the new number. It never lowers a number and never touches a section that has no PREPEND rule. See Policy Chain for the section order, what position can’t change, and the placement result codes.
A PREPEND block rule can start blocking
If you had a PREPEND rule that blocked traffic the default allow rules already passed, it never decided anything. Now it comes first, so it blocks. That’s the intent of PREPEND, but check such rules before the first sync on 1.23.0.
What changes on your firewalls with the same file
Nothing in these files has to change for the firewalls to change, once the agent is on 1.23.0.
- Fields that used to be dropped now apply.
log,quick,gateway,statetypeand the rest. Takequickseriously: it changes evaluation order, and a quick rule decides as soon as it matches. - Content is declarative. A managed rule or alias is exactly its snippet. A field the snippet doesn’t set goes to OPNsense’s default at every sync. If someone turned on logging by hand in the OPNsense interface, or changed an alias’s refresh interval or categories, the next sync resets it. To keep a setting, put it in the snippet.
sequencein the content is ignored. Placement comes from the template’s position and the snippet’s priority.- The first sync that reaches a firewall after the upgrade re-places rules even if no template changed. A sync of an unchanged configuration is skipped unless you use
--force. PREPEND rules an older agent put after the device’s own rules move ahead of them, with the renumbering above, and hand-made settings on managed rules and aliases reset.
Firewalls installed from the NetDefense repository upgrade the agent along with their OPNsense updates, so there may be no separate moment to prepare. The upgrade note says what to pull and copy into snippets before that update.
What is now refused at save
These checks run when you upload or update a snippet, so a pipeline learns about them immediately. Snippets already stored aren’t re-checked and keep working.
- In
RULE,ALIASandUNBOUND_*snippets, values must be JSON strings. Write"443", not443, and"1"and"0", nottrueandfalse. Exceptions:enabledmay be a string or a boolean, a few other switch fields may also be booleans, an alias’scontentand anUNBOUND_ACL’snetworksmay be lists, and keys that appear only in pulled output take any value. The refusal names the field and the form to write. - Every
RULEneeds a non-emptyaction. OPNsense’s default action is pass, so a rule without one would let traffic through. The refusal reads:content must include a non-empty 'action': OPNsense's default action is pass, so a rule without one would let traffic through. GROUPmembersmust be a list,""ornull. A comma-separated string used to be ignored, and entries that aren’t strings are refused too.
What now fails at sync
Before, an unknown key was ignored. Now it fails.
- Unknown or misspelled keys fail that rule or alias. A
"lgo": "1"givesRULE_FIELD_UNKNOWN(ALIAS_FIELD_UNKNOWNfor an alias), with a “did you mean” hint and the firewall’s OPNsense version. The rest of the sync still applies, and the task endsFAILED. OPNsense adds fields within a release line, so a field can be valid on one 26.7 point release and unknown on an earlier one. - A list value of only blanks or commas is refused.
- An old agent is refused for its whole sync. A device on an agent older than 1.23.0 gets
SNIPPET_AGENT_TOO_OLDwhen its snippet content is something that agent would apply only in part, for example a non-default value in a field it drops. No task is created for that device and nothing reaches it until the agent is upgraded or the snippet edited. A field left at OPNsense’s default doesn’t count.
Upgrade before you add the new fields
Add log, quick or gateway to a snippet only after the firewalls it reaches run 1.23.0. Until then, the firewalls still on an older agent are refused for their whole sync instead of getting a rule that silently lacks the field. See Agent and OPNsense versions.
For automation: ndcli 1.38.0
Exit codes are unchanged. What changes is what the output says, and what you filter on.
- Warnings show ⚠ in every result family. Some warnings, such as a failed package-catalog refresh, used to show ✗.
- New items. A
renumbereditem shows as~with its before and after sequence, and anunchangedrule or alias shows as=.-f jsoncarries the new codes and actions. --organd--oumatch exact names. They always did on the server; the help text used to say regex.--deviceand--templateare unanchored regular expressions, so--device fw-01also syncsfw-010. Anchor a single device as^fw-01$.- Pulled content changed.
ndcli snippet pullnow returns the identifying fields plus every field that differs from OPNsense’s default, as strings, so a diff against a file you stored earlier will show changes.
The flags are in the sync reference and the content contract is in the snippet reference.
Checklist for snippet files in a repository
- Quote every value, apart from
enabledand list-valuedcontentornetworks. - Set
actionon every rule. - Drop
sequence, and any key OPNsense’s model doesn’t have. - Include every non-default setting you rely on. A sync resets the rest.
- Check PREPEND block rules, and rules with
quick, against the order they will now have. - Upgrade agents to 1.23.0 before adding fields that older agents drop.
- Review snippets you pulled with an older agent before upgrading: they hold every field of their source, including ones the old agent ignored, and 1.23.0 applies them all.
- Anchor single-device filters in sync commands as
^name$. - Expect renumbered items in the first sync result after an upgrade. They are the device’s own rules getting higher sequence numbers, in the same order.