From: Juliana Fajardini Date: Fri, 13 Jun 2025 23:49:50 +0000 (-0300) Subject: decode/ipv4: add missing ip-in-ip case handling X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=9939e29f6eb3d1161b12c6284b3bc7a54544c55b;p=thirdparty%2Fsuricata.git decode/ipv4: add missing ip-in-ip case handling 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) --- diff --git a/doc/userguide/configuration/suricata-yaml.rst b/doc/userguide/configuration/suricata-yaml.rst index 2482d69ba7..45a20b5355 100644 --- a/doc/userguide/configuration/suricata-yaml.rst +++ b/doc/userguide/configuration/suricata-yaml.rst @@ -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 ---------------- diff --git a/src/decode-ipv4.c b/src/decode-ipv4.c index c1bb9cce47..03c78a7643 100644 --- a/src/decode-ipv4.c +++ b/src/decode-ipv4.c @@ -38,6 +38,30 @@ #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 */ diff --git a/src/decode-ipv4.h b/src/decode-ipv4.h index a825007c20..36c171e803 100644 --- a/src/decode-ipv4.h +++ b/src/decode-ipv4.h @@ -176,6 +176,7 @@ typedef struct IPV4Vars_ uint16_t opts_set; } IPV4Vars; +void DecodeIPV4IpInIpConfig(void); void DecodeIPV4RegisterTests(void); diff --git a/src/decode.c b/src/decode.c index ff06929cca..f28f7e137f 100644 --- a/src/decode.c +++ b/src/decode.c @@ -918,6 +918,7 @@ void CaptureStatsSetup(ThreadVars *tv) void DecodeGlobalConfig(void) { + DecodeIPV4IpInIpConfig(); DecodeTeredoConfig(); DecodeGeneveConfig(); DecodeVXLANConfig(); diff --git a/suricata.yaml.in b/suricata.yaml.in index bcf861ae53..c7a2f1f156 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -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 ##