]> 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)
committerJuliana Fajardini <jufajardini@oisf.net>
Tue, 30 Aug 2022 02:13:45 +0000 (23:13 -0300)
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

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

index df0c6ab37bbe2298388801a427e8ec8075cf16a9..f7fb514123327c3610200d80c46d0ab7008e9e06 100644 (file)
@@ -797,6 +797,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 b87366644ad493bba96825c88d5920c821f87dd4..e205cb195b8a7339b74fd290fd05fd87cedb683c 100644 (file)
@@ -402,12 +402,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 8303202079eeb578620ed62474c88f709f32935e..ddbbeb4ed30c5a7c0d6870f9c806c7c969180995 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2021 Open Information Security Foundation
+/* Copyright (C) 2007-2022 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -468,6 +468,7 @@ void StreamTcpInitConfig(bool 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);
 
     if (!quiet) {
         SCLogConfig("stream.\"inline\": %s",
@@ -923,9 +924,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 && 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 && 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);
@@ -1085,8 +1098,20 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p,
                 ssn->client.last_ack);
 
     } else if (p->tcph->th_flags & TH_ACK) {
-        if (!stream_config.midstream)
+        /* 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) {
+            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 cb4d19bcba17758cf3ffb589bf87e0e68cc3eb6a..a2d857ee1fc54019c5cd29d99050b596b74e284a 100644 (file)
@@ -67,6 +67,7 @@ typedef struct TcpStreamCnf_ {
 
     enum ExceptionPolicy ssn_memcap_policy;
     enum ExceptionPolicy reassembly_memcap_policy;
+    enum ExceptionPolicy midstream_policy;
 
     StreamingBufferConfig sbcnf;
 } TcpStreamCnf;