mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-13 13:32:50 +00:00
Add ability to print name/description of rules.
When run with -l <rule>, falco will print the name/description of the single rule <rule> and exit. With -L, falco will print the name/description of all rules. All the work is done in lua in the rule loader. A new lua function describe_rule calls the local function describe_single_rule once or multiple times depending on -l/-L. describe_single_rule prints the rule name and a wrapped version of the rule description.
This commit is contained in:
@@ -45,6 +45,8 @@ static void usage()
|
||||
" -p, --pidfile <pid_file> When run as a daemon, write pid to specified file\n"
|
||||
" -e <events_file> Read the events from <events_file> (in .scap format) instead of tapping into live.\n"
|
||||
" -r <rules_file> Rules file (defaults to value set in configuration file, or /etc/falco_rules.yaml).\n"
|
||||
" -L Show the name and description of all rules and exit.\n"
|
||||
" -l <rule> Show the name and description of the rule with name <rule> and exit.\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
@@ -217,6 +219,8 @@ int falco_init(int argc, char **argv)
|
||||
lua_State* ls = NULL;
|
||||
bool daemon = false;
|
||||
string pidfilename = "/var/run/falco.pid";
|
||||
bool describe_all_rules = false;
|
||||
string describe_rule = "";
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
@@ -236,7 +240,7 @@ int falco_init(int argc, char **argv)
|
||||
// Parse the args
|
||||
//
|
||||
while((op = getopt_long(argc, argv,
|
||||
"c:ho:e:r:dp:",
|
||||
"c:ho:e:r:dp:Ll:",
|
||||
long_options, &long_index)) != -1)
|
||||
{
|
||||
switch(op)
|
||||
@@ -262,6 +266,12 @@ int falco_init(int argc, char **argv)
|
||||
case 'p':
|
||||
pidfilename = optarg;
|
||||
break;
|
||||
case 'L':
|
||||
describe_all_rules = true;
|
||||
break;
|
||||
case 'l':
|
||||
describe_rule = optarg;
|
||||
break;
|
||||
case '?':
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
@@ -359,6 +369,18 @@ int falco_init(int argc, char **argv)
|
||||
inspector->set_filter(rules->get_filter());
|
||||
falco_logger::log(LOG_INFO, "Parsed rules from file " + config.m_rules_filename + "\n");
|
||||
|
||||
if (describe_all_rules)
|
||||
{
|
||||
rules->describe_rule(NULL);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (describe_rule != "")
|
||||
{
|
||||
rules->describe_rule(&describe_rule);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
inspector->set_hostname_and_port_resolution_mode(false);
|
||||
|
||||
if (config.m_json_output)
|
||||
|
@@ -182,6 +182,54 @@ function load_rules(filename)
|
||||
io.flush()
|
||||
end
|
||||
|
||||
local rule_fmt = "%-50s %s"
|
||||
|
||||
-- http://lua-users.org/wiki/StringRecipes, with simplifications and bugfixes
|
||||
local function wrap(str, limit, indent)
|
||||
indent = indent or ""
|
||||
limit = limit or 72
|
||||
local here = 1
|
||||
return str:gsub("(%s+)()(%S+)()",
|
||||
function(sp, st, word, fi)
|
||||
if fi-here > limit then
|
||||
here = st
|
||||
return "\n"..indent..word
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function describe_single_rule(name)
|
||||
if (state.rules_by_name[name] == nil) then
|
||||
error ("No such rule: "..name)
|
||||
end
|
||||
|
||||
-- Wrap the description into an multiple lines each of length ~ 60
|
||||
-- chars, with indenting to line up with the first line.
|
||||
local wrapped = wrap(state.rules_by_name[name]['desc'], 60, string.format(rule_fmt, "", ""))
|
||||
|
||||
local line = string.format(rule_fmt, name, wrapped)
|
||||
print(line)
|
||||
print()
|
||||
end
|
||||
|
||||
-- If name is nil, describe all rules
|
||||
function describe_rule(name)
|
||||
|
||||
print()
|
||||
local line = string.format(rule_fmt, "Rule", "Description")
|
||||
print(line)
|
||||
line = string.format(rule_fmt, "----", "-----------")
|
||||
print(line)
|
||||
|
||||
if name == nil then
|
||||
for rulename, rule in pairs(state.rules_by_name) do
|
||||
describe_single_rule(rulename)
|
||||
end
|
||||
else
|
||||
describe_single_rule(name)
|
||||
end
|
||||
end
|
||||
|
||||
function on_event(evt_, rule_id)
|
||||
|
||||
if state.rules_by_idx[rule_id] == nil then
|
||||
|
@@ -89,10 +89,34 @@ void falco_rules::load_rules(string rules_filename)
|
||||
throw sinsp_exception(err);
|
||||
}
|
||||
} else {
|
||||
throw sinsp_exception("No function " + m_lua_load_rules + " found in lua compiler module");
|
||||
throw sinsp_exception("No function " + m_lua_load_rules + " found in lua rule module");
|
||||
}
|
||||
}
|
||||
|
||||
void falco_rules::describe_rule(std::string *rule)
|
||||
{
|
||||
lua_getglobal(m_ls, m_lua_describe_rule.c_str());
|
||||
if(lua_isfunction(m_ls, -1))
|
||||
{
|
||||
if (rule == NULL)
|
||||
{
|
||||
lua_pushnil(m_ls);
|
||||
} else {
|
||||
lua_pushstring(m_ls, rule->c_str());
|
||||
}
|
||||
|
||||
if(lua_pcall(m_ls, 1, 0, 0) != 0)
|
||||
{
|
||||
const char* lerr = lua_tostring(m_ls, -1);
|
||||
string err = "Could not describe " + (rule == NULL ? "all rules" : "rule " + *rule) + ": " + string(lerr);
|
||||
throw sinsp_exception(err);
|
||||
}
|
||||
} else {
|
||||
throw sinsp_exception("No function " + m_lua_describe_rule + " found in lua rule module");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sinsp_filter* falco_rules::get_filter()
|
||||
{
|
||||
return m_lua_parser->get_filter();
|
||||
|
@@ -9,6 +9,7 @@ class falco_rules
|
||||
falco_rules(sinsp* inspector, lua_State *ls, string lua_main_filename);
|
||||
~falco_rules();
|
||||
void load_rules(string rules_filename);
|
||||
void describe_rule(string *rule);
|
||||
sinsp_filter* get_filter();
|
||||
|
||||
private:
|
||||
@@ -22,4 +23,5 @@ class falco_rules
|
||||
string m_lua_ignored_syscalls = "ignored_syscalls";
|
||||
string m_lua_ignored_events = "ignored_events";
|
||||
string m_lua_on_event = "on_event";
|
||||
string m_lua_describe_rule = "describe_rule";
|
||||
};
|
||||
|
Reference in New Issue
Block a user