From: Juliana Fajardini Date: Wed, 17 Aug 2022 14:39:33 +0000 (-0300) Subject: stream: add exception policy for midstream flows X-Git-Tag: suricata-6.0.7~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05378946dc7d01dbf23f8287a0df9c6c8f680b2c;p=thirdparty%2Fsuricata.git stream: add exception policy for midstream flows 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) --- diff --git a/src/decode.c b/src/decode.c index e7317a66af..db7cefa9ec 100644 --- a/src/decode.c +++ b/src/decode.c @@ -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: diff --git a/src/decode.h b/src/decode.h index 308774c970..223e3c67ef 100644 --- a/src/decode.h +++ b/src/decode.h @@ -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 */ diff --git a/src/stream-tcp.c b/src/stream-tcp.c index a1d0ee3c37..be9b7582da 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -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); diff --git a/src/stream-tcp.h b/src/stream-tcp.h index cb1388e7f0..cba7ea1fba 100644 --- a/src/stream-tcp.h +++ b/src/stream-tcp.h @@ -66,6 +66,7 @@ typedef struct TcpStreamCnf_ { enum ExceptionPolicy ssn_memcap_policy; enum ExceptionPolicy reassembly_memcap_policy; + enum ExceptionPolicy midstream_policy; StreamingBufferConfig sbcnf; } TcpStreamCnf;