From: Eric Leblond Date: Fri, 19 Sep 2014 14:54:00 +0000 (+0200) Subject: af-packet: force suricata in IPS mode when needed X-Git-Tag: suricata-2.1beta2~104 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1e36053eca47c56bc8fc47287a09de3a49bbb507;p=thirdparty%2Fsuricata.git af-packet: force suricata in IPS mode when needed AF_PACKET is not setting the engine mode to IPS when some interfaces are peered and use IPS mode. This is due to the fact, it is possible to peer 2 interfaces and run an IPS on them and have a third one that is running in normal IDS mode. In fact this choice is the bad one as unwanted side effect is that there is no drop log and that stream inline is not used. To fix that, this patch puts suricata in IPS mode as soon as there is two interfaces in IPS mode. And it displays a error message to warn user that the accuracy of detection on IDS only interfaces will be low. --- diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index 51d6ea4303..0388aafab6 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -333,6 +333,76 @@ int AFPConfigGeThreadsCount(void *conf) return afp->threads; } +int AFPRunModeIsIPS() +{ + int nlive = LiveGetDeviceCount(); + int ldev; + ConfNode *if_root; + ConfNode *if_default = NULL; + ConfNode *af_packet_node; + int has_ips = 0; + int has_ids = 0; + + /* Find initial node */ + af_packet_node = ConfGetNode("af-packet"); + if (af_packet_node == NULL) { + return 0; + } + + if_default = ConfNodeLookupKeyValue(af_packet_node, "interface", "default"); + + for (ldev = 0; ldev < nlive; ldev++) { + char *live_dev = LiveGetDeviceName(ldev); + char *copymodestr = NULL; + if_root = ConfNodeLookupKeyValue(af_packet_node, "interface", live_dev); + + if (if_root == NULL) { + if (if_default == NULL) { + SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); + return 0; + } + if_root = if_default; + } + + if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) { + if (strcmp(copymodestr, "ips") == 0) { + has_ips = 1; + } else { + has_ids = 1; + } + } else { + has_ids = 1; + } + } + + if (has_ids && has_ips) { + SCLogInfo("AF_PACKET mode using IPS and IDS mode"); + for (ldev = 0; ldev < nlive; ldev++) { + char *live_dev = LiveGetDeviceName(ldev); + if_root = ConfNodeLookupKeyValue(af_packet_node, "interface", live_dev); + char *copymodestr = NULL; + + if (if_root == NULL) { + if (if_default == NULL) { + SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); + return 0; + } + if_root = if_default; + } + + if (! ((ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) && + (strcmp(copymodestr, "ips") == 0))) { + SCLogError(SC_ERR_INVALID_ARGUMENT, + "AF_PACKET IPS mode used and interface '%s' is in IDS or TAP mode. " + "Sniffing '%s' but expect bad result as stream-inline is activated.", + live_dev, live_dev); + } + } + } + + return has_ips; +} + /** * \brief RunModeIdsAFPAuto set up the following thread packet handlers: * - Receive thread (from live iface) diff --git a/src/runmode-af-packet.h b/src/runmode-af-packet.h index b6637861ac..0e1c764dd7 100644 --- a/src/runmode-af-packet.h +++ b/src/runmode-af-packet.h @@ -29,5 +29,6 @@ int RunModeIdsAFPAutoFp(DetectEngineCtx *); int RunModeIdsAFPWorkers(DetectEngineCtx *); void RunModeIdsAFPRegister(void); const char *RunModeAFPGetDefaultMode(void); +int AFPRunModeIsIPS(); #endif /* __RUNMODE_AF_PACKET_H__ */ diff --git a/src/suricata.c b/src/suricata.c index a42e597ed5..9549827939 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -993,6 +993,10 @@ static TmEcode ParseInterfacesList(int run_mode, char *pcap_dev) SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for af-packet"); SCReturnInt(TM_ECODE_FAILED); } + if (AFPRunModeIsIPS()) { + SCLogInfo("AF_PACKET: Setting IPS mode"); + EngineModeSetIPS(); + } } #ifdef HAVE_NFLOG } else if (run_mode == RUNMODE_NFLOG) {