]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
userguide: document how suricata processes rules
authorJuliana Fajardini <jufajardini@oisf.net>
Thu, 21 Jul 2022 20:44:59 +0000 (17:44 -0300)
committerVictor Julien <victor@inliniac.net>
Sat, 13 Sep 2025 06:40:12 +0000 (08:40 +0200)
Added a page that explains how rules are prioritized by Suri, as well
as what main different types of inspection happen and what elements are
involved when ordering rules.

Task #5449

doc/userguide/configuration/suricata-yaml.rst
doc/userguide/rules/flow-keywords.rst
doc/userguide/rules/http-keywords.rst
doc/userguide/rules/index.rst
doc/userguide/rules/meta.rst
doc/userguide/rules/rules-internals.rst [new file with mode: 0644]

index 3f9bff13b7455443d86a18f7754c93b71fee2f68..b76ba20e66b90ed2c0c354d5b33a2632e0bb0fd6 100644 (file)
@@ -164,6 +164,8 @@ back to the default.
 We recommend that you use the default value for this setting unless you are seeing a high number of discarded alerts
 (``alert_queue_overflow``) - see the `Discarded and Suppressed Alerts Stats`_ section for more details.
 
+.. _alert queue overflow impact:
+
 Impact on engine behavior
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -649,6 +651,8 @@ The following shows the configuration options for version 2 of the
       # file naming scheme.
       #force-hash: [sha1, md5]
 
+.. _detection-engine:
+
 Detection engine
 ----------------
 
index 3ba6bbe06a9a68ea81428e3806e974d970bf65ec..6f3995e66db935c26b6ae66a01a18109dd15d662 100644 (file)
@@ -6,6 +6,8 @@ Flow Keywords
 .. role:: example-rule-options
 .. role:: example-rule-emphasis
 
+.. _flowbits:
+
 flowbits
 --------
 
@@ -121,6 +123,7 @@ The determination of *established* depends on the protocol:
 
   .. image:: flow-keywords/Flow2.png
 
+.. _flowint:
 
 flowint
 -------
index 6d51e39b7175ba9c60b34ad2c69a2b3c09139c0f..12caf7504637169ff5e22c2bdea6e5aefb0787ae 100644 (file)
@@ -1284,4 +1284,4 @@ Example HTTP Response::
   classtype:bad-unknown; sid:102; rev:1;)
 
 .. note:: ``http.start`` contains the normalized headers and is terminated by
-  an extra \\r\\n to indicate the end of the headers.
\ No newline at end of file
+  an extra \\r\\n to indicate the end of the headers.
index b34c5519c56edab4b8ab160f66b6a0ff0be76024..59c8c23e993734e840c3b43775f55a517c624288 100644 (file)
@@ -57,3 +57,4 @@ Suricata Rules
    pgsql-keywords
    rule-types
    email-keywords
+   rules-internals
index 8312c91de091afb20896e7378f4ecf04d7d0fe60..fd892c1c5de6846fbeebdb2c53a6944d47579d12 100644 (file)
@@ -174,6 +174,8 @@ This would make a reference to http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE
 
 All the reference types are defined in the reference.config configuration file.
 
+.. _priority:
+
 priority
 --------
 
diff --git a/doc/userguide/rules/rules-internals.rst b/doc/userguide/rules/rules-internals.rst
new file mode 100644 (file)
index 0000000..4ed0486
--- /dev/null
@@ -0,0 +1,195 @@
+Rule Processing
+===============
+
+.. toctree::
+
+Suricata rules have many elements that influence how they are processed by
+Suricata and matched against network traffic.
+
+This section explains some key aspects of how Suricata handles rules internally,
+so it can be easier to understand/predict how different rules may interact in
+specific scenarios.
+
+**This material is intended for:** rule writers; developers.
+
+Possible questions one should be better equipped to answer after reading this
+document:
+
+- What happens if two rules have the same priority value (the keyword)?
+- What type of rules will be evaluated first, given a set of rules?
+- How does Suricata decide what rule is "more important" when matching traffic?
+
+.. important:: Rules processing is also heavily affected by rule types, as mentioned
+   in this chapter. You may want to read more on :doc:`rule-types`.
+
+.. note::
+
+    Throughout this documentation and for Suricata, the terms "rule" and
+    "signature" are mainly interchangeable, unless context indicates otherwise.
+
+Overview
+--------
+
+Rules are provided to Suricata via rules files. Starting from those, the
+Detection Engine loader will:
+
+#. Load all the signatures;
+#. Check for validity (non-existing keywords; duplicated ``sid`` etc);
+#. Report stats on loaded, good and bad signatures;
+#. Sort all valid signatures and store them in a list in the Detect Engine
+   Context (``DetectEngineCtx``) structure, taking into consideration several
+   rule aspects according to their order of relevance to the Detection Engine;
+#. Attribute internal rule IDs that reflect this `rule prioritization`_;
+#. During inspection, match rules against the inspected traffic, according to rule
+   and traffic type.
+
+.. _rule prioritization:
+
+Rule Prioritization
+-------------------
+
+Suricata registers several different ordering functions (with
+``SCSigRegisterSignatureOrderingFuncs()``), which are then used to compare
+the rules, sort them, and define their priority. The elements taken into
+consideration for such are the signature's:
+
+#. :ref:`Action <actions>`
+#. Usage of :ref:`flowbits`
+#. Usage of :ref:`flowint`
+#. Usage of flowvar
+#. Usage of pktvar
+#. Usage of hostbits
+#. Usage of ippair
+#. :ref:`"Priority" keyword<priority>`
+
+In this order. Once signatures are ordered, they are attributed a unique
+internal ID (``Signature::iid``) which symbolizes their priority (the lower the
+``iid``, the higher the priority). This could mean that a rule with a
+keyword-defined priority of 1 could have lower priority than another rule that
+had flowbits set and a rule action with higher priority, for instance.
+
+.. note:: this list isn't fully comprehensive, in the sense that each item has
+   extra logic for prioritization. For example, considering flowbits, the
+   priority is write (highest) > write + read > read (lowest) > no flowbits.
+
+Another important element when considering rule parsing, processing and matching
+is that the ruleset is optimized into signature group heads based on the signature
+elements (thus, for instance, a TCP rule and an UDP rule would be loaded into
+different groups, and their internal ids will not interfere between one another,
+as they're matched against different traffic). For more on this, see
+:ref:`detection-engine`.
+
+Inspection Process
+------------------
+
+Once it is time to inspect network traffic against the loaded rules, the
+Detect Engine will match against - if applicable:
+
+#. IP Only rules;
+#. Packet/payload-related rules;
+#. Frame keywords;
+#. Application layer protocol transaction rules.
+
+During packet inspection, if the signature uses the last two in this list,
+inspection is left to those steps.
+
+.. tip::
+
+  With the introduction of :doc:`Firewall mode <../firewall/firewall-design>`,
+  it is possible to explicitly control to which step of the detection engine flow
+  a rule will be hooked. This is done with :ref:`Explicit rule hooks <rule-hooks>`.
+
+For each rule that is matched, a ``PacketAlert`` is created. After all matches
+for a packet have been processed, and the :ref:`alert queue limit <alert queue
+overflow impact>` is taken into account, the remaining ``PacketAlerts`` become
+the alerts in Suricata logs.
+
+Considerations on Inspection Steps
+----------------------------------
+
+IP Only rules
+~~~~~~~~~~~~~
+
+Without optimization, IP Only signatures would match on every packet on a flow.
+To improve performance, what Suricata does is to evaluate rules that are
+``ip-only`` only once per flow direction, for the first packet in each direction.
+
+Application layer protocol transactions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each parser has its own state machine, and uses a per-direction parsing state
+"progress". Keywords can be registered for each progress value. So, for
+instance, ``http`` has a value "request line available" for which there are
+keywords like :ref:`http.uri <rules-http-uri-normalization>`, :ref:`http.method
+<http.method>` etc. registered. While parsing the traffic, if the engine reaches
+this state, the signatures with those keywords may be already evaluated, even if
+they have a lower priority than an http body inspecting signature.
+
+Relatedly, a rule with two keywords matching at two different progress stages may
+be evaluated against two different packets.
+
+Implications
+------------
+
+Action precedence and interaction with ``ip-only`` rules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To illustrate what may be counter-intuitive implications of how inspection
+steps, action prioritization and rule keywords interact and affect the engine
+behavior, we will use a real case example. Consider these three rules:
+
+.. container:: example-rule
+
+    pass tcp 0.0.0.0/0 any <> 0.0.0.0/0 443 (msg:"Allow TCP in port 443"; flow:
+    not_established; sid:1; rev:1;)
+
+.. container:: example-rule
+
+    pass tcp 0.0.0.0/0 any <> 0.0.0.0/0 80 (msg:"Allow TCP in port 80"; flow:
+    not_established; sid:2; rev:1;)
+
+.. container:: example-rule
+
+    drop ip 0.0.0.0/0 any -> 0.0.0.0/0 any (msg:"No outbound internet access
+    from host"; sid:3; rev:1;)
+
+The first two are signatures that analyze individual packets and match only if
+the flow has not been established (``flow:not_established``): the rules grant
+``PASS`` to the matched packet - but not to its flow.
+
+The third signature is considered ``ip-only``. This means it will be evaluated
+for the *first* packet in both directions of a flow, in addition to rules 1 and
+2. By extension, **the other packets in the same flow will not be evaluated
+against this rule.**
+
+With an action order configuration that prioritizes ``PASS`` over ``DROP``, this
+means that rules 1 and 2 will have a higher internal priority over rule 3,
+therefore nullifying the ``DROP`` outcome. The result: a flow for outbound
+internet traffic from the host, expected to be dropped, wouldn't be.
+
+If the expected behavior with those three signatures was to allow traffic on
+ports 80 and 443 only, while dropping everything else, the simplest way to
+achieve this would be to remove the ``flow:not_established`` portion from rules
+sid:1 and sid:2. This ensures that the ``PASS`` action would be applied to the
+whole flow following the match on the first packet and that all other traffic
+would be dropped.
+
+Following that, all three rules will be evaluated on the same step, and if a
+flow isn't flagged with ``pass``, it will be dropped with the third rule.
+
+.. Tip::
+   A more straightforward way to achieve that in Suricata 8 is using the firewall
+   more. See :doc:`../firewall/firewall-design`.
+
+Alerts not seen
+~~~~~~~~~~~~~~~
+
+Another aspect of rule prioritization combined with the alerts queue size is
+that, in corner case scenarios, if a packet matches against too many rules,
+signatures with lower priority could be discarded from the ``PacketAlert`` queue
+(see the section on :ref:`alert queue overflow impact <alert queue overflow impact>`
+for more).
+
+The stats counter ``detect.alert_queue_overflow`` will be higher than zero if
+an alert was discarded due to ``Alert Queue`` overflow (cf. :ref:`alerts stats`).
+