Add support for tagging rules.

- in lua, look for a tags attribute to each rule. This is passed up in
  add_filter as a tags argument (as a lua table). If not present, an
  empty table is used. The tags table is iterated to populate a set
  of tags as strings, which is passed to add_filter().
- A new method falco_engine::enable_rule_by_tag is similar to
  enable_rule(), but is given a set of tag strings. Any rules containing
  one of the tags is enabled/disabled.
- The list of event types has been changed to a set to more accurately
  reflect its purpose.
- New argument to falco -T allows disabling all rules matching a given
  tag, via enable_rule_by_tag(). It can be provided multiple times.
- New argument to falco -t allows running those rules matching a given
  tag. If provided all rules are first disabled. It can be
  provided multiple times, but can not be combined with -T or
  -D (disable rules by name)
- falco_enging supports the notion of a ruleset. The idea is that you
  can choose a set of rules that are enabled/disabled by using
  enable_rule()/enable_rule_by_tag() in combination with a
  ruleset. Later, in process_event() you include that ruleset and the
  rules you had previously enabled will be run.
- rulsets are provided as strings in enable_rule()/enable_rule_by_tag()
  and as numbers in process_event()--this avoids the overhead of string
  lookups per-event. Ruleset ids are created on the fly as needed. A
  utility method find_ruleset_id() looks up the ruleset id for a given
  name. The default ruleset is NULL string/0 numeric if not provided.
- Although the ruleset is a useful falco engine feature, it isn't that
  important to the falco standalone program, so it's not
  documented. However, you can change the ruleset by providing
  FALCO_RULESET in the environment.
This commit is contained in:
Mark Stemm
2017-02-03 18:08:48 -08:00
parent 1e205db8aa
commit a0a6914b6a
6 changed files with 172 additions and 30 deletions

View File

@@ -40,7 +40,8 @@ string lua_print_stats = "print_stats";
using namespace std;
falco_engine::falco_engine(bool seed_rng)
: m_rules(NULL), m_sampling_ratio(1), m_sampling_multiplier(0),
: m_rules(NULL), m_next_ruleset_id(0),
m_sampling_ratio(1), m_sampling_multiplier(0),
m_replace_container_info(false)
{
luaopen_lpeg(m_ls);
@@ -107,20 +108,51 @@ void falco_engine::load_rules_file(const string &rules_filename, bool verbose, b
load_rules(rules_content, verbose, all_events);
}
void falco_engine::enable_rule(string &pattern, bool enabled)
void falco_engine::enable_rule(string &pattern, bool enabled, string *ruleset)
{
m_evttype_filter->enable(pattern, enabled);
uint16_t ruleset_id = 0;
if(ruleset)
{
ruleset_id = find_ruleset_id(*ruleset);
}
m_evttype_filter->enable(pattern, enabled, ruleset_id);
}
unique_ptr<falco_engine::rule_result> falco_engine::process_event(sinsp_evt *ev)
void falco_engine::enable_rule_by_tag(set<string> &tags, bool enabled, string *ruleset)
{
uint16_t ruleset_id = 0;
if(ruleset)
{
ruleset_id = find_ruleset_id(*ruleset);
}
m_evttype_filter->enable_tags(tags, enabled, ruleset_id);
}
uint16_t falco_engine::find_ruleset_id(std::string &ruleset)
{
auto it = m_known_rulesets.find(ruleset);
if(it == m_known_rulesets.end())
{
m_known_rulesets[ruleset] = ++m_next_ruleset_id;
it = m_known_rulesets.find(ruleset);
}
return it->second;
}
unique_ptr<falco_engine::rule_result> falco_engine::process_event(sinsp_evt *ev, uint16_t ruleset_id)
{
if(should_drop_evt())
{
return unique_ptr<struct rule_result>();
}
if(!m_evttype_filter->run(ev))
if(!m_evttype_filter->run(ev, ruleset_id))
{
return unique_ptr<struct rule_result>();
}
@@ -182,10 +214,11 @@ void falco_engine::print_stats()
}
void falco_engine::add_evttype_filter(string &rule,
list<uint32_t> &evttypes,
set<uint32_t> &evttypes,
set<string> &tags,
sinsp_filter* filter)
{
m_evttype_filter->add(rule, evttypes, filter);
m_evttype_filter->add(rule, evttypes, tags, filter);
}
void falco_engine::clear_filters()