mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-12 13:07:49 +00:00
new(falco): implement rule selection configuration in falco.yaml
Signed-off-by: Luca Guerra <luca@guerra.sh>
This commit is contained in:
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
|
||||
#include "evttype_index_ruleset.h"
|
||||
|
||||
#include "falco_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
evttype_index_ruleset::evttype_index_ruleset(
|
||||
@@ -235,17 +237,17 @@ void evttype_index_ruleset::clear()
|
||||
m_filters.clear();
|
||||
}
|
||||
|
||||
void evttype_index_ruleset::enable(const std::string &substring, bool match_exact, uint16_t ruleset_id)
|
||||
void evttype_index_ruleset::enable(const std::string &pattern, match_type match, uint16_t ruleset_id)
|
||||
{
|
||||
enable_disable(substring, match_exact, true, ruleset_id);
|
||||
enable_disable(pattern, match, true, ruleset_id);
|
||||
}
|
||||
|
||||
void evttype_index_ruleset::disable(const std::string &substring, bool match_exact, uint16_t ruleset_id)
|
||||
void evttype_index_ruleset::disable(const std::string &pattern, match_type match, uint16_t ruleset_id)
|
||||
{
|
||||
enable_disable(substring, match_exact, false, ruleset_id);
|
||||
enable_disable(pattern, match, false, ruleset_id);
|
||||
}
|
||||
|
||||
void evttype_index_ruleset::enable_disable(const std::string &substring, bool match_exact, bool enabled, uint16_t ruleset_id)
|
||||
void evttype_index_ruleset::enable_disable(const std::string &pattern, match_type match, bool enabled, uint16_t ruleset_id)
|
||||
{
|
||||
while(m_rulesets.size() < (size_t)ruleset_id + 1)
|
||||
{
|
||||
@@ -255,17 +257,25 @@ void evttype_index_ruleset::enable_disable(const std::string &substring, bool ma
|
||||
for(const auto &wrap : m_filters)
|
||||
{
|
||||
bool matches;
|
||||
std::string::size_type pos;
|
||||
|
||||
if(match_exact)
|
||||
switch(match)
|
||||
{
|
||||
size_t pos = wrap->rule.name.find(substring);
|
||||
case match_type::exact:
|
||||
pos = wrap->rule.name.find(pattern);
|
||||
|
||||
matches = (substring == "" || (pos == 0 &&
|
||||
substring.size() == wrap->rule.name.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
matches = (substring == "" || (wrap->rule.name.find(substring) != std::string::npos));
|
||||
matches = (pattern == "" || (pos == 0 &&
|
||||
pattern.size() == wrap->rule.name.size()));
|
||||
break;
|
||||
case match_type::substring:
|
||||
matches = (pattern == "" || (wrap->rule.name.find(pattern) != std::string::npos));
|
||||
break;
|
||||
case match_type::wildcard:
|
||||
matches = falco::utils::matches_wildcard(pattern, wrap->rule.name);
|
||||
break;
|
||||
default:
|
||||
// should never happen
|
||||
matches = false;
|
||||
}
|
||||
|
||||
if(matches)
|
||||
|
@@ -53,13 +53,13 @@ public:
|
||||
void on_loading_complete() override;
|
||||
|
||||
void enable(
|
||||
const std::string &substring,
|
||||
bool match_exact,
|
||||
const std::string &pattern,
|
||||
match_type match,
|
||||
uint16_t rulset_id) override;
|
||||
|
||||
void disable(
|
||||
const std::string &substring,
|
||||
bool match_exact,
|
||||
const std::string &pattern,
|
||||
match_type match,
|
||||
uint16_t rulset_id) override;
|
||||
|
||||
void enable_tags(
|
||||
@@ -85,8 +85,8 @@ private:
|
||||
|
||||
// Helper used by enable()/disable()
|
||||
void enable_disable(
|
||||
const std::string &substring,
|
||||
bool match_exact,
|
||||
const std::string &pattern,
|
||||
match_type match,
|
||||
bool enabled,
|
||||
uint16_t rulset_id);
|
||||
|
||||
|
@@ -242,11 +242,11 @@ std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_c
|
||||
}
|
||||
if(info->enabled)
|
||||
{
|
||||
source->ruleset->enable(rule.name, true, m_default_ruleset_id);
|
||||
source->ruleset->enable(rule.name, filter_ruleset::match_type::exact, m_default_ruleset_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
source->ruleset->disable(rule.name, true, m_default_ruleset_id);
|
||||
source->ruleset->disable(rule.name, filter_ruleset::match_type::exact, m_default_ruleset_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,17 +272,15 @@ void falco_engine::enable_rule(const std::string &substring, bool enabled, const
|
||||
|
||||
void falco_engine::enable_rule(const std::string &substring, bool enabled, const uint16_t ruleset_id)
|
||||
{
|
||||
bool match_exact = false;
|
||||
|
||||
for(const auto &it : m_sources)
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
it.ruleset->enable(substring, match_exact, ruleset_id);
|
||||
it.ruleset->enable(substring, filter_ruleset::match_type::substring, ruleset_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
it.ruleset->disable(substring, match_exact, ruleset_id);
|
||||
it.ruleset->disable(substring, filter_ruleset::match_type::substring, ruleset_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,17 +294,37 @@ void falco_engine::enable_rule_exact(const std::string &rule_name, bool enabled,
|
||||
|
||||
void falco_engine::enable_rule_exact(const std::string &rule_name, bool enabled, const uint16_t ruleset_id)
|
||||
{
|
||||
bool match_exact = true;
|
||||
|
||||
for(const auto &it : m_sources)
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
it.ruleset->enable(rule_name, match_exact, ruleset_id);
|
||||
it.ruleset->enable(rule_name, filter_ruleset::match_type::exact, ruleset_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
it.ruleset->disable(rule_name, match_exact, ruleset_id);
|
||||
it.ruleset->disable(rule_name, filter_ruleset::match_type::exact, ruleset_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void falco_engine::enable_rule_wildcard(const std::string &rule_name, bool enabled, const std::string &ruleset)
|
||||
{
|
||||
uint16_t ruleset_id = find_ruleset_id(ruleset);
|
||||
|
||||
enable_rule_wildcard(rule_name, enabled, ruleset_id);
|
||||
}
|
||||
|
||||
void falco_engine::enable_rule_wildcard(const std::string &rule_name, bool enabled, const uint16_t ruleset_id)
|
||||
{
|
||||
for(const auto &it : m_sources)
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
it.ruleset->enable(rule_name, filter_ruleset::match_type::wildcard, ruleset_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
it.ruleset->disable(rule_name, filter_ruleset::match_type::wildcard, ruleset_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -102,6 +102,12 @@ public:
|
||||
// Same as above but providing a ruleset id instead
|
||||
void enable_rule_exact(const std::string &rule_name, bool enabled, const uint16_t ruleset_id);
|
||||
|
||||
// Like enable_rule, but wildcards are supported and substrings are not matched
|
||||
void enable_rule_wildcard(const std::string &rule_name, bool enabled, const std::string &ruleset = s_default_ruleset);
|
||||
|
||||
// Same as above but providing a ruleset id instead
|
||||
void enable_rule_wildcard(const std::string &rule_name, bool enabled, const uint16_t ruleset_id);
|
||||
|
||||
//
|
||||
// Enable/Disable any rules with any of the provided tags (set, exact matches only)
|
||||
//
|
||||
|
@@ -197,6 +197,48 @@ void readfile(const std::string& filename, std::string& data)
|
||||
return;
|
||||
}
|
||||
|
||||
bool matches_wildcard(const std::string &pattern, const std::string &s)
|
||||
{
|
||||
std::string::size_type star_pos = pattern.find("*");
|
||||
if(star_pos == std::string::npos)
|
||||
{
|
||||
// regular match (no wildcards)
|
||||
return pattern == s;
|
||||
}
|
||||
|
||||
if(star_pos == 0)
|
||||
{
|
||||
// wildcard at the beginning "*something*..."
|
||||
|
||||
std::string::size_type next_pattern_start = pattern.find_first_not_of("*");
|
||||
if(next_pattern_start == std::string::npos)
|
||||
{
|
||||
// pattern was just a sequence of stars *, **, ***, ... . This always matches.
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string next_pattern = pattern.substr(next_pattern_start);
|
||||
std::string to_find = next_pattern.substr(0, next_pattern.find("*"));
|
||||
std::string::size_type lit_pos = s.find(to_find);
|
||||
if(lit_pos == std::string::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return matches_wildcard(next_pattern.substr(to_find.size()), s.substr(lit_pos + to_find.size()));
|
||||
} else
|
||||
{
|
||||
// wildcard at the end or in the middle "something*else*..."
|
||||
|
||||
if(pattern.substr(0, star_pos) != s.substr(0, star_pos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return matches_wildcard(pattern.substr(star_pos), s.substr(star_pos));
|
||||
}
|
||||
}
|
||||
|
||||
namespace network
|
||||
{
|
||||
bool is_unix_scheme(const std::string& url)
|
||||
|
@@ -37,6 +37,8 @@ void readfile(const std::string& filename, std::string& data);
|
||||
|
||||
uint32_t hardware_concurrency();
|
||||
|
||||
bool matches_wildcard(const std::string &pattern, const std::string &s);
|
||||
|
||||
namespace network
|
||||
{
|
||||
static const std::string UNIX_SCHEME("unix://");
|
||||
|
@@ -41,6 +41,10 @@ public:
|
||||
ruleset_retriever_func_t get_ruleset;
|
||||
};
|
||||
|
||||
enum class match_type {
|
||||
exact, substring, wildcard
|
||||
};
|
||||
|
||||
virtual ~filter_ruleset() = default;
|
||||
|
||||
void set_engine_state(const engine_state_funcs &engine_state);
|
||||
@@ -167,31 +171,37 @@ public:
|
||||
/*!
|
||||
\brief Find those rules matching the provided substring and enable
|
||||
them in the provided ruleset.
|
||||
\param substring Substring used to match rule names.
|
||||
If empty, all rules are matched.
|
||||
\param match_exact If true, substring must be an exact match for a
|
||||
given rule name. Otherwise, any rules having substring as a substring
|
||||
in the rule name are enabled/disabled.
|
||||
\param pattern Pattern used to match rule names.
|
||||
\param match How to match the pattern against rules:
|
||||
- exact: rules that has the same exact name as the pattern are matched
|
||||
- substring: rules having the pattern as a substring in the rule are matched.
|
||||
An empty pattern matches all rules.
|
||||
- wildcard: rules with names that satisfies a wildcard (*) pattern are matched.
|
||||
A "*" pattern matches all rules.
|
||||
Wildcards can appear anywhere in the pattern (e.g. "*hello*world*")
|
||||
\param ruleset_id The id of the ruleset to be used
|
||||
*/
|
||||
virtual void enable(
|
||||
const std::string &substring,
|
||||
bool match_exact,
|
||||
const std::string &pattern,
|
||||
match_type match,
|
||||
uint16_t ruleset_id) = 0;
|
||||
|
||||
/*!
|
||||
\brief Find those rules matching the provided substring and disable
|
||||
them in the provided ruleset.
|
||||
\param substring Substring used to match rule names.
|
||||
If empty, all rules are matched.
|
||||
\param match_exact If true, substring must be an exact match for a
|
||||
given rule name. Otherwise, any rules having substring as a substring
|
||||
in the rule name are enabled/disabled.
|
||||
\param pattern Pattern used to match rule names.
|
||||
\param match How to match the pattern against rules:
|
||||
- exact: rules that has the same exact name as the pattern are matched
|
||||
- substring: rules having the pattern as a substring in the rule are matched.
|
||||
An empty pattern matches all rules.
|
||||
- wildcard: rules with names that satisfies a wildcard (*) pattern are matched.
|
||||
A "*" pattern matches all rules.
|
||||
Wildcards can appear anywhere in the pattern (e.g. "*hello*world*")
|
||||
\param ruleset_id The id of the ruleset to be used
|
||||
*/
|
||||
virtual void disable(
|
||||
const std::string &substring,
|
||||
bool match_exact,
|
||||
const std::string &pattern,
|
||||
match_type match,
|
||||
uint16_t ruleset_id) = 0;
|
||||
|
||||
/*!
|
||||
|
Reference in New Issue
Block a user