Skip to content

opnsense: add new integration for OPNsense firewall logs - #21272

Open
TocharianOU wants to merge 4 commits into
elastic:mainfrom
TocharianOU:add-opnsense-integration
Open

TocharianOU wants to merge 4 commits into
elastic:mainfrom
TocharianOU:add-opnsense-integration

Conversation

@TocharianOU

@TocharianOU TocharianOU commented Sep 15, 2026

Copy link
Copy Markdown

Proposed commit message

OPNsense is an open-source firewall and routing platform based on FreeBSD. This repository ships a pfsense integration but has nothing for OPNsense.

One log data stream collecting filterlog events — the packet filter decisions made by pf — over syslog, with udp, tcp and logfile inputs.

The filterlog body is CSV whose column layout is not fixed:

  • It changes with the IP version. IPv4 carries tos, ecn, ttl, id, offset, flags and reports the protocol as number, name; IPv6 carries class, flow, hoplimit and reverses those two columns to name, number.
  • It then changes again with the protocol. TCP appends flags, sequence and acknowledgment numbers, window, urgent pointer and options; UDP stops after the payload length; ICMP switches to key=value pairs.

The pipeline parses this positionally in a single script rather than as a stack of grok alternatives, which keeps the column order documented in one place. opnsense.log.tcp.flags is worth calling out: it distinguishes an ordinary SYN connection attempt from an ACK scan.

Checklist

  • I have reviewed tips for building integrations and this pull request is aligned with them.
  • I have verified that all data streams collect metrics or logs.
  • I have added an entry to my package's changelog.yml file.
  • I have verified that Kibana version constraints are current according to guidelines.
  • I have verified that any added dashboard complies with Kibana's Dashboard good practices

Author's Checklist

  • Please confirm the owning team. .github/CODEOWNERS and owner.github both name @elastic/security-service-integrations, with owner.type: community. If another team should own it, I will update both.
  • Please confirm source.license: Apache-2.0 is acceptable — the same question as on crowdsec: add new integration for CrowdSec alerts #21270.
  • The changelog.yml link points at this pull request.
  • /review-integration from elastic/integration-skills has been run and its findings addressed.

How to test this PR locally

cd packages/opnsense
elastic-package format --fail-fast
elastic-package check
elastic-package test pipeline
elastic-package test script

The pipeline test fixtures are captured syslog from a live OPNsense 26.7, covering both IP versions, the match and ip-option reasons, and tcp, udp, icmp and ipv6-icmp. A second fixture covers the branches the capture did not reach: IPv4 and IPv6 TCP with a FIN/PSH/URG flag combination, non-filterlog messages from the same syslog stream, RFC 3164 framing, and a line with no syslog header. A script test covers corrupt source and destination address columns.

To exercise it end to end, in the OPNsense UI go to System → Settings → Logging / targets, add a target pointing at the agent's listener with Applications including filter, and make sure the rules you want to observe have logging enabled.

Related issues

Screenshots

The package ships the [Logs OPNsense] Firewall activity dashboard: traffic volume and block rate, activity over time by action and by interface, a port-over-time heatmap where a port sweep reads as a vertical stripe, TCP flag distribution, interface-by-action and protocol-by-direction nested donuts, rule hit ranking, top talkers, and a source map. Screenshots are included in the package under img/.

@TocharianOU
TocharianOU requested a review from a team as a code owner September 15, 2026 14:43
OPNsense is an open-source firewall and routing platform based on FreeBSD. This
repository ships a pfSense integration but has nothing for OPNsense, which is
the more common choice among European operators.

One `log` data stream collecting filterlog events over syslog, with udp, tcp and
logfile inputs.

The filterlog body is CSV whose column layout is not fixed. It changes with the
IP version - IPv6 carries class, flow and hoplimit where IPv4 carries tos, ecn,
ttl, id and offset, and reverses the protocol name and number columns - and then
again with the protocol, where TCP appends flags, sequence and acknowledgement
numbers, window and options, UDP stops after the payload length, and ICMP
switches to key=value pairs. The pipeline parses this positionally in a single
script, which keeps the column order documented in one place rather than spread
across grok alternatives.

Built and tested against a live OPNsense 26.7. The pipeline test fixtures are
captured syslog covering both IP versions, the match and ip-option reasons, and
tcp, udp, icmp and ipv6-icmp.
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

Reviewers

Buildkite won't run for external contributors automatically; you need to add a comment:

  • /test : will kick off a build in Buildkite.

NOTE: https://github.com/elastic/integrations/blob/main/.buildkite/pull-requests.json contains all those details.

@TocharianOU
TocharianOU marked this pull request as draft September 15, 2026 14:44
@TocharianOU
TocharianOU marked this pull request as ready for review September 15, 2026 14:50
@qcorporation qcorporation added New Integration Issue or pull request for creating a new integration package. documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. labels Sep 15, 2026
Ran /review-integration from elastic/integration-skills over the package and
addressed everything it reported. Same pass as the CrowdSec package, which was
built from the same template.

Package metadata
- format_version 3.3.2 -> 3.4.2 and conditions.kibana.version -> ^8.19.0 || ^9.1.0,
  the values required for a new package.
- ECS pinned to git@v9.3.0 in build.yml, with the pipeline's ecs.version raised
  to match.

Fields
- base-fields.yml now uses external: ecs on all six entries instead of
  redefining each field inline.
- Added beats.yml; the logfile input emits log.offset and log.file.path.

Ingest pipeline
- Follows JSE00001: message is renamed to event.original unconditionally and the
  syslog grok reads from event.original without modifying it. For messages that
  are not filterlog events, message is still repopulated from the parsed body so
  the line stays readable.
- Pipeline-level on_failure now appends the full processor-type/tag error
  template first, then sets event.kind, then tags the document
  preserve_original_event. Documents that only trip a processor-level on_failure
  get the same tag.

Tests
- Added test-common-config.yml.
- Renamed the fixture to the test-<package>-<datastream>-<type>-sample.log
  convention and added a variants fixture covering branches the filterlog
  fixture never reached: IPv4 and IPv6 TCP carrying a FIN/PSH/URG flag
  combination, two non-filterlog syslog messages from the same stream, a
  message in RFC 3164 rather than RFC 5424 format, and a line with no syslog
  header at all.

Dashboard
- Saved objects are stored with their JSON attributes unstringified, matching
  every upstream package. kbdash could not parse the previous form.
- Dashboard and saved search now use UUID identifiers, and the title is sentence
  case.

Documentation
- README rewritten against docs/extend/documentation-guidelines.md: Overview,
  What data does this integration collect?, What do I need to use this
  integration?, How do I deploy this integration?, Troubleshooting, Performance
  and scaling, and Reference.

elastic-package format, lint, check and test pipeline all pass.
@TocharianOU

Copy link
Copy Markdown
Author

Applied the same /review-integration pass that @qcorporation suggested on #21270, since this package was built from the same template and had the same issues.

  • format_version → 3.4.2, conditions.kibana.version^8.19.0 || ^9.1.0, ECS pinned to git@v9.3.0
  • base-fields.yml uses external: ecs; added beats.yml
  • Pipeline follows JSE00001 — the syslog grok now reads from event.original. Messages that are not filterlog events still get message repopulated from the parsed body so the line stays readable.
  • on_failure reordered to error.message → event.kind → tags
  • Added test-common-config.yml, renamed fixtures to convention, and added a variants fixture covering branches the filterlog fixture never reached: IPv4 and IPv6 TCP with a FIN/PSH/URG flag combination, two non-filterlog syslog messages from the same stream, a message in RFC 3164 rather than RFC 5424 format, and a line with no syslog header at all
  • Dashboard saved objects stored unstringified so kbdash can read them; UUID identifiers, sentence-case title
  • README rewritten against docs/extend/documentation-guidelines.md

elastic-package format, lint, check and test pipeline all pass.

The two open questions from #21270source.license: Apache-2.0 and the CODEOWNERS team — apply to this package identically.

@qcorporation

Copy link
Copy Markdown
Contributor

/test

@qcorporation

Copy link
Copy Markdown
Contributor

@vera-review-bot review

@github-actions

Copy link
Copy Markdown
Contributor

Elastic Docs Style Checker (Vale)

Summary: 7 warnings, 6 suggestions found

⚠️ Warnings (7): Fix when the suggestion improves clarity or correctness.
File Line Rule Message
packages/opnsense/_dev/build/docs/README.md 86 Elastic.MenuArrowsBold Use '→' to separate menu items, not '' or '='. Example: Select Manage index → Add lifecycle policy.
packages/opnsense/_dev/build/docs/README.md 86 Elastic.MenuArrows Use '→' to separate menu items, not '' or '='. Example: Select Manage index → Add lifecycle policy.
packages/opnsense/_dev/build/docs/README.md 118 Elastic.MenuArrowsBold Use '→' to separate menu items, not '' or '='. Example: Select Manage index → Add lifecycle policy.
packages/opnsense/_dev/build/docs/README.md 118 Elastic.MenuArrows Use '→' to separate menu items, not '' or '='. Example: Select Manage index → Add lifecycle policy.
packages/opnsense/_dev/build/docs/README.md 118 Elastic.MenuArrows Use '→' to separate menu items, not '' or '='. Example: Select Manage index → Add lifecycle policy.
packages/opnsense/_dev/build/docs/README.md 191 Elastic.BritishSpellings Use American English spelling 'acknowledgment' instead of British English 'acknowledgement'.
packages/opnsense/data_stream/log/fields/fields.yml 99 Elastic.BritishSpellings Use American English spelling 'acknowledgment' instead of British English 'acknowledgement'.
💡 Suggestions (6): Optional style improvements. Apply when helpful.
File Line Rule Message
packages/opnsense/_dev/build/docs/README.md 25 Elastic.Semicolons Use semicolons sparingly. Consider splitting the sentence or using a comma or conjunction.
packages/opnsense/_dev/build/docs/README.md 137 Elastic.Semicolons Use semicolons sparingly. Consider splitting the sentence or using a comma or conjunction.
packages/opnsense/_dev/build/docs/README.md 159 Elastic.Semicolons Use semicolons sparingly. Consider splitting the sentence or using a comma or conjunction.
packages/opnsense/_dev/build/docs/README.md 166 Elastic.Semicolons Use semicolons sparingly. Consider splitting the sentence or using a comma or conjunction.
packages/opnsense/_dev/build/docs/README.md 189 Elastic.Semicolons Use semicolons sparingly. Consider splitting the sentence or using a comma or conjunction.
packages/opnsense/changelog.yml 1 Elastic.Versions Use 'later versions' instead of 'newer versions' when referring to versions.

The Vale linter checks documentation changes against the Elastic Docs style guide. To use Vale locally or report issues, refer to Elastic style guide for Vale.

@infra-vault-gh-plugin-prod

infra-vault-gh-plugin-prod Bot commented Sep 16, 2026

Copy link
Copy Markdown

💔 Build Failed

Failed CI Steps

History

@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

✅ All changelog entries have the correct PR link.

Comment thread packages/opnsense/manifest.yml Outdated
Comment thread packages/opnsense/_dev/build/docs/README.md Outdated
@vera-review-bot

Copy link
Copy Markdown

Review summary

Issues found across the latest commits 6a891fe — 1 medium, 2 low
  • 🟡 owner.github names an individual account while CODEOWNERS assigns the package to an Elastic team (link) (Unresolved)
  • 🔵 The new README uses the retired term "Agentless" (link) (Unresolved)

Package-level:

  • 🔵 Proposed commit message

    opnsense: add new integration for OPNsense firewall logs
    
    Add a new community package that collects OPNsense filterlog events, the
    accept and block decisions made by the pf packet filter, over syslog. The
    package has one `log` data stream with `udp`, `tcp` and `logfile` inputs,
    an ingest pipeline that maps events to ECS with vendor detail under
    `opnsense.log.*`, field definitions, pipeline test fixtures captured from
    OPNsense 26.7, and the "[Logs OPNsense] Firewall activity" dashboard.
    
    The filterlog body is CSV whose column layout depends on the IP version
    and then on the transport protocol, so the pipeline parses it positionally
    in a single script rather than a stack of grok alternatives.
    `opnsense.log.tcp.flags` is kept so that a SYN connection attempt can be
    distinguished from an ACK scan.
    
    Relates #​21270
    

Since this is a community PR, a new commit triggers another review — at most once every 30 minutes. I skip the PR while it's approved or has merge conflicts.

🤖 AI-Generated Review | Vera Review Bot - v0.4.1 | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Same fixes as the CrowdSec package, which was built from the same template.

- owner.github now names elastic/security-service-integrations, the team the
  CODEOWNERS entry lists, so the codeowners check passes. owner.type stays
  community.
- Added a script test covering the pipeline's failure paths: filterlog lines
  whose source or destination address column is corrupt. It asserts the bad
  address is reported in error.message and left unset, the valid address and
  the action are still parsed, and the raw line is kept in event.original with
  the preserve_original_event tag.
- README: "Agentless" is now "Elastic Managed (agentless)"; every menu path
  uses →, not only the ones the style check flagged; "acknowledgment" in the
  README and fields.yml.
@TocharianOU TocharianOU changed the title [opnsense] Add new integration for OPNsense firewall logs opnsense: add new integration for OPNsense firewall logs Sep 16, 2026
@qcorporation

Copy link
Copy Markdown
Contributor

@jamiehynds @narph we need to recommend an owner for this new contribution: can you please help

@TocharianOU

Copy link
Copy Markdown
Author

For context on ownership: every comparable firewall package in the repository is owned by @elastic/integration-experience — including pfsense, which shares OPNsense's filterlog format, as well as fortinet_fortigate, panw, checkpoint, sonicwall_firewall and iptables. I used @elastic/security-service-integrations in CODEOWNERS and the manifest; I will switch both to whichever team you settle on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. New Integration Issue or pull request for creating a new integration package.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants