summaryrefslogtreecommitdiffstats
path: root/doc/userguide/rules/differences-from-snort.rst
blob: 9ca145c5e238ae317ab386ffc9425a2cb53fe382 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
======================
Differences From Snort
======================

This document is intended to highlight the major differences between Suricata
and Snort that apply to rules and rule writing.

Where not specified, the statements below apply to Suricata.  In general,
references to Snort refer to the version 2.9 branch.

Automatic Protocol Detection
----------------------------

-  Suricata does automatic protocol detection of the following
   application layer protocols:

   -  dcerpc
   -  dnp3
   -  dns
   -  http
   -  imap (detection only by default; no parsing)
   -  ftp
   -  modbus (disabled by default; minimalist probe parser; can lead to false positives)
   -  smb
   -  smb2 (disabled internally inside the engine)
   -  smtp
   -  ssh
   -  tls (SSLv2, SSLv3, TLSv1, TLSv1.1 and TLSv1.2)

-  In Suricata, protocol detection is port agnostic (in most cases). In
   Snort, in order for the ``http_inspect`` and other preprocessors to be
   applied to traffic, it has to be over a configured port.

   -  Some configurations for app-layer in the Suricata yaml can/do by default
      specify specific destination ports (e.g. DNS)
   -  **You can look on 'any' port without worrying about the
      performance impact that you would have to be concerned about with
      Snort.**

-  If the traffic is detected as HTTP by Suricata, the ``http_*``
   buffers are populated and can be used, regardless of port(s)
   specified in the rule.

-  You don't have to check for the http protocol (i.e.
   ``alert http ...``) to use the ``http_*`` buffers although it
   is recommended.

