]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: make port whitelisting configurable
authorVictor Julien <victor@inliniac.net>
Wed, 2 Mar 2016 12:37:14 +0000 (13:37 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 5 Apr 2016 07:37:42 +0000 (09:37 +0200)
Make the port grouping whitelisting configurable. A whitelisted port
ends up in it's own port group.

detect:
  grouping:
    tcp-whitelist: 80, 443
    udp-whitelist: 53, 5060

No portranges are allowed at this point.

src/detect-engine.c
src/detect.c
src/detect.h
suricata.yaml.in

index e66035e25fe76bfc8caf0ddde00ccea3ffa768ac..fb06a7c0f35bc63dd17907d1ae1ad2b1003a9351 100644 (file)
@@ -957,6 +957,9 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx)
 #endif
     }
 
+    DetectPortCleanupList(de_ctx->tcp_whitelist);
+    DetectPortCleanupList(de_ctx->udp_whitelist);
+
     SCFree(de_ctx);
     //DetectAddressGroupPrintMemory();
     //DetectSigGroupPrintMemory();
@@ -1181,6 +1184,55 @@ static int DetectEngineCtxLoadConf(DetectEngineCtx *de_ctx)
     SCLogDebug("de_ctx->inspection_recursion_limit: %d",
                de_ctx->inspection_recursion_limit);
 
+    /* parse port grouping whitelisting settings */
+
+    char *ports = NULL;
+    (void)ConfGet("detect.grouping.tcp-whitelist", &ports);
+    if (ports) {
+        SCLogInfo("grouping: tcp-whitelist %s", ports);
+    } else {
+        ports = "53, 80, 139, 443, 445, 1433, 3306, 3389, 6666, 6667, 8080";
+        SCLogInfo("grouping: tcp-whitelist (default) %s", ports);
+
+    }
+    if (DetectPortParse(de_ctx, &de_ctx->tcp_whitelist, ports) != 0) {
+        SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY, "'%s' is not a valid value "
+                "for detect.grouping.tcp-whitelist", ports);
+    }
+    DetectPort *x = de_ctx->tcp_whitelist;
+    for ( ; x != NULL;  x = x->next) {
+        if (x->port != x->port2) {
+            SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY, "'%s' is not a valid value "
+                "for detect.grouping.tcp-whitelist: only single ports allowed", ports);
+            DetectPortCleanupList(de_ctx->tcp_whitelist);
+            de_ctx->tcp_whitelist = NULL;
+            break;
+        }
+    }
+
+    ports = NULL;
+    (void)ConfGet("detect.grouping.udp-whitelist", &ports);
+    if (ports) {
+        SCLogInfo("grouping: udp-whitelist %s", ports);
+    } else {
+        ports = "53, 135, 5060";
+        SCLogInfo("grouping: udp-whitelist (default) %s", ports);
+
+    }
+    if (DetectPortParse(de_ctx, &de_ctx->udp_whitelist, ports) != 0) {
+        SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY, "'%s' is not a valid value "
+                "forr detect.grouping.udp-whitelist", ports);
+    }
+    for (x = de_ctx->udp_whitelist; x != NULL;  x = x->next) {
+        if (x->port != x->port2) {
+            SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY, "'%s' is not a valid value "
+                "for detect.grouping.udp-whitelist: only single ports allowed", ports);
+            DetectPortCleanupList(de_ctx->udp_whitelist);
+            de_ctx->udp_whitelist = NULL;
+            break;
+        }
+    }
+
     return 0;
 error:
     return -1;
index fd99ed761ae7e03768eb3c171bb1d6cea6ee0621..3f3ff4164d9c0a280067a30f280d89573770387a 100644 (file)
@@ -3295,19 +3295,19 @@ int RulesGroupByProto(DetectEngineCtx *de_ctx)
     return 0;
 }
 
-int tcp_whitelisted[] = { 53, 80, 139, 443, 445, 1433, 3306, 3389, 6666, 6667, 8080, -1 };
-int udp_whitelisted[] = { 53, 135, 5060, -1 };
-
-static int PortIsWhitelisted(const DetectPort *a, int ipproto)
+static int PortIsWhitelisted(const DetectEngineCtx *de_ctx,
+                             const DetectPort *a, int ipproto)
 {
-    int *w = tcp_whitelisted;
+    DetectPort *w = de_ctx->tcp_whitelist;
     if (ipproto == IPPROTO_UDP)
-        w = udp_whitelisted;
-    while (*w++ != -1) {
-        if (a->port >= *w && a->port2 <= *w) {
-            SCLogDebug("port group %u:%u whitelisted -> %d", a->port, a->port2, *w);
+        w = de_ctx->udp_whitelist;
+
+    while (w) {
+        if (a->port >= w->port && a->port2 <= w->port) {
+            SCLogDebug("port group %u:%u whitelisted -> %d", a->port, a->port2, w->port);
             return 1;
         }
+        w = w->next;
     }
 
     return 0;
@@ -3406,7 +3406,7 @@ static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, int ipproto, uint3
 
         int wl = s->whitelist;
         while (p) {
-            int pwl = PortIsWhitelisted(p, ipproto) ? 111 : 0;
+            int pwl = PortIsWhitelisted(de_ctx, p, ipproto) ? 111 : 0;
             pwl = MAX(wl,pwl);
 
             DetectPort *lookup = DetectPortHashLookup(de_ctx, p);
index c4f98f3159e564e86a058c649adcc537bff1689e..2aa20bfa8bd933bf4347ff91b3485858d26234a5 100644 (file)
@@ -667,6 +667,9 @@ typedef struct DetectEngineCtx_ {
 
     HashListTable *dport_hash_table;
 
+    DetectPort *tcp_whitelist;
+    DetectPort *udp_whitelist;
+
 } DetectEngineCtx;
 
 /* Engine groups profiles (low, medium, high, custom) */
index a9db90babb6efc203629aa8fd5f4a609a0ad17f4..e428f106993997db64dcbf0341546cc3e7497a96 100644 (file)
@@ -602,6 +602,14 @@ detect:
   # is started. This will limit the downtime in IPS mode.
   #delayed-detect: yes
 
+  # the grouping values above control how many groups are created per
+  # direction. Port whitelisting forces that port to get it's own group.
+  # Very common ports will benefit, as well as ports with many expensive
+  # rules.
+  grouping:
+    #tcp-whitelist: 53, 80, 139, 443, 445, 1433, 3306, 3389, 6666, 6667, 8080
+    #udp-whitelist: 53, 135, 5060
+
   profiling:
     # Log the rules that made it past the prefilter stage, per packet
     # default is off. The threshold setting determines how many rules