CLI Usage

After having installed suricata_check as described in Installation and having ensured it is included in the PATH variable (check your operating system specific instructions for this), you can invoke it using by running suricata-check.

To get an overview of all CLI options, run suricata-check --help. We will go over some basic use-cases below. You can also take a look at the CLI Reference

Consider a directory containing a rules file such as the following:

/var/lib/suricata/rules
├── classification.config
├── scanner_recognition.lua
├── suricata.rules

You can navigate to this directory and directly execute suricata-check as follows:

cd /var/lib/suricata/rules
suricata-check

Output

After suricata-check has been executed, you will see several new files:

/var/lib/suricata/rules
├── classification.config
├── scanner_recognition.lua
├── suricata-check-fast.log
├── suricata-check-stats.log
├── suricata-check.jsonl
├── suricata-check.log
├── suricata.rules

If you do not want these files to be generated in the current working directory, you can use the -o option as follows to specify an absolute or relative path:

suricata-check -o /path/to/my/output/dir

Human-readable output

suricata-check-fast.log contains output that is easy to read for humans. The structure is similar to that of suricata.fast as generated by suricata when rules trigger alerts. When suricata-check detects issues with a rule, it will write one line for each issue in suricata-check-fast.log similar to:

[C100] Line 1, sid 2260000: The rule does not use the `target` Suricata meta option. Consider adding the `target` option to specify which IP address is the target of the attack.

Machine-readable output

suricata-check.jsonl contains jsonlines output containing the same information as suricata-check-fast.log but more detailed and easily machine-readable for further processing by other tools. For example:

{
  "rule": "alert ip any any -> any any (msg:\"SURICATA Applayer Mismatch protocol both directions\"; flow:established; app-layer-event:applayer_mismatch_protocol_both_directions; flowint:applayer.anomaly.count,+,1; classtype:protocol-command-decode; sid:2260000; rev:1;)",
  "issues": [
    {
      "code": "C100",
      "message": "The rule does not use the `target` Suricata meta option.\nConsider adding the `target` option to specify which IP address is the target of the attack.",
      "checker": "BestChecker"
    },
    {
      "code": "C101",
      "message": "The rule does not use set the `created_at` metadata option.\nConsider adding the `created_at` metadata option to inform users of the recency of this signature.",
      "checker": "BestChecker"
    },
    {
      "code": "S800",
      "message": "The rule did not specify the `attack_target` metadata option.\nConsider specifying the `attack_target` metadata option to help analysts interpret alerts raised by this rule.",
      "checker": "MetadataChecker"
    },
    {
      "code": "S801",
      "message": "The rule did not specify the `signature_severity` metadata option.\nConsider specifying the `signature_severity` metadata option to help analysts interpret alerts raised by this rule.",
      "checker": "MetadataChecker"
    },
    {
      "code": "S802",
      "message": "The rule did not specify the `performance_impact` metadata option.\nConsider specifying the `performance_impact` metadata option to help SOCs determine when to enable this rule.",
      "checker": "MetadataChecker"
    },
    {
      "code": "S803",
      "message": "The rule did not specify the `deployment` metadata option. Consider specifying the `deployment` metadata option to help SOCs determine when to enable this rule.",
      "checker": "MetadataChecker"
    },
    {
      "code": "S400",
      "message": "The rule has a non-standard format for the msg field.\nConsider changing the msg field to `RULESET CATEGORY Description`.",
      "checker": "MsgChecker"
    },
    {
      "code": "S000",
      "message": "The rule did not specificy an inbound or outbound direction.\nConsider constraining the rule to a specific direction such as INBOUND or OUTBOUND traffic.",
      "checker": "OverallChecker"
    },
    {
      "code": "S020",
      "message": "The detection logic does not use the content option, which is can cause significant runtime overhead.\nConsider adding a content match.",
      "checker": "OverallChecker"
    },
    {
      "code": "P002",
      "message": "No Alert Throttling, the rule does not utilize the threshold limit option` to prevent alert flooding, making it potentially noisy.\n\nConsider setting a threshold limit to prevent alert flooding.\n\nUsing track by_both is considered to be safe if unsure which to use.",
      "checker": "PrincipleChecker"
    },
    {
      "code": "P003",
      "message": "No Exceptions, the rule does not include any exceptions for commom benign traffic, making it potentially noisy.\n\nConsider identifying common benign traffic on which the rule may trigger and add exceptions to the rule.",
      "checker": "PrincipleChecker"
    },
    {
      "code": "P004",
      "message": "No Generalized Characteristic, the rule does detect a characteristic that is so specific that it is unlikely generalize.",
      "checker": "PrincipleChecker"
    },
    {
      "code": "S301",
      "message": "Allocation to unallocated SID range, whereas local range should be used.\nConsider using an sid in one of the following ranges: [(1000000, 1999999)].",
      "checker": "SidChecker"
    }
  ],
  "summary": {
    "total_issues": 13,
    "issues_by_group": {
      "BestChecker": 2,
      "MandatoryChecker": 0,
      "MetadataChecker": 4,
      "MsgChecker": 1,
      "OrderChecker": 0,
      "OverallChecker": 2,
      "PcreChecker": 0,
      "PerformanceChecker": 0,
      "PrincipleChecker": 3,
      "ReferenceChecker": 0,
      "SidChecker": 1,
      "StateChecker": 0,
      "UnexpectedChecker": 0,
      "WhitespaceChecker": 0
    }
  },
  "line_begin": 1,
  "line_end": 1
}

