some quick notes on rule optimization. I did an exercise where I showed readers how to track long-running TLS sessions with relatively small TCP payloads.
I framed it towards possible detection of DoH servers, but this can also maybe catch poorly configured malware that is just shitting out TLS ping/pong beacons as well.
Un-optimized, these rules took over 120 million CPU ticks to process an 8.4MB pcap. Optimized with prefilter, and hyperscan support, we dropped that to under 35 million ticks in total. An order of magnitude less, thanks to far fewer prefilter checks.
This exercise is also a small introduction to using non fast_pattern prefilter keywords as well.
Suricata operates on creating chains of rules, and, by default, prefilters those rules based on the content match that is defined as the fast_pattern for that rule. By changing the prefilter default directive to "auto". that enables us to use something other than a content match as the prefilter criteria for a rule. In this case, one rule used dsize (payload size), and the other used flow.age (stream duration in seconds) as its prefilter.
I also enabled hyperscan support in this test, further boosting the pattern matching engine's performance in exchange for small delay on startup for hyperscan to build its cache.
The performance is still fucking garbage, but much much much less so.


