From 703350ffdb89db36a131194717c8381798a0c66f Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Tue, 2 Aug 2016 18:52:28 -0700 Subject: [PATCH] Add ability to disable rules. The main change was to start passing the rule name around when adding a rule. That way, you can use the same name to the new method falco_engine::enable_rule() which takes a rule name and a bool enabled flag. New falco command line option -D allows you to disable one or more rules on the command line. This depends on changes in https://github.com/draios/sysdig/pull/640. --- userspace/engine/falco_engine.cpp | 18 +++++++++++++++--- userspace/engine/falco_engine.h | 8 +++++++- userspace/engine/lua/rule_loader.lua | 2 +- userspace/engine/rules.cpp | 13 ++++++++----- userspace/engine/rules.h | 2 +- userspace/falco/falco.cpp | 16 +++++++++++++++- 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/userspace/engine/falco_engine.cpp b/userspace/engine/falco_engine.cpp index 0ba6e8be62b..05ae022511e 100644 --- a/userspace/engine/falco_engine.cpp +++ b/userspace/engine/falco_engine.cpp @@ -50,7 +50,10 @@ void falco_engine::load_rules(const string &rules_content, bool verbose) falco_common::init(m_lua_main_filename.c_str(), FALCO_ENGINE_SOURCE_LUA_DIR); falco_rules::init(m_ls); - m_rules = new falco_rules(m_inspector, this, m_ls); + if(!m_rules) + { + m_rules = new falco_rules(m_inspector, this, m_ls); + } m_rules->load_rules(rules_content, verbose); } @@ -72,6 +75,14 @@ void falco_engine::load_rules_file(const string &rules_filename, bool verbose) load_rules(rules_content, verbose); } +void falco_engine::enable_rule(string &rule, bool enabled) +{ + if(!m_evttype_filter.enable(rule, enabled)) + { + throw falco_exception("No rule with name " + rule + " found"); + } +} + falco_engine::rule_result *falco_engine::process_event(sinsp_evt *ev) { @@ -140,10 +151,11 @@ void falco_engine::print_stats() } -void falco_engine::add_evttype_filter(list &evttypes, +void falco_engine::add_evttype_filter(string &rule, + list &evttypes, sinsp_filter* filter) { - m_evttype_filter.add(evttypes, filter); + m_evttype_filter.add(rule, evttypes, filter); } void falco_engine::set_sampling_ratio(uint32_t sampling_ratio) diff --git a/userspace/engine/falco_engine.h b/userspace/engine/falco_engine.h index 27f207d41b5..b56bf86c433 100644 --- a/userspace/engine/falco_engine.h +++ b/userspace/engine/falco_engine.h @@ -27,6 +27,11 @@ class falco_engine : public falco_common void load_rules_file(const std::string &rules_filename, bool verbose); void load_rules(const std::string &rules_content, bool verbose); + // + // Enable/Disable any given rule. + // + void enable_rule(std::string &rule, bool enabled); + struct rule_result { sinsp_evt *evt; std::string rule; @@ -57,7 +62,8 @@ class falco_engine : public falco_common // Add a filter, which is related to the specified list of // event types, to the engine. // - void add_evttype_filter(list &evttypes, + void add_evttype_filter(std::string &rule, + list &evttypes, sinsp_filter* filter); // diff --git a/userspace/engine/lua/rule_loader.lua b/userspace/engine/lua/rule_loader.lua index e41bc5db1dc..4caec1a1b62 100644 --- a/userspace/engine/lua/rule_loader.lua +++ b/userspace/engine/lua/rule_loader.lua @@ -174,7 +174,7 @@ function load_rules(rules_content, rules_mgr, verbose, all_events) install_filter(filter_ast.filter.value) -- Pass the filter and event types back up - falco_rules.add_filter(rules_mgr, evttypes) + falco_rules.add_filter(rules_mgr, v['rule'], evttypes) -- Rule ASTs are merged together into one big AST, with "OR" between each -- rule. diff --git a/userspace/engine/rules.cpp b/userspace/engine/rules.cpp index 808fa9f3844..04078ba0700 100644 --- a/userspace/engine/rules.cpp +++ b/userspace/engine/rules.cpp @@ -27,13 +27,15 @@ void falco_rules::init(lua_State *ls) int falco_rules::add_filter(lua_State *ls) { - if (! lua_islightuserdata(ls, -2) || + if (! lua_islightuserdata(ls, -3) || + ! lua_isstring(ls, -2) || ! lua_istable(ls, -1)) { throw falco_exception("Invalid arguments passed to add_filter()\n"); } - falco_rules *rules = (falco_rules *) lua_topointer(ls, -2); + falco_rules *rules = (falco_rules *) lua_topointer(ls, -3); + const char *rulec = lua_tostring(ls, -2); list evttypes; @@ -47,19 +49,20 @@ int falco_rules::add_filter(lua_State *ls) lua_pop(ls, 1); } - rules->add_filter(evttypes); + std::string rule = rulec; + rules->add_filter(rule, evttypes); return 0; } -void falco_rules::add_filter(list &evttypes) +void falco_rules::add_filter(string &rule, list &evttypes) { // While the current rule was being parsed, a sinsp_filter // object was being populated by lua_parser. Grab that filter // and pass it to the engine. sinsp_filter *filter = m_lua_parser->get_filter(true); - m_engine->add_evttype_filter(evttypes, filter); + m_engine->add_evttype_filter(rule, evttypes, filter); } void falco_rules::load_rules(const string &rules_content, bool verbose, bool all_events) diff --git a/userspace/engine/rules.h b/userspace/engine/rules.h index 45ff11b3b3d..8f2ef6d8382 100644 --- a/userspace/engine/rules.h +++ b/userspace/engine/rules.h @@ -20,7 +20,7 @@ class falco_rules static int add_filter(lua_State *ls); private: - void add_filter(list &evttypes); + void add_filter(string &rule, list &evttypes); lua_parser* m_lua_parser; sinsp* m_inspector; diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index a34bffd41c0..30de950f9f4 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -41,6 +41,7 @@ static void usage() " -p, --pidfile When run as a daemon, write pid to specified file\n" " -e Read the events from (in .scap format) instead of tapping into live.\n" " -r Rules file (defaults to value set in configuration file, or /etc/falco_rules.yaml).\n" + " -D Disable the rule with name . Can be specified multiple times.\n" " -L Show the name and description of all rules and exit.\n" " -l Show the name and description of the rule with name and exit.\n" " -v Verbose output.\n" @@ -166,11 +167,14 @@ int falco_init(int argc, char **argv) outputs = new falco_outputs(); outputs->set_inspector(inspector); + set disabled_rules; + string rule; + // // Parse the args // while((op = getopt_long(argc, argv, - "c:ho:e:r:dp:Ll:vA", + "c:ho:e:r:D:dp:Ll:vA", long_options, &long_index)) != -1) { switch(op) @@ -190,6 +194,10 @@ int falco_init(int argc, char **argv) case 'r': rules_filename = optarg; break; + case 'D': + rule = optarg; + disabled_rules.insert(rule); + break; case 'd': daemon = true; break; @@ -274,6 +282,12 @@ int falco_init(int argc, char **argv) falco_logger::log(LOG_INFO, "Parsed rules from file " + rules_filename + "\n"); + for (auto rule : disabled_rules) + { + falco_logger::log(LOG_INFO, "Disabling rule: " + rule + "\n"); + engine->enable_rule(rule, false); + } + outputs->init(config.m_json_output); if(!all_events)