From: Victor Julien Date: Wed, 2 Mar 2016 12:37:14 +0000 (+0100) Subject: detect: make port whitelisting configurable X-Git-Tag: suricata-3.1RC1~305 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6ba01b1b73dfccc6ee009f5ce3d0880cbc2b6d1;p=thirdparty%2Fsuricata.git detect: make port whitelisting configurable 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. --- diff --git a/src/detect-engine.c b/src/detect-engine.c index e66035e25f..fb06a7c0f3 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -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; diff --git a/src/detect.c b/src/detect.c index fd99ed761a..3f3ff4164d 100644 --- a/src/detect.c +++ b/src/detect.c @@ -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); diff --git a/src/detect.h b/src/detect.h index c4f98f3159..2aa20bfa8b 100644 --- a/src/detect.h +++ b/src/detect.h @@ -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) */ diff --git a/suricata.yaml.in b/suricata.yaml.in index a9db90babb..e428f10699 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -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