# Rule with flow option "only\_stream" never seems to match anything

**URL:** <https://forum.suricata.io/t/rule-with-flow-option-only-stream-never-seems-to-match-anything/1655>\
**Category:** Rules\
**Created:** [August 25, 2021, 3:00pm UTC](https://forum.suricata.io/t/rule-with-flow-option-only-stream-never-seems-to-match-anything/1655 "2021-08-25T15:00:02Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![BloShadow](https://avatars.discourse-cdn.com/v4/letter/b/ec9cab/32.png) [@BloShadow](https://forum.suricata.io/u/BloShadow)\
**Post date:** [August 25, 2021, 3:00pm UTC](https://forum.suricata.io/t/rule-with-flow-option-only-stream-never-seems-to-match-anything/1655/1 "2021-08-25T15:00:02Z")

</div>

Hey everyone,

I am trying to understand what exactly the “only\_stream” option of the flow keywords exactly does. From the documentation of the flow keyword:

> Match on packets that have been reassembled by the stream engine.

To me this sounds like this should match when the TCP frames of the trace need to be reassembled. After looking into the source code (following the flags for only\_stream and looking more closely into stream-tcp-reassemble.c) I believe this even more since the match counter should get increased if the option is set and the StreamPayload returns that some reassembly was done in the tcp-reassembly class.

However: when I use the following rule to match any reassembled frames, no alerts are ever returned.  
`alert ip any any -> any any (flow:only_stream; sid:1;)`

The traces I used should require some reassembly at least (out of order TCP frames, ack-ing unseen segments, etc.), however the rule above returns no matches (and when I use no\_stream instead every frame matches). Is there anything I’m missing why this rule never matches? Or can someone please point me to an example where this does indeed return any alerts at all?

Suricata.yaml stream engine settings I am using, in case I need to align something here (please note: my traces are rather small, \< 1MB, but I would assume TCP reassembly should also happen in those cases?):

```auto
stream:
  memcap: 64mb
  checksum-validation: yes # reject wrong csums
  inline: auto # auto will use inline mode in IPS mode, yes or no set it statically
  reassembly:
    memcap: 256mb
    depth: 1mb # reassemble 1mb into a stream
    toserver-chunk-size: 2560
    toclient-chunk-size: 2560
    randomize-chunk-size: yes
    #randomize-chunk-range: 10
    #raw: yes
    #segment-prealloc: 2048
    #check-overlap-different-data: true

```

---

<div class="post-metadata">

**Author:** ![syoc](https://avatars.discourse-cdn.com/v4/letter/s/f475e1/32.png) [@syoc](https://forum.suricata.io/u/syoc)\
**Post date:** [August 26, 2021, 8:41am UTC](https://forum.suricata.io/t/rule-with-flow-option-only-stream-never-seems-to-match-anything/1655/2 "2021-08-26T08:41:37Z")

</div>

Hi. Just wanted to chime in and say that I get no matches with some pcaps I had laying around.  
Some other rules with `flow:established` did trigger. I always assumed that `flow:only_stream` meant only matching on the reassembled buffer with the payloads from the complete flow, and not matching on the payloads of each individual packet.

---

<div class="post-metadata">

**Author:** ![syoc](https://avatars.discourse-cdn.com/v4/letter/s/f475e1/32.png) [@syoc](https://forum.suricata.io/u/syoc)\
**Post date:** [August 26, 2021, 8:44am UTC](https://forum.suricata.io/t/rule-with-flow-option-only-stream-never-seems-to-match-anything/1655/3 "2021-08-26T08:44:13Z")

</div>

The following rule did trigger (a lot): `alert ip any any -> any any (msg:"stream"; flow:only_stream; content:" "; sid:1;)`

Which kind of makes sense if the flag only affects which buffers are used for content matching, and no content matching is used.

---

<div class="post-metadata">

**Author:** ![BloShadow](https://avatars.discourse-cdn.com/v4/letter/b/ec9cab/32.png) [@BloShadow](https://forum.suricata.io/u/BloShadow)\
**Post date:** [August 26, 2021, 10:42am UTC](https://forum.suricata.io/t/rule-with-flow-option-only-stream-never-seems-to-match-anything/1655/4 "2021-08-26T10:42:14Z")

</div>

Wow, you are right. When I use your rule with the added content, then I actually get matches as well.

Yes, it seems like that is actually the case for the _only\_stream_ flag. However I still think it’s at least not really consistent behaviour then. If the flag affects which buffers are used, then why does _no\_stream_ work differently? So currently the matching results look something like this for me:

```auto
flow:only_stream; --> no matches ever
flow:no_stream; --> matches all frames
flow:only_stream; content:" "; --> more matches than first rule
flow:no_stream; content:" "; --> less matches then second rule

```

which makes sense since you obviously can not get more then all / less than none matches. I guess _no\_stream_ does not affect the buffer which is used, therefore we still match on the individual packets and everything matches even without content matching. Still, it’s definitely not very intuitive to me, but thanks for the explanation / experimentation with the rules.
