]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
decode/ipv4: add missing ip-in-ip case handling
authorJuliana Fajardini <jufajardini@oisf.net>
Fri, 13 Jun 2025 23:49:50 +0000 (20:49 -0300)
committerVictor Julien <victor@inliniac.net>
Fri, 8 Aug 2025 06:16:49 +0000 (08:16 +0200)
A flow with IPv4 IP in IP traffic won't handle this tunneling case
properly.
This leads to potential malicious traffic not triggering alerts, as well
as other inaccuracies in the logs.

Bug #7725

(cherry-picked from commit e3e24cfb3d6382507aaf390bf697efae9c5f6c64)

doc/userguide/configuration/suricata-yaml.rst
src/decode-ipv4.c
src/decode-ipv4.h
src/decode.c
suricata.yaml.in

index 2482d69ba78e4556ba156ea4da5e17052e0ea3c9..45a20b5355b7f495e3c715a561bfb667cf74a464 100644 (file)
@@ -2788,6 +2788,27 @@ Using this default configuration, Teredo detection will run on UDP port
 3544. If the `ports` parameter is missing, or set to `any`, all ports will be
 inspected for possible presence of Teredo.
 
+IP-in-IP
+~~~~~~~~
+
+IPv4
+^^^^
+
+Enable decoding IP-in-IP tunneling for IPv4. There is also a dedicated option to
+set the parent flow for packets, when the engine sees such IP-in-IP packets. This
+option can be enabled regardless of enabled the ipip tunneling.
+As this may impact signature matching and flow tracking, these are disabled by default.
+
+::
+
+   # IP-in-IP tunneling for ipv4 over ipv4 handling.
+   # Disabled by default, as these will impact number of alerts seen, as well as
+   # number of flows.
+   # ipv4:
+   #   ipip:
+   #     enabled: true
+   #     track-parent-flow: true   # disabled by default
+
 Advanced Options
 ----------------
 
index c1bb9cce4731887956f3b932c08b37619bc8a646..03c78a76437ec58c729cf37472d7f133aec63183 100644 (file)
 #include "flow.h"
 #include "util-print.h"
 
+static bool g_ipv4_ipip_enabled = false;
+static bool g_ipv4_ipip_parent_flow_enabled = false;
+
+void DecodeIPV4IpInIpConfig(void)
+{
+    int enabled = 0;
+
+    if (ConfGetBool("decoder.ipv4.ipip.enabled", &enabled) == 1) {
+        if (enabled) {
+            g_ipv4_ipip_enabled = true;
+        } else {
+            g_ipv4_ipip_enabled = false;
+        }
+        enabled = 0;
+    }
+    if (ConfGetBool("decoder.ipv4.ipip.track-parent-flow", &enabled) == 1) {
+        if (enabled) {
+            g_ipv4_ipip_parent_flow_enabled = true;
+        } else {
+            g_ipv4_ipip_parent_flow_enabled = false;
+        }
+    }
+}
+
 /* Generic validation
  *
  * [--type--][--len---]
@@ -585,7 +609,22 @@ int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
         case IPPROTO_ESP:
             DecodeESP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
             break;
-
+        case IPPROTO_IPIP: {
+            /* optional in Suricata 7 as it wasn't always present */
+            if (g_ipv4_ipip_enabled) {
+                /* spawn off tunnel packet */
+                Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
+                        IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), DECODE_TUNNEL_IPV4);
+                if (tp != NULL) {
+                    PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4);
+                    PacketEnqueueNoLock(&tv->decode_pq, tp);
+                }
+            }
+            if (g_ipv4_ipip_parent_flow_enabled) {
+                FlowSetupPacket(p);
+            }
+            break;
+        }
         case IPPROTO_IPV6:
             {
                 /* spawn off tunnel packet */
index a825007c20bcc73f1f3929daecd6d89d7cc9155d..36c171e8031ee99d9a9c027897b81914c2204f3a 100644 (file)
@@ -176,6 +176,7 @@ typedef struct IPV4Vars_
     uint16_t opts_set;
 } IPV4Vars;
 
+void DecodeIPV4IpInIpConfig(void);
 
 void DecodeIPV4RegisterTests(void);
 
index ff06929cca32afdcdce02a3c5f6b90ee1e55818b..f28f7e137f7d68158042363b9bfa544474b48059 100644 (file)
@@ -918,6 +918,7 @@ void CaptureStatsSetup(ThreadVars *tv)
 
 void DecodeGlobalConfig(void)
 {
+    DecodeIPV4IpInIpConfig();
     DecodeTeredoConfig();
     DecodeGeneveConfig();
     DecodeVXLANConfig();
index bcf861ae53913d69ea05582d1de3f967ced67f45..c7a2f1f156d5e8810360cec84a899a4b53d71cad 100644 (file)
@@ -1672,6 +1672,14 @@ decoder:
   # maximum number of decoder layers for a packet
   # max-layers: 16
 
+  # IP-in-IP tunneling for ipv4 over ipv4 handling.
+  # Disabled by default, as these will impact number of alerts seen, as well as
+  # number of flows.
+  # ipv4:
+  #   ipip:
+  #     enabled: true
+  #     track-parent-flow: true   # disabled by default
+
 ##
 ## Performance tuning and profiling
 ##