-  If you are trying to detect legitimate (supported) application layer
   protocol traffic and don't want to look on specific port(s), the rule
   should be written as ``alert <protocol> ...`` with ``any`` in
   place of the usual protocol port(s).  For example, when you want to
   detect HTTP traffic and don't want to limit detection to a particular
   port or list of ports, the rules should be written as
   ``alert http ...`` with ``any`` in place of
   ``$HTTP_PORTS``.

   -  You can also use ``app-layer-protocol:<protocol>;`` inside the rule instead.

   So, instead of this Snort rule::

      alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ...

   Do this for Suricata::

      alert http $HOME_NET -> $EXTERNAL_NET any ...

   Or::

      alert tcp $HOME_NET any -> $EXTERNAL_NET any (app-layer-protocol:http; ...

``urilen`` Keyword
------------------

-  Ranges given in the ``urilen`` keyword are inclusive for Snort
   but not inclusive for Suricata.

   Example: ``urilen:2<>10``

      -  Snort interprets this as, "the URI length must be **greater than
         or equal to** 2, and **less than or equal to** 10".
      -  Suricata interprets this as "the URI length must be **greater
         than** 2 and **less than** 10".

   -  There is a request to have Suricata behave like Snort in future
      versions –
      `https://redmine.openinfosecfoundation.org/issues/1416 <https://redmine.openinfosecfoundation.org/issues/1416>`_

      -  Currently on hold

-  By default, with *Suricata*, ``urilen`` applies to the
   **normalized** buffer

   -  Use ``,raw`` for raw buffer
   -  e.g. ``urilen:>20,raw;``

-  By default, with *Snort*, ``urilen`` applies to the **raw**
   buffer

   -  Use ``,norm`` for normalized buffer
   -  e.g. ``urilen:>20,norm;``

``http_uri`` Buffer
-------------------

-  In Snort, the ``http_uri`` buffer normalizes '+' characters
   (0x2B) to spaces (0x20).

   -  Suricata can do this as well but you have to explicitly
      set ``query-plusspace-decode: yes`` in the ``libhtp`` section of Suricata's yaml file.

-  `https://redmine.openinfosecfoundation.org/issues/1035 <https://redmine.openinfosecfoundation.org/issues/1035>`_
-  `https://github.com/inliniac/suricata/pull/620 <https://github.com/inliniac/suricata/pull/620>`_

``http_header`` Buffer
----------------------

-  In Snort, the ``http_header`` buffer includes the CRLF CRLF (0x0D
   0x0A 0x0D 0x0A) that separates the end of the last HTTP header from
   the beginning of the HTTP body.  Suricata includes a CRLF after the
   last header in the ``http_header`` buffer but not an extra one
   like Snort does.  If you want to match the end of the buffer, use
   either the ``http_raw_header`` buffer, a relative
   ``isdataat`` (e.g. ``isdataat:!1,relative``) or a PCRE
   (although PCRE will be worse on performance).

-  Suricata *will* include CRLF CRLF at the end of the ``http_raw_header``
   buffer like Snort does.

-  Snort will include a *leading* CRLF in the ``http_header`` buffer of
   *server responses* (but not client requests).  Suricata does not have
   the leading CRLF in the ``http_header`` buffer of the server response
   or client request.

-  In the ``http_header`` buffer, Suricata will normalize HTTP header lines
   such that there is a single space (0x20) after the colon (':') that
   separates the header name from the header value; this single space
   replaces zero or more whitespace characters (including tabs) that may be
   present in the raw HTTP header line immediately after the colon.  If the
   extra whitespace (or lack thereof) is important for matching, use
   the ``http_raw_header`` buffer instead of the ``http_header`` buffer.

-  Snort will also normalize superfluous whitespace between the header name
   and header value like Suricata does but only if there is at least one space
   character (0x20 only so not 0x90) immediately after the colon.  This means
   that, unlike Suricata, if there is no space (or if there is a tab)
   immediately after the colon before the header value, the content of the
   header line will remain unchanged in the ``http_header`` buffer.

-  When there are duplicate HTTP headers (referring to the header name
   only, not the value), the normalized buffer (``http_header``)
   will concatenate the values in the order seen (from top to
   bottom), with a comma and space (", ") between each of them.  If this
   hinders detection, use the ``http_raw_header`` buffer instead.

   Example request::

        GET /test.html HTTP/1.1
        Content-Length: 44
        Accept: */*
        Content-Length: 55

   The Content-Length header line becomes this in the ``http_header`` buffer::

        Content-Length: 44, 55

-  The HTTP 'Cookie' and 'Set-Cookie' headers are **NOT** included in
   the ``http_header`` buffer; instead they are extracted and put into
   their own buffer – ``http_cookie``. See the `http_cookie Buffer`_
   section.

-  The HTTP 'Cookie' and 'Set-Cookie' headers **ARE** included in the
   ``http_raw_header`` buffer so if you are trying to match on
   something like particular header ordering involving (or not
   involving) the HTTP Cookie headers, use the ``http_raw_header``
   buffer.

-  If 'enable\_cookie' is set for Snort, the HTTP Cookie header names
   and trailing CRLF (i.e. "Cookie: \\r\\n" and "Set-Cooke \\r\\n") are
   kept in the ``http_header`` buffer.  This is not the case for
   Suricata which removes the entire "Cookie" or "Set-Cookie" line from
   the ``http_header`` buffer.

-  Other HTTP headers that have their own buffer
   (``http_user_agent``, ``http_host``) are not removed from the
   ``http_header`` buffer like the Cookie headers are.

-  When inspecting server responses and ``file_data`` is used,
   content matches in ``http_*`` buffers should come before
   ``file_data`` unless you use ``pkt_data`` to reset the cursor
   before matching in ``http_*`` buffers.  Snort will not complain if
   you use ``http_*`` buffers after ``file_data`` is set.

``http_cookie`` Buffer
----------------------

-  The ``http_cookie`` buffer will NOT include the header name,
   colon, or leading whitespace.  i.e. it will not include "Cookie: " or "Set-Cookie: ".

-  The ``http_cookie`` buffer does not include a CRLF (0x0D 0x0A) at
   the end.  If you want to match the end of the buffer, use a relative
   ``isdataat`` or a PCRE (although PCRE will be worse on
   performance).

-  There is no ``http_raw_cookie`` buffer in Suricata.  Use
   ``http_raw_header`` instead.

-  You do not have to configure anything special to use the
   'http\_cookie' buffer in Suricata.  This is different from Snort
   where you have to set ``enable_cookie`` in the
   ``http_inspect_server`` preprocessor config in order to have the
   ``http_cookie`` buffer treated separate from the
   ``http_header`` buffer.

-  If Snort has 'enable\_cookie' set and multiple "Cookie" or
   "Set-Cookie" headers are seen, it will concatenate them together
   (with no separator between them) in the order seen from top to
   bottom.

-  If a request contains multiple "Cookie" or "Set-Cookie" headers, the
   values will be concatenated in the Suricata ``http_cookie``
   buffer, in the order seen from top to bottom, with a comma and space
   (", ") between each of them.

   Example request::

        GET /test.html HTTP/1.1
        Cookie: monster
        Accept: */*
        Cookie: elmo

   Suricata ``http_cookie`` buffer contents::

        monster, elmo

   Snort ``http_cookie`` buffer contents::

        monsterelmo

-  Corresponding PCRE modifier: ``C`` (same as Snort)

New HTTP keywords
-----------------

Suricata supports several HTTP keywords that Snort doesn't have.

Examples are ``http_user_agent``, ``http_host`` and ``http_content_type``.

See :doc:`http-keywords` for all HTTP keywords.


``byte_extract`` Keyword
------------------------

-  Suricata supports
   ``byte_extract`` from ``http_*`` buffers, including
   ``http_header`` which does not always work as expected in Snort.

-  In Suricata, variables extracted using ``byte_extract`` must be used
   in the same buffer, otherwise they will have the value "0" (zero). Snort
   does allow cross-buffer byte extraction and usage.

-  Be sure to always positively and negatively test Suricata rules that
   use ``byte_extract`` and ``byte_test`` to verify that they
   work as expected.


``byte_jump`` Keyword
---------------------

-  Suricata allows a variable name from ``byte_extract`` or
   ``byte_math`` to be specified for the ``nbytes`` value. The
   value of ``nbytes`` must adhere to the same constraints
   as if it were supplied directly in the rule.


``byte_math`` Keyword
---------------------

-  Suricata accepts ``dce`` as an endian value or as a separate keyword.
   ``endian dce`` or ``dce`` are equivalent.

-  Suricata's rule parser rejects rules that repeat keywords in a single
   rule. E.g., ``byte_math: endian big, endian little``.

-  Suricata's rule parser accepts ``rvalue`` values of ``0`` to the maximum
   uint32 value. Snort rejects ``rvalue`` values of ``0`` and requires
   values to be between ``[1..max-uint32 value]``.

-  Suricata will never match if there's a zero divisor. Division by 0 is undefined.

``byte_test`` Keyword
---------------------

- Suricata allows a variable name from ``byte_extract`` or ``byte_math``
  to be specified for the ``nbytes`` value. The value of ``nbytes`` must adhere
  to the same constraints as though a value was directly supplied by the rule.

-  Suricata allows a variable name from ``byte_extract`` to be specified for
   the ``nbytes`` value. The value of ``nbytes`` must adhere to the same constraints
   as if it were supplied directly in the rule.


``isdataat`` Keyword
--------------------

-  The ``rawbytes`` keyword is supported in the Suricata syntax but
   doesn't actually do anything.

-  Absolute ``isdataat`` checks will succeed if the offset used is
   **less than** the size of the inspection buffer.  This is true for
   Suricata and Snort.

-  For *relative* ``isdataat`` checks, there is a **1 byte difference**
   in the way Snort and Suricata do the comparisons.

   -  Suricata will succeed if the relative offset is **less than or
      equal to** the size of the inspection buffer. This is different
      from absolute ``isdataat`` checks.
   -  Snort will succeed if the relative offset is **less than** the
      size of the inspection buffer, just like absolute ``isdataat``
      checks.
   -  Example - to check that there is no data in the inspection buffer
      after the last content match:

      -  Snort:        ``isdataat:!0,relative;``
      -  Suricata:     ``isdataat:!1,relative;``

-  With Snort, the "inspection buffer" used when checking an
   ``isdataat`` keyword is generally the packet/segment with some
   exceptions:

   -  With PAF enabled the PDU is examined instead of the
      packet/segment.  When ``file_data`` or ``base64_data`` has
      been set, it is those buffers (unless ``rawbytes`` is set).
   -  With some preprocessors - modbus, gtp, sip, dce2, and dnp3 - the
      buffer can be particular portions of those protocols (unless
      ``rawbytes`` is set).
   -  With some preprocessors - rpc\_decode, ftp\_telnet, smtp, and dnp3
      - the buffer can be particular *decoded* portions of those
      protocols (unless ``rawbytes`` is set).

-  With Suricata, the "inspection buffer" used when checking an absolute
   ``isdataat`` keyword is the packet/segment if looking at a packet
   (e.g. ``alert tcp-pkt...``) or the reassembled stream segments.

-  In Suricata, a *relative* ``isdataat`` keyword **will apply to the
   buffer of the previous content match**.  So if the previous content
   match is a ``http_*`` buffer, the relative ``isdataat``
   applies to that buffer, starting from the end of the previous content
   match in that buffer.  *Snort does not behave like this!*

-  For example, this Suricata rule looks for the string ".exe" at the
   end of the URI; to do the same thing in the normalized URI buffer in
   Snort you would have to use a PCRE – ``pcre:"/\x2Eexe$/U";``

   ::

       alert http $HOME_NET any -> $EXTERNAL_NET any (msg:".EXE File Download Request"; flow:established,to_server; content:"GET"; http_method; content:".exe"; http_uri; isdataat:!1,relative; priority:3; sid:18332111;)

-  If you are unclear about behavior in a particular instance, you are
   encouraged to positively and negatively test your rules that use an
   ``isdataat`` keyword.

Relative PCRE
-------------

-  You can do relative PCRE matches in normalized/special buffers with Suricata.  Example::

     content:".php?sign="; http_uri; pcre:"/^[a-zA-Z0-9]{8}$/UR";

-  With Snort you can't combine the "relative" PCRE option ('R') with other buffer options like normalized URI ('U') – you get a syntax error.

``tls*`` Keywords
------------------

In addition to TLS protocol identification, Suricata supports the storing of
certificates to disk, verifying the validity dates on certificates, matching
against the calculated SHA1 fingerprint of certificates, and
matching on certain TLS/SSL certificate fields including the following:

-  Negotiated TLS/SSL version.
-  Certificate Subject field.
-  Certificate Issuer field.
-  Certificate SNI Field

For details see :doc:`tls-keywords`.

``dns_query`` Keyword
---------------------

-  Sets the detection pointer to the DNS query.

-  Works like ``file_data`` does ("sticky buffer") but for a DNS
   request query.

-  Use ``pkt_data`` to reset the detection pointer to the beginning of
   the packet payload.

-  See :doc:`dns-keywords` for details.

IP Reputation and ``iprep`` Keyword
-----------------------------------

-  Snort has the "reputation" preprocessor that can be used to define
   whitelist and blacklist files of IPs which are used generate GID 136
   alerts as well as block/drop/pass traffic from listed IPs depending
   on how it is configured.

-  Suricata also has the concept of files with IPs in them but provides
   the ability to assign them:

   -  Categories
   -  Reputation score

-  Suricata rules can leverage these IP lists with the ``iprep``
   keyword that can be configured to match on:

   -  Direction
   -  Category
   -  Value (reputation score)

-  :doc:`../reputation/index`
-  :doc:`../reputation/ipreputation/ip-reputation-config`
-  :doc:`ip-reputation-rules`
-  :doc:`../reputation/ipreputation/ip-reputation-format`
-  `https://blog.inliniac.net/2012/11/21/ip-reputation-in-suricata/ <https://blog.inliniac.net/2012/11/21/ip-reputation-in-suricata/>`_

Flowbits
--------

-  Suricata fully supports the setting and checking of flowbits
   (including the same flowbit) on the same packet/stream.  Snort does
   not always allow for this.

-  In Suricata, ``flowbits:isset`` is checked after the fast pattern
   match but before other ``content`` matches. In Snort,
   ``flowbits:isset`` is checked in the order it appears in the
   rule, from left to right.

-  If there is a chain of flowbits where multiple rules set flowbits and
   they are dependent on each other, then the order of the rules or the
   ``sid`` values can make a
   difference in the rules being evaluated in the proper order and
   generating alerts as expected.  See bug 1399 -
   `https://redmine.openinfosecfoundation.org/issues/1399 <https://redmine.openinfosecfoundation.org/issues/1399>`_.

-  :doc:`flow-keywords`

flowbits:noalert;
-----------------

A common pattern in existing rules is to use ``flowbits:noalert;`` to make
sure a rule doesn't generate an alert if it matches.

Suricata allows using just ``noalert;`` as well. Both have an identical meaning
in Suricata.

Negated Content Match Special Case
----------------------------------

-  For Snort, a *negated* content match where the starting point for
   searching is at or beyond the end of the inspection buffer will never
   return true.

   -  For negated matches, you want it to return true if the content is
      not found.
   -  This is believed to be a Snort bug rather than an engine difference
      but it was reported to Sourcefire and acknowledged many years ago
      indicating that perhaps it is by design.
   -  This is not the case for Suricata which behaves as
      expected.

     Example HTTP request::

       POST /test.php HTTP/1.1
       Content-Length: 9

       user=suri

     This rule snippet will never return true in Snort but will in
     Suricata::

       content:!"snort"; offset:10; http_client_body;

File Extraction
---------------

-  Suricata has the ability to match on files from FTP, HTTP and SMTP streams and
   log them to disk.

-  Snort has the "file" preprocessor that can do something similar
   but it is experimental, development of it
   has been stagnant for years, and it is not something that should be used
   in a production environment.

-  Files can be matched on using a number of keywords including:

   -  ``filename``
   -  ``fileext``
   -  ``filemagic``
   -  ``filesize``
   -  ``filemd5``
   -  ``filesha1``
   -  ``filesha256``
   -  ``filesize``
   - See :doc:`file-keywords` for a full list.

-  The ``filestore`` keyword tells Suricata to save the file to
   disk.

-  Extracted files are logged to disk with meta data that includes
   things like timestamp, src/dst IP, protocol, src/dst port, HTTP URI,
   HTTP Host, HTTP Referer, filename, file magic, md5sum, size, etc.

-  There are a number of configuration options and considerations (such
   as stream reassembly depth and libhtp body-limit) that should be
   understood if you want fully utilize file extraction in Suricata.

-  :doc:`file-keywords`
-  :doc:`../file-extraction/file-extraction`
-  `https://blog.inliniac.net/2011/11/29/file-extraction-in-suricata/ <https://blog.inliniac.net/2011/11/29/file-extraction-in-suricata/>`_
-  `https://blog.inliniac.net/2014/11/11/smtp-file-extraction-in-suricata/ <https://blog.inliniac.net/2014/11/11/smtp-file-extraction-in-suricata/>`_

Lua Scripting
-------------

-  Suricata has the ``lua`` (or ``luajit``) keyword which allows for a
   rule to reference a Lua script that can access the packet, payload,
   HTTP buffers, etc.
-  Provides powerful flexibility and capabilities that Snort does
   not have.
-  More details in: :ref:`lua-detection`

Fast Pattern
------------

-  Snort's fast pattern matcher is always case insensitive; Suricata's
   is case sensitive unless 'nocase' is set on the content match used by
   the fast pattern matcher.

-  Snort will truncate fast pattern matches based on the
   ``max-pattern-len`` config (default no limit) unless
   ``fast_pattern:only`` is used in the rule. Suricata does not do any
   automatic fast pattern truncation cannot be configured to do so.

-  Just like in Snort, in Suricata you can specify a substring of the
   content string to be use as the fast pattern match. e.g.
   ``fast_pattern:5,20;``

-  In Snort, leading NULL bytes (0x00) will be removed from content
   matches when determining/using the longest content match unless
   ``fast_pattern`` is explicitly set. Suricata does not truncate
   anything, including NULL bytes.

-  Snort does not allow for all ``http_*`` buffers to be used for
   the fast pattern match (e.g. ``http_raw_*``, ``http_method``,
   ``http_cookie``, etc.).  Suricata lets you use any 'http\_\*'
   buffer you want for the fast pattern match, including
   ``http_raw_*' and ``http_cookie`` buffers.

-  Suricata supports the ``fast_pattern:only`` syntax but
   technically it is not really implemented; the ``only`` is
   silently ignored when encountered in a rule.  It is still recommended
   that you use ``fast_pattern:only`` where appropriate in case this
   gets implemented in the future and/or if the rule will be used by
   Snort as well.

-  With Snort, unless ``fast_pattern`` is explicitly set, content
   matches in normalized HTTP Inspect buffers (e.g. http content
   modifiers such ``http_uri``, ``http_header``, etc.) take
   precedence over non-HTTP Inspect content matches, even if they are
   shorter.  Suricata does the same thing and gives a higher 'priority'
   (precedence) to ``http_*`` buffers (except for ``http_method``,
   ``http_stat_code``, and ``http_stat_msg``).

-  See :doc:`fast-pattern-explained` for full details on how Suricata
   automatically determines which content to use as the fast pattern match.

-  When in doubt about what is going to be use as the fast pattern match
   by Suricata, set ``fast_pattern`` explicitly in the rule and/or
   run Suricata with the ``--engine-analysis`` switch and view the
   generated file (``rules_fast_pattern.txt``).

-  Like Snort, the fast pattern match is checked before ``flowbits``
   in Suricata.

-  Using Hyperscan as the MPM matcher (``mpm-algo`` setting) for Suricata
   can greatly improve performance, especially when it comes to fast pattern
   matching.  Hyperscan will also take into account depth and offset
   when doing fast pattern matching, something the other algorithms and
   Snort do not do.

-  :ref:`rules-keyword-fast_pattern`

Don't Cross The Streams
-----------------------

Suricata will examine network traffic as individual packets and, in the
case of TCP, as part of a (reassembled) stream.  However, there are
certain rule keywords that only apply to packets only (``dsize``,
``flags``, ``ttl``) and certain ones that only apply to streams
only (``http_*``) and you can't mix packet and stream keywords. Rules
that use packet keywords will inspect individual packets only and
rules that use stream keywords will inspect streams only.  Snort is a
little more forgiving when you mix these – for example, in Snort you can
use ``dsize`` (a packet keyword) with ``http_*`` (stream
keywords) and Snort will allow it although, because of ``dsize``, it
will only apply detection to individual packets (unless PAF is enabled
then it will apply it to the PDU).

If ``dsize`` is in a rule that also looks for a stream-based
application layer protocol (e.g. ``http``), Suricata will not match on
the *first application layer packet* since ``dsize`` make Suricata
evaluate the packet and protocol detection doesn't happen until after
the protocol is checked for that packet; *subsequent* packets in that
flow should have the application protocol set appropriately and will
match rules using ``dsize`` and a stream-based application layer
protocol.

If you need to check sizes on a stream in a rule that uses a stream
keyword, or in a rule looking for a stream-based application layer
protocol, consider using the ``stream_size`` keyword and/or
``isdataat``.

Suricata also supports these protocol values being used in rules and
Snort does not:

-  ``tcp-pkt`` – example:

   -  ``alert tcp-pkt ...``
   -  This tells Suricata to only apply the rule to TCP packets and not
      the (reassembled) stream.

-  ``tcp-stream`` – example:

   -  ``alert tcp-stream ...``
   -  This tells Suricata to inspect the (reassembled) TCP stream only.

Alerts
------

-  In Snort, the number of alerts generated for a packet/stream can be
   limited by the ``event_queue`` configuration.

-  Suricata has an internal hard-coded limit of 15 alerts per packet/stream (and
   this cannot be configured); all rules that match on the traffic being
   analyzed will fire up to that limit.

-  Sometimes Suricata will generate what appears to be two alerts for
   the same TCP packet.  This happens when Suricata evaluates the packet
   by itself and as part of a (reassembled) stream.

Buffer Reference Chart
----------------------

+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| Buffer                | Snort 2.9.x                              | Suricata                                  | PCRE   | Can be used as | Suricata Fast    |
|                       | Support?                                 | Support?                                  | flag   | Fast Pattern?  | Pattern Priority |
|                       |                                          |                                           |        |                | (lower number is |
|                       |                                          |                                           |        |                | higher priority) |
+=======================+==========================================+===========================================+========+================+==================+
| content (no modifier) | YES                                      | YES                                       | <none> | YES            | 3                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_method           | YES                                      | YES                                       | M      | Suricata only  | 3                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_stat_code        | YES                                      | YES                                       | S      | Suricata only  | 3                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_stat_msg         | YES                                      | YES                                       | Y      | Suricata only  | 3                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| uricontent            | YES but deprecated, use http_uri instead | YES but deprecated, use http_uri instead  | U      | YES            | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_uri              | YES                                      | YES                                       | U      | YES            | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_raw_uri          | YES                                      | YES                                       | I      | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_header           | YES                                      | YES                                       | H      | YES            | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_raw_header       | YES                                      | YES                                       | D      | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_cookie           | YES                                      | YES                                       | C      | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_raw_cookie       | YES                                      | NO (use http_raw_header instead)          | K      | NO             | n/a              |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_host             | NO                                       | YES                                       | W      | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_raw_host         | NO                                       | YES                                       | Z      | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_client_body      | YES                                      | YES                                       | P      | YES            | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_server_body      | NO                                       | YES                                       | Q      | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| http_user_agent       | NO                                       | YES                                       | V      | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| dns_query             | NO                                       | YES                                       | n/a\*  | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| tls_sni               | NO                                       | YES                                       | n/a\*  | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| tls_cert_issuer       | NO                                       | YES                                       | n/a\*  | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| tls_cert_subject      | NO                                       | YES                                       | n/a\*  | Suricata only  | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+
| file_data             | YES                                      | YES                                       | n/a\*  | YES            | 2                |
+-----------------------+------------------------------------------+-------------------------------------------+--------+----------------+------------------+

\* Sticky buffer