diff --git a/filters/audits/ibm-i.md b/filters/audits/ibm-i.md new file mode 100644 index 000000000..dfbe165fe --- /dev/null +++ b/filters/audits/ibm-i.md @@ -0,0 +1,40 @@ +# IBM i / AS400 normalization and rule review + +Keep hostnames and unspecified addresses out of the standard IP field while retaining source values. + +This draft targets UTMStack `v11`. It contains 1 filter changes +and 0 rule changes for this technology only. Review covered +1 filter configurations and 8 matching shipped rule files. +Unchanged rules are listed in the regression manifest; they are not duplicated in the diff. + +## Contract and validation + +- Compared exact standard names/types with go-sdk v1.1.31 and the supplied UTMStack dictionaries. +- Checked documented pipeline ordering, rename/move behavior, open vendor log fields, + event-side versus alert-side fields, and surviving fields used by affected rule predicates/history/grouping. +- Strict SDK configuration decoding and actual CEL compilation pass for this scope. +- 2 synthetic normalization cases pass, including SDK Event conversion and any + trigger predicate assertions recorded in the manifest. +- The scoped alerts module tests and `git diff --check` pass with the shared contract runner applied. + +The shared alert-contract PR supplies the reusable Go runner for the manifest in +`plugins/alerts/testdata/filter-contracts/ibm-i.json`. Apply that support before running `go test ./...` in `plugins/alerts`. + +The model starts from synthetic extraction results. It does not run complex grok, +JSON/KV/XML/CSV extraction, time conversion, dynamic plugins, historical OpenSearch +queries, or the closed EventProcessor. Raw vendor logs and resulting alerts must +still be checked in staging before rollout. No customer false-positive reduction +has been measured and no production rollout is included. + + + +## References + +- [SDK schema](https://github.com/threatwinds/go-sdk/blob/v1.1.31/plugins/plugins.proto) +- [Filter steps](https://github.com/threatwinds/go-sdk/wiki/Filter-Steps-Reference) +- [Standard event schema](https://github.com/threatwinds/go-sdk/wiki/Standard-Event-Schema) +- [Rule implementation](https://github.com/threatwinds/go-sdk/wiki/Implementing-Rules) + +`afterEvents`, empty noncapturing grok names, supported numeric strings, and custom +`log.*` fields are accepted. Existing textual protocol casing and vendor action names +are preserved unless a concrete consumer mismatch requires correction. diff --git a/filters/ibm/ibm_as_400.yml b/filters/ibm/ibm_as_400.yml index 11522baef..0ccdf0ef8 100644 --- a/filters/ibm/ibm_as_400.yml +++ b/filters/ibm/ibm_as_400.yml @@ -85,4 +85,11 @@ pipeline: params: source: origin.ip destination: origin.geolocation - where: exists("origin.ip") \ No newline at end of file + where: exists("origin.ip") + + # Keep addresses in IP fields and retain other source values under log. + - rename: + from: + - origin.ip + to: log.unparsedOriginIp + where: exists("origin.ip") && (!(inCIDR("origin.ip","0.0.0.0/0") || inCIDR("origin.ip","::/0")) || oneOf("origin.ip",["0.0.0.0","::"])) diff --git a/plugins/alerts/testdata/filter-contracts/ibm-i.json b/plugins/alerts/testdata/filter-contracts/ibm-i.json new file mode 100644 index 000000000..1248b2c05 --- /dev/null +++ b/plugins/alerts/testdata/filter-contracts/ibm-i.json @@ -0,0 +1,48 @@ +{ + "technology": "IBM i / AS400", + "filters": [ + "filters/ibm/ibm_as_400.yml" + ], + "rules": [ + "rules/ibm/ibm_as_400/as400_audit_journal_disable.yml", + "rules/ibm/ibm_as_400/as400_exit_point_tampering.yml", + "rules/ibm/ibm_as_400/as400_ifs_access.yml", + "rules/ibm/ibm_as_400/as400_job_queue_manipulation.yml", + "rules/ibm/ibm_as_400/as400_library_list_manipulation.yml", + "rules/ibm/ibm_as_400/as400_program_adopt_abuse.yml", + "rules/ibm/ibm_as_400/as400_remote_command.yml", + "rules/ibm/ibm_as_400/as400_sql_injection.yml" + ], + "fixtures": [ + { + "name": "ibm_valid_source_ip", + "filter": "ibm/ibm_as_400.yml", + "input": { + "origin": { + "ip": "2001:db8::7" + } + }, + "expected": { + "origin.ip": "2001:db8::7" + }, + "absent": [], + "rules": {} + }, + { + "name": "ibm_hostname_not_ip", + "filter": "ibm/ibm_as_400.yml", + "input": { + "origin": { + "ip": "lab-host" + } + }, + "expected": { + "log.unparsedOriginIp": "lab-host" + }, + "absent": [ + "origin.ip" + ], + "rules": {} + } + ] +}