Skip to content

suricata-fastlogs parser extracts GID as severity instead of Priority field #1734

@zadok3141

Description

@zadok3141

Title: suricata-fastlogs parser extracts GID as severity instead of Priority field


Describe the bug

The crowdsecurity/suricata-fastlogs parser in suricata-logs.yaml incorrectly maps the Suricata Generator ID (GID) to suricata_rule_severity instead of the actual Priority field. This causes the crowdsecurity/suricata-major-severity scenario to match every standard Suricata alert regardless of actual severity.

Parser version: Latest (tested on CrowdSec v1.7.4, OPNsense/FreeBSD)

Root cause

The SURICATA_RULE_ID grok pattern extracts the fast.log field [GID:SID:REV] as:

SURICATA_RULE_ID: '\[%{NUMBER:suricata_rule_severity}:%{NUMBER:rule_id}:%{NUMBER:suricata_alert_signature_rev}\]'

For a fast.log line like:

03/27/2026-07:09:05.719162  [**] [1:2000428:10] ET POLICY ZIP file download [**] [Classification: Misc activity] [Priority: 3] {TCP} 34.104.35.123:80 -> 192.168.20.6:61325

The parser extracts:

  • suricata_rule_severity = 1 (this is the GID — Generator ID, always 1 for standard rules)
  • rule_id = 2000428 (SID — correct)
  • suricata_alert_signature_rev = 10 (revision — correct)

The actual severity is in [Priority: 3], which is correctly captured as suricata_priority by the main grok pattern but never used for the suricata_rule_severity meta field.

In the statics section, the meta is set from the wrong parsed field:

- meta: suricata_rule_severity
  expression: evt.Parsed.suricata_rule_severity   # = GID (always 1), not severity

Impact

The crowdsecurity/suricata-major-severity scenario filters on evt.Meta.suricata_rule_severity == '1'. Since GID is always 1, this matches every Suricata alert — including low-priority policy alerts like ET POLICY ZIP file download (Priority 3). This causes false positive bans on legitimate IPs (e.g., Google Cloud CDN endpoints that OPNsense downloads updates from).

The crowdsecurity/suricata-high-medium-severity scenario (filters on severity == '2') never triggers because GID is never 2.

Confirmed with cscli explain

└ create evt.Parsed.suricata_priority : 3          ← actual Priority from fast.log
└ create evt.Parsed.suricata_rule_severity : 1     ← GID (always 1), NOT severity
└ create evt.Meta.suricata_rule_severity : 1       ← scenario sees this as severity 1
├ Scenarios
    └ 🟢 crowdsecurity/suricata-major-severity     ← incorrectly triggers

Suggested fix

Change the statics in the fast.log parser section from:

- meta: suricata_rule_severity
  expression: evt.Parsed.suricata_rule_severity

to:

- meta: suricata_rule_severity
  expression: evt.Parsed.suricata_priority

Optionally, rename the grok capture from suricata_rule_severity to suricata_gid to prevent future confusion:

SURICATA_RULE_ID: '\[%{NUMBER:suricata_gid}:%{NUMBER:rule_id}:%{NUMBER:suricata_alert_signature_rev}\]'

The eve-logs parser in the same file is correct, proving this is a fast.log-specific bug:

# eve-logs parser (correct) — extracts actual severity from JSON
- target: evt.Meta.suricata_rule_severity
  expression: JsonExtract(evt.Parsed.message, "alert.severity")

Suricata's source code confirms alert.severity in EVE JSON is the same value as Priority in fast.log (source):

jb_set_uint(js, "severity", pa->s->prio);

So the eve-logs parser correctly maps severity, but the fast.log parser maps the GID instead. Users of fast.log (commonly recommended for CrowdSec on OPNsense — see opnsense/core#7083) get every alert treated as severity 1.

References:

Environment

  • CrowdSec version: v1.7.4
  • Parser: crowdsecurity/suricata-logs (hub version)
  • Platform: OPNsense (FreeBSD 14.3), also reproducible on Linux
  • Suricata fast.log format: standard

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions