Skip to content

Commit b94800f

Browse files
committed
userguide: explain rule types and categorization
Add documentation about the rule types introduced by 2696fda. Add doc tags around code definitions that are referenced in the docs. Task #https://redmine.openinfosecfoundation.org/issues/7031
1 parent 278dc24 commit b94800f

File tree

4 files changed

+227
-0
lines changed

4 files changed

+227
-0
lines changed

doc/userguide/rules/intro.rst

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,226 @@ reassembled streams, TLS-, SSL-, SSH-, FTP- and dcerpc-buffers.
349349

350350
Note that there are some exceptions, e.g. the ``http_raw_uri`` keyword.
351351
See :ref:`rules-http-uri-normalization` for more information.
352+
353+
354+
Rule Types and Categorization
355+
-----------------------------
356+
357+
Once parsed, Suricata rules are categorized for performance and further
358+
processing (as different rule types will be handled by specific engine modules).
359+
The signature types are defined in `src/detect.h
360+
<https://github.com/OISF/suricata/blob/master/src/detect.h>`_:
361+
362+
.. literalinclude:: ../../../src/detect.h
363+
:caption: src/detect.h
364+
:language: c
365+
:start-after: // rule types documentation tag start: SignatureType
366+
:end-before: // rule types documentation tag end: SignatureType
367+
368+
The rule type will impact:
369+
370+
- To what does the signature action apply, in case of a match (`Action Scope`)
371+
- When is the rule matched against traffic (`Inspected`)
372+
- Against what the rule matches (`Matches`)
373+
374+
This categorization is done taking into consideration the presence or absence of
375+
certain rule elements, as well as the type of keywords used. The categorization
376+
currently takes place in `src/detect-engine-build.c:void SignatureSetType()
377+
<https://github.com/OISF/suricata/blob/master/src/detect-engine-build.c#L1642-L1704>`_.
378+
379+
The ``SignatureSetType()`` overall flow is described below:
380+
381+
.. image:: intro/OverallAlgoHorizontal-v1-20241108.png
382+
:width: 600
383+
:alt: A flowchart representing the SignatureSetType function.
384+
385+
The following table lists all Suricata signature types, and how they impact the
386+
aspects aforementioned.
387+
388+
.. list-table:: Suricata Rule Types
389+
:header-rows: 1
390+
391+
* - Type
392+
- Action Scope
393+
- Inspected
394+
- Matches
395+
- Keyword Examples (non-exhaustive)
396+
* - Decoder Events Only
397+
- Packet
398+
- Per-packet basis
399+
- Packets that are broken on an IP level
400+
- 'decode-event'
401+
* - Packet
402+
- Packet
403+
- Per-packet basis
404+
- Packet-level info (e.g.: header info)
405+
- 'itype', 'tcp.hdr', 'tcp.seq', 'ttl' etc.
406+
* - IP Only
407+
- Flow
408+
- Once per direction
409+
- On IP addresses on the flow
410+
- Source/ Destination field of a rule
411+
* - IP Only (contains a negated address)(*)
412+
- Flow
413+
- Once per direction
414+
- On the flow, on IP address level (negated addresses)
415+
- Source/ Destination field of a rule, containing negated address
416+
* - Protocol Detection Only
417+
- Flow
418+
- Once per direction, when protocol detection is done
419+
- On protocol detected for the flow
420+
- 'app-layer-protocol'
421+
* - Packet-Stream
422+
- Flow, if stateful (**)
423+
- Flow, if stateful, per-packet if not
424+
- Against the reassembled stream. If stream unavailable, match per-packet
425+
(packet payload and stream payload)
426+
- 'content' with 'startswith' or 'depth'
427+
* - Stream
428+
- Flow, if stateful (**)
429+
- Per stream chunk, if stateful, per-packet if not
430+
- Against the reassembled stream. If stream unavailable, match per-packet
431+
- 'tcp-stream' in protocol field; simple 'content'; 'byte_extract'
432+
* - Application Layer Protocol
433+
- Flow
434+
- Per-packet basis
435+
- On 'protocol' field
436+
- `Protocol field <https://suri-rtd-test.readthedocs.io/en/doc-sigtypes-et-properties-v5/rules/intro.html#protocol>`_ of a rule
437+
* - Application Layer Protocol Transactions
438+
- Flow
439+
- Per transaction update
440+
- On buffer keywords
441+
- Application layer protocol-related, e.g. 'http.host', 'rfb.secresult',
442+
'dcerpc.stub_data', 'frame' keywords
443+
444+
.. note::
445+
(*) IP Only signatures with negated addresses are `like` IP-only signatures, but
446+
currently handled differently due to limitations of the algorithm processing
447+
IP Only rules.
448+
449+
.. note:: Action Scope: `Flow, if stateful`
450+
451+
(**) Apply to the flow. If a segment isn't accepted into a stream for any
452+
reason (such as packet anomalies, errors, memcap reached etc), the rule will
453+
be applied on a packet level.
454+
455+
Signature Properties
456+
~~~~~~~~~~~~~~~~~~~~
457+
458+
The `Action Scope` mentioned above relates to the Signature Properties, as seen in
459+
`src/detect-engine.c <https://github.com/OISF/suricata/blob/master/src/detect-engine.c>`_:
460+
461+
.. literalinclude:: ../../../src/detect-engine.c
462+
:caption: src/detect-engine.c
463+
:language: c
464+
:start-after: // rule types documentation tag start: SignatureProperties
465+
:end-before: // rule types documentation tag end: SignatureProperties
466+
467+
Signature Examples per Type
468+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
469+
470+
Decoder Events Only
471+
^^^^^^^^^^^^^^^^^^^
472+
473+
For more examples check https://github.com/OISF/suricata/blob/master/rules/decoder-events.rules.
474+
475+
.. container:: example-rule
476+
477+
alert pkthdr any any -> any any (msg:"SURICATA IPv4 malformed option"; :example-rule-emphasis:`decode-event:ipv4.opt_malformed;` classtype:protocol-command-decode; sid:2200006; rev:2;)
478+
479+
Packet
480+
^^^^^^
481+
482+
.. container:: example-rule
483+
484+
alert udp any any -> any any (msg:"UDP with flow direction"; flow:to_server; sid:1001;)
485+
486+
.. container:: example-rule
487+
488+
alert tcp any any -> any any (msg:"ttl"; :example-rule-emphasis:`ttl:123;` sid:701;)
489+
490+
IP Only
491+
^^^^^^^
492+
493+
.. container:: example-rule
494+
495+
alert tcp-stream any any -> any any (msg:"tcp-stream, no content"; sid:101;)
496+
497+
498+
.. container:: example-rule
499+
500+
alert tcp-pkt [192.168.0.0/16,10.0.0.0/8,172.16.0.0/12] any -> any any (msg:"tcp-pkt, no content"; sid:201;)
501+
502+
IP Only (contains negated address)
503+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
504+
505+
.. container:: example-rule
506+
507+
alert tcp 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12 any -> :example-rule-emphasis:`![192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]` any (msg:"tcp, has negated IP address"; sid:304;)
508+
509+
.. container:: example-rule
510+
511+
alert tcp :example-rule-emphasis:`[10.0.0.0/8,!10.10.10.10]` any -> :example-rule-emphasis:`[10.0.0.0/8,!10.10.10.10]` any (msg:"tcp, has negated IP address"; sid:305;)
512+
513+
Protocol Detection Only
514+
^^^^^^^^^^^^^^^^^^^^^^^
515+
516+
.. container:: example-rule
517+
518+
alert tcp any any -> any any (msg:"tcp, pd negated"; :example-rule-emphasis:`app-layer-protocol:!http;` sid:401;)
519+
520+
521+
.. container:: example-rule
522+
523+
alert tcp any any -> any any (msg:"tcp, pd positive"; :example-rule-emphasis:`app-layer-protocol:http;` sid:402;)
524+
525+
526+
Packet-Stream
527+
^^^^^^^^^^^^^
528+
529+
.. container:: example-rule
530+
531+
alert tcp any any -> any any (msg:"tcp, anchored content"; :example-rule-emphasis:`content:"abc"; startswith;` sid:303;)
532+
533+
.. container:: example-rule
534+
535+
alert http any any -> any any (msg:"http, anchored content"; :example-rule-emphasis:`content:"abc"; startswith;` sid:603;)
536+
537+
538+
Stream
539+
^^^^^^
540+
541+
.. container:: example-rule
542+
543+
alert :example-rule-emphasis:`tcp-stream` any any -> any any (msg:"tcp-stream, simple content"; :example-rule-emphasis:`content:"abc";` sid:102;)
544+
545+
.. container:: example-rule
546+
547+
alert :example-rule-emphasis:`http` any any -> any any (msg:"http, simple content"; :example-rule-emphasis:`content:"abc";` sid:602;)
548+
549+
.. container:: example-rule
550+
551+
alert tcp any any -> any any (msg:"byte_extract with dce"; byte_extract:4,0,var,dce; byte_test:4,>,var,4,little; sid:901;)
552+
553+
554+
Application Layer Protocol
555+
^^^^^^^^^^^^^^^^^^^^^^^^^^
556+
557+
.. container:: example-rule
558+
559+
alert :example-rule-emphasis:`http` any any -> any any (msg:"http, no content"; sid:601;)
560+
561+
Application Layer Protocol Transactions
562+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
563+
564+
.. container:: example-rule
565+
566+
alert tcp any any -> any any (msg:"http, pos event"; :example-rule-emphasis:`app-layer-event:http.file_name_too_long;` sid:501;)
567+
568+
.. container:: example-rule
569+
570+
alert http any any -> any any (msg:"Test"; flow:established,to_server; :example-rule-emphasis:`http.method; content:"GET"; http.uri; content:".exe";` endswith; :example-rule-emphasis:`http.host; content:!".google.com";` endswith; sid:1102;)
571+
572+
.. container:: example-rule
573+
574+
alert udp any any -> any any (msg:"DNS UDP Frame"; flow:to_server; :example-rule-emphasis:`frame:dns.pdu;` content:"\|01 20 00 01\|"; offset:2; content:"suricata"; offset:13; sid:1402; rev:1;)
Loading

src/detect-engine.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static DetectEnginePktInspectionEngine *g_pkt_inspect_engines = NULL;
110110
static DetectEngineFrameInspectionEngine *g_frame_inspect_engines = NULL;
111111

112112
// clang-format off
113+
// rule types documentation tag start: SignatureProperties
113114
const struct SignatureProperties signature_properties[SIG_TYPE_MAX] = {
114115
/* SIG_TYPE_NOT_SET */ { SIG_PROP_FLOW_ACTION_PACKET, },
115116
/* SIG_TYPE_IPONLY */ { SIG_PROP_FLOW_ACTION_FLOW, },
@@ -122,6 +123,7 @@ const struct SignatureProperties signature_properties[SIG_TYPE_MAX] = {
122123
/* SIG_TYPE_APPLAYER */ { SIG_PROP_FLOW_ACTION_FLOW, },
123124
/* SIG_TYPE_APP_TX */ { SIG_PROP_FLOW_ACTION_FLOW, },
124125
};
126+
// rule types documentation tag end: SignatureProperties
125127
// clang-format on
126128

127129
/** \brief register inspect engine at start up time

src/detect.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct SCSigSignatureWrapper_;
5959
/* Forward declarations for structures from Rust. */
6060
typedef struct SCDetectRequiresStatus SCDetectRequiresStatus;
6161

62+
// rule types documentation tag start: SignatureType
6263
enum SignatureType {
6364
SIG_TYPE_NOT_SET = 0,
6465
SIG_TYPE_IPONLY, // rule is handled by IPONLY engine
@@ -76,6 +77,7 @@ enum SignatureType {
7677

7778
SIG_TYPE_MAX,
7879
};
80+
// rule types documentation tag end: SignatureType
7981

8082
enum SignaturePropertyFlowAction {
8183
SIG_PROP_FLOW_ACTION_PACKET,

0 commit comments

Comments
 (0)