]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: add exception policy for midstream flows
authorJuliana Fajardini <jufajardini@oisf.net>
Wed, 17 Aug 2022 14:39:33 +0000 (11:39 -0300)
committerVictor Julien <vjulien@oisf.net>
Sat, 3 Sep 2022 12:22:06 +0000 (14:22 +0200)
This allows to set a midstream-policy that can:
- fail closed (stream.midstream-policy=drop-flow)
- fail open (stream.midstream-policy=pass-flow)
- bypass stream (stream.midstream-policy=bypass)
- do nothing (default behavior)

Usage and behavior:

If stream.midstream-policy is set then if Suricata identifies a midstream flow
it will apply the corresponding action associated with the policy.

No setting means Suricata will not apply such policies, either inspecting the
flow (if stream.midstream=true) or ignoring it stream.midstream=false.

Task #5468

(cherry picked from commit aa5bb2c329aff59b7811b43258ffd4d95fe7364f)

src/decode.c
src/decode.h
src/stream-tcp.c
src/stream-tcp.h

index e7317a66af1733b1d750fa63c9ed1ab7b6d0e20d..db7cefa9ecc175000287a9202b48c635c65deece 100644 (file)
@@ -783,6 +783,8 @@ const char *PacketDropReasonToString(enum PacketDropReason r)
             return "stream error";
         case PKT_DROP_REASON_STREAM_MEMCAP:
             return "stream memcap";
+        case PKT_DROP_REASON_STREAM_MIDSTREAM:
+            return "stream midstream";
         case PKT_DROP_REASON_APPLAYER_ERROR:
             return "applayer error";
         case PKT_DROP_REASON_APPLAYER_MEMCAP:
index 308774c97031eba1a7bbb37562b977992d5797ae..223e3c67ef44abb67dae74e4b2c8132f2225ad13 100644 (file)
@@ -404,12 +404,13 @@ enum PacketDropReason {
     PKT_DROP_REASON_DEFRAG_MEMCAP,
     PKT_DROP_REASON_FLOW_MEMCAP,
     PKT_DROP_REASON_FLOW_DROP,
-    PKT_DROP_REASON_STREAM_ERROR,
-    PKT_DROP_REASON_STREAM_MEMCAP,
     PKT_DROP_REASON_APPLAYER_ERROR,
     PKT_DROP_REASON_APPLAYER_MEMCAP,
     PKT_DROP_REASON_RULES,
     PKT_DROP_REASON_RULES_THRESHOLD, /**< detection_filter in action */
+    PKT_DROP_REASON_STREAM_ERROR,
+    PKT_DROP_REASON_STREAM_MEMCAP,
+    PKT_DROP_REASON_STREAM_MIDSTREAM,
 };
 
 /* forward declaration since Packet struct definition requires this */
index a1d0ee3c3745a6c33d7ec63c9121db2a9aca77b4..be9b7582daa3150529cbc2c62f570af22067a881 100644 (file)
@@ -474,6 +474,7 @@ void StreamTcpInitConfig(char quiet)
     stream_config.ssn_memcap_policy = ExceptionPolicyParse("stream.memcap-policy", true);
     stream_config.reassembly_memcap_policy =
             ExceptionPolicyParse("stream.reassembly.memcap-policy", true);
+    stream_config.midstream_policy = ExceptionPolicyParse("stream.midstream-policy", true);
     SCLogConfig("memcap-policy: %u/%u", stream_config.ssn_memcap_policy,
             stream_config.reassembly_memcap_policy);
 
@@ -933,10 +934,21 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p,
         return -1;
 
     /* SYN/ACK */
-    } else if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) {
-        if (stream_config.midstream == FALSE &&
-                stream_config.async_oneside == FALSE)
+    } else if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
+        /* Drop reason will only be used if midstream policy is set to fail closed */
+        ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM);
+
+        if (stream_config.midstream == FALSE && stream_config.async_oneside == FALSE) {
+            SCLogDebug("Midstream not enabled, so won't pick up a session");
             return 0;
+        }
+        if (!(stream_config.midstream_policy == EXCEPTION_POLICY_IGNORE ||
+                    stream_config.midstream_policy == EXCEPTION_POLICY_PASS_FLOW ||
+                    stream_config.midstream_policy == EXCEPTION_POLICY_PASS_PACKET)) {
+            SCLogDebug("Midstream policy not permissive, so won't pick up a session");
+            return 0;
+        }
+        SCLogDebug("midstream picked up");
 
         if (ssn == NULL) {
             ssn = StreamTcpNewSession(p, stt->ssn_pool_id);
@@ -1094,8 +1106,20 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p,
                 ssn->client.last_ack);
 
     } else if (p->tcph->th_flags & TH_ACK) {
-        if (stream_config.midstream == FALSE)
+        /* Drop reason will only be used if midstream policy is set to fail closed */
+        ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM);
+
+        if (stream_config.midstream == FALSE) {
+            SCLogDebug("Midstream not enabled, so won't pick up a session");
+            return 0;
+        }
+        if (!(stream_config.midstream_policy == EXCEPTION_POLICY_IGNORE ||
+                    stream_config.midstream_policy == EXCEPTION_POLICY_PASS_FLOW ||
+                    stream_config.midstream_policy == EXCEPTION_POLICY_PASS_PACKET)) {
+            SCLogDebug("Midstream policy not permissive, so won't pick up a session");
             return 0;
+        }
+        SCLogDebug("midstream picked up");
 
         if (ssn == NULL) {
             ssn = StreamTcpNewSession(p, stt->ssn_pool_id);
index cb1388e7f0f2357b36a6c1e5b653ae4263db3946..cba7ea1fba4295779d14152882ac83259c8f0140 100644 (file)
@@ -66,6 +66,7 @@ typedef struct TcpStreamCnf_ {
 
     enum ExceptionPolicy ssn_memcap_policy;
     enum ExceptionPolicy reassembly_memcap_policy;
+    enum ExceptionPolicy midstream_policy;
 
     StreamingBufferConfig sbcnf;
 } TcpStreamCnf;