opnsense: add new integration for OPNsense firewall logs - #21272
TocharianOU wants to merge 4 commits into
Conversation
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.
ReviewersBuildkite won't run for external contributors automatically; you need to add a comment:
NOTE: https://github.com/elastic/integrations/blob/main/.buildkite/pull-requests.json contains all those details. |
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.
|
Applied the same
The two open questions from #21270 — |
|
/test |
|
@vera-review-bot review |
Elastic Docs Style Checker (Vale)Summary: 7 warnings, 6 suggestions found
|
| 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.
💔 Build Failed
Failed CI StepsHistory |
|
✅ All changelog entries have the correct PR link. |
Review summaryIssues found across the latest commits 6a891fe — 1 medium, 2 low
Package-level:
🤖 AI-Generated Review | Vera Review Bot - v0.4.1 | 📚 Knowledge base: integration-skills
|
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.
|
@jamiehynds @narph we need to recommend an owner for this new contribution: can you please help |
|
For context on ownership: every comparable firewall package in the repository is owned by |
Proposed commit message
OPNsense is an open-source firewall and routing platform based on FreeBSD. This repository ships a
pfsenseintegration but has nothing for OPNsense.One
logdata stream collecting filterlog events — the packet filter decisions made bypf— over syslog, withudp,tcpandlogfileinputs.The filterlog body is CSV whose column layout is not fixed:
tos, ecn, ttl, id, offset, flagsand reports the protocol asnumber, name; IPv6 carriesclass, flow, hoplimitand reverses those two columns toname, number.key=valuepairs.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.flagsis worth calling out: it distinguishes an ordinary SYN connection attempt from an ACK scan.Checklist
changelog.ymlfile.Author's Checklist
.github/CODEOWNERSandowner.githubboth name@elastic/security-service-integrations, withowner.type: community. If another team should own it, I will update both.source.license: Apache-2.0is acceptable — the same question as on crowdsec: add new integration for CrowdSec alerts #21270.changelog.ymllink points at this pull request./review-integrationfromelastic/integration-skillshas been run and its findings addressed.How to test this PR locally
The pipeline test fixtures are captured syslog from a live OPNsense 26.7, covering both IP versions, the
matchandip-optionreasons, andtcp,udp,icmpandipv6-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/.