Statistics

If you are interested in an overview of how many rules have issues and which issues are prevelant, this is also provided in suricata-check-stats.log. The output is tabular in structure, such as the following example snippet:

 MetadataChecker
-----------------
        Count  Percentage of Rules
----  -------  ---------------------
S800     8032  21%
S801     7464  19%
S802    25451  66%
S803     7639  20%

Debug information

In case of unexpected outputs or errors, you can inspect suricata-check.log for debug information. It also contains the lines logged to stdout and stderr, but may contain additional information for DEBUG loggers.

In case you require detailed logs for debugging, run suricata-check with the following argument.

suricata-check --log-level DEBUG

Single rule processing

Sometimes, it may be desirable to process a single rule. You can do so by using the --single-rule option. Note that you may need to escape special characters.

suricata-check --single-rule 'alert ip any any -> any any (msg:"Some msg"; sid:1;)'

Rule issues will be output directly to stdout, but can also be inspected via suricata-check.jsonl and suricata-check-fast.log if desirable since the same files are created.

Dealing with multiple rules files

In case you have a directory containing multiple rules files, you can manually specify the rule file to analyze as follows:

suricata-check -r /var/lib/suricata/rules/suricata.rules

Note that output will still be generated in the current working directory unless specified using the -o option.

Enabling and disabling checker issues

When dealing with large rulesets or legacy rulesets, it may be desirable to suppress some issues. Issues are divided into several categories as described in Issue Codes. Some issues have been disabled by default as a runtime performance optimization. To run suricata-check with all checkers and issues enabled, use the -a option as follows:

suricata-check -a

Individual issues can be enabled and disabled using regular expressions. Issues are enabled when they are matched by the -i option, unless they are also matched by the -e option.

For example, if one would like to enable all issues from the MandatoryChecker and all issues from the MetadataChecker except S802, one could use the following options:

suricata-check -i "M.*|S8.." -e S802

You can inspect the suricata-check.log output to verify if the intended checkers are indeed enabled:

2024-12-14 15:26:43,332 - suricata_check.suricata_check - INFO - include_all: False
2024-12-14 15:26:43,332 - suricata_check.suricata_check - INFO - include: ('M.*|S8..',)
2024-12-14 15:26:43,332 - suricata_check.suricata_check - INFO - exclude: ('S802',)
2024-12-14 15:26:43,451 - suricata_check.suricata_check - INFO - Checker BestChecker is disabled.
2024-12-14 15:26:43,451 - suricata_check.suricata_check - INFO - Checker UnexpectedChecker is disabled.
2024-12-14 15:26:43,452 - suricata_check.suricata_check - INFO - Checker PrincipleChecker is disabled.
2024-12-14 15:26:43,452 - suricata_check.suricata_check - INFO - Checker PrincipleMLChecker is disabled.
2024-12-14 15:26:43,452 - suricata_check.suricata_check - INFO - Checker MsgChecker is disabled.
2024-12-14 15:26:43,453 - suricata_check.suricata_check - INFO - Checker OrderChecker is disabled.
2024-12-14 15:26:43,453 - suricata_check.suricata_check - INFO - Checker OverallChecker is disabled.
2024-12-14 15:26:43,453 - suricata_check.suricata_check - INFO - Checker PcreChecker is disabled.
2024-12-14 15:26:43,454 - suricata_check.suricata_check - INFO - Checker PerformanceChecker is disabled.
2024-12-14 15:26:43,454 - suricata_check.suricata_check - INFO - Checker ReferenceChecker is disabled.
2024-12-14 15:26:43,454 - suricata_check.suricata_check - INFO - Checker SidChecker is disabled.
2024-12-14 15:26:43,456 - suricata_check.suricata_check - INFO - Checker StateChecker is disabled.
2024-12-14 15:26:43,456 - suricata_check.suricata_check - INFO - Checker WhitespaceChecker is disabled.
2024-12-14 15:26:43,456 - suricata_check.suricata_check - INFO - Discovered and enabled checkers: [MandatoryChecker, MetadataChecker]

It is also possible to enable issues based on their severity using the --issue-severity option.

For example, if one would like to only see issues with severity WARNING or greater, one could use the following option:

suricata-check --issue-severity=WARNING

CI/CD Integration

You can use suricata-check to generate output to be processed by platforms such as GitHub and GitLab to integrate it with your Continuous Integration and Continuous Deployment workflows using the --gitlab and --github options. Read more about those options here.