From 69ae442e6fe231d605a172d1d63f5f7a402364e7 Mon Sep 17 00:00:00 2001 From: Jason Dellaluce Date: Thu, 23 Sep 2021 07:15:14 +0000 Subject: [PATCH 1/2] update(outputs): make tags configurable in json output Signed-off-by: Jason Dellaluce --- falco.yaml | 6 ++++++ userspace/engine/falco_engine.cpp | 3 ++- userspace/engine/formats.cpp | 22 ++++++++++++++++++---- userspace/engine/formats.h | 4 +++- userspace/falco/configuration.cpp | 1 + userspace/falco/configuration.h | 1 + userspace/falco/falco.cpp | 1 + userspace/falco/falco_outputs.cpp | 2 ++ userspace/falco/falco_outputs.h | 1 + 9 files changed, 35 insertions(+), 6 deletions(-) diff --git a/falco.yaml b/falco.yaml index 758c4f1556f..2a02615f3db 100644 --- a/falco.yaml +++ b/falco.yaml @@ -46,6 +46,12 @@ json_output: false # (user=root ....") in the json output. json_include_output_property: true +# When using json output, whether or not to include the "tags" property +# itself in the json output. If set to true, outputs caused by rules +# with no tags will have a "tags" field set to an empty array. If set to +# false, the "tags" field will not be included in the json output at all. +json_include_tags_property: true + # Send information logs to stderr and/or syslog Note these are *not* security # notification logs! These are just Falco lifecycle (and possibly error) logs. log_stderr: true diff --git a/userspace/engine/falco_engine.cpp b/userspace/engine/falco_engine.cpp index 0d1205fdbbe..789b74fb04b 100644 --- a/userspace/engine/falco_engine.cpp +++ b/userspace/engine/falco_engine.cpp @@ -177,7 +177,8 @@ void falco_engine::load_rules(const string &rules_content, bool verbose, bool al // json_output to false. bool json_output = false; bool json_include_output_property = false; - falco_formats::init(m_inspector, this, m_ls, json_output, json_include_output_property); + bool json_include_tags_property = false; + falco_formats::init(m_inspector, this, m_ls, json_output, json_include_output_property, json_include_tags_property); m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority, required_engine_version); } diff --git a/userspace/engine/formats.cpp b/userspace/engine/formats.cpp index fdbcbaf3800..b3078efd67b 100644 --- a/userspace/engine/formats.cpp +++ b/userspace/engine/formats.cpp @@ -24,6 +24,7 @@ sinsp *falco_formats::s_inspector = NULL; falco_engine *falco_formats::s_engine = NULL; bool falco_formats::s_json_output = false; bool falco_formats::s_json_include_output_property = true; +bool falco_formats::s_json_include_tags_property = true; std::unique_ptr falco_formats::s_formatters = NULL; const static struct luaL_Reg ll_falco[] = @@ -36,12 +37,14 @@ void falco_formats::init(sinsp *inspector, falco_engine *engine, lua_State *ls, bool json_output, - bool json_include_output_property) + bool json_include_output_property, + bool json_include_tags_property) { s_inspector = inspector; s_engine = engine; s_json_output = json_output; s_json_include_output_property = json_include_output_property; + s_json_include_tags_property = json_include_tags_property; // todo(leogr): we should have used std::make_unique, but we cannot since it's not C++14 s_formatters = std::unique_ptr(new sinsp_evt_formatter_cache(s_inspector)); @@ -207,11 +210,22 @@ string falco_formats::format_event(const gen_event *evt, const std::string &rule event["output"] = line; } - for (auto &tag : tags) + if(s_json_include_tags_property) { - rule_tags[rule_tags_idx++] = tag; + if (tags.size() == 0) + { + // This sets an empty array + rule_tags = Json::arrayValue; + } + else + { + for (auto &tag : tags) + { + rule_tags[rule_tags_idx++] = tag; + } + } + event["tags"] = rule_tags; } - event["tags"] = rule_tags; full_line = writer.write(event); diff --git a/userspace/engine/formats.h b/userspace/engine/formats.h index adbbd978f1b..5713da05af5 100644 --- a/userspace/engine/formats.h +++ b/userspace/engine/formats.h @@ -37,7 +37,8 @@ class falco_formats falco_engine *engine, lua_State *ls, bool json_output, - bool json_include_output_property); + bool json_include_output_property, + bool json_include_tags_property); // formatter = falco.formatter(format_string) static int lua_formatter(lua_State *ls); @@ -56,4 +57,5 @@ class falco_formats static std::unique_ptr s_formatters; static bool s_json_output; static bool s_json_include_output_property; + static bool s_json_include_tags_property; }; diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index ad4de78192a..546196ceb91 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -71,6 +71,7 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio m_json_output = m_config->get_scalar("json_output", false); m_json_include_output_property = m_config->get_scalar("json_include_output_property", true); + m_json_include_tags_property = m_config->get_scalar("json_include_tags_property", true); falco::outputs::config file_output; file_output.name = "file"; diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index fa734074127..73eb69690d3 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -195,6 +195,7 @@ class falco_configuration std::list m_rules_filenames; bool m_json_output; bool m_json_include_output_property; + bool m_json_include_tags_property; std::string m_log_level; std::vector m_outputs; uint32_t m_notifications_rate; diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index 802f8dfe140..5286598eba6 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -1122,6 +1122,7 @@ int falco_init(int argc, char **argv) outputs->init(config.m_json_output, config.m_json_include_output_property, + config.m_json_include_tags_property, config.m_output_timeout, config.m_notifications_rate, config.m_notifications_max_burst, config.m_buffered_outputs, diff --git a/userspace/falco/falco_outputs.cpp b/userspace/falco/falco_outputs.cpp index ae9f9688e1b..ec8541fce9e 100644 --- a/userspace/falco/falco_outputs.cpp +++ b/userspace/falco/falco_outputs.cpp @@ -62,6 +62,7 @@ falco_outputs::~falco_outputs() void falco_outputs::init(bool json_output, bool json_include_output_property, + bool json_include_tags_property, uint32_t timeout, uint32_t rate, uint32_t max_burst, bool buffered, bool time_format_iso_8601, std::string hostname) @@ -79,6 +80,7 @@ void falco_outputs::init(bool json_output, // So we can safely update them. falco_formats::s_json_output = json_output; falco_formats::s_json_include_output_property = json_include_output_property; + falco_formats::s_json_include_tags_property = json_include_tags_property; m_timeout = std::chrono::milliseconds(timeout); diff --git a/userspace/falco/falco_outputs.h b/userspace/falco/falco_outputs.h index dcd676faaa4..ddd94ba9707 100644 --- a/userspace/falco/falco_outputs.h +++ b/userspace/falco/falco_outputs.h @@ -40,6 +40,7 @@ class falco_outputs void init(bool json_output, bool json_include_output_property, + bool json_include_tags_property, uint32_t timeout, uint32_t rate, uint32_t max_burst, bool buffered, bool time_format_iso_8601, std::string hostname); From 86f8bd6f407ef2d7161429d4e0d51438bbe4d7a6 Mon Sep 17 00:00:00 2001 From: Jason Dellaluce Date: Thu, 23 Sep 2021 07:21:11 +0000 Subject: [PATCH 2/2] update(test): enhance test cases for tags in json outputs Signed-off-by: Jason Dellaluce --- test/confs/psp.yaml | 6 ++++++ test/falco_test.py | 14 +++++++++----- test/falco_tests.yaml | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/test/confs/psp.yaml b/test/confs/psp.yaml index a9549668f47..155d28b6ad6 100644 --- a/test/confs/psp.yaml +++ b/test/confs/psp.yaml @@ -43,6 +43,12 @@ json_output: false # (user=root ....") in the json output. json_include_output_property: true +# When using json output, whether or not to include the "tags" property +# itself in the json output. If set to true, outputs caused by rules +# with no tags will have a "tags" field set to an empty array. If set to +# false, the "tags" field will not be included in the json output at all. +json_include_tags_property: true + # Send information logs to stderr and/or syslog Note these are *not* security # notification logs! These are just Falco lifecycle (and possibly error) logs. log_stderr: true diff --git a/test/falco_test.py b/test/falco_test.py index 77f750d5ab7..486b3213941 100644 --- a/test/falco_test.py +++ b/test/falco_test.py @@ -90,6 +90,8 @@ def setUp(self): self.json_output = self.params.get('json_output', '*', default=False) self.json_include_output_property = self.params.get( 'json_include_output_property', '*', default=True) + self.json_include_tags_property = self.params.get( + 'json_include_tags_property', '*', default=True) self.all_events = self.params.get('all_events', '*', default=False) self.priority = self.params.get('priority', '*', default='debug') self.rules_file = self.params.get( @@ -388,10 +390,11 @@ def check_json_output(self, res): for line in res.stdout.decode("utf-8").splitlines(): if line.startswith('{'): obj = json.loads(line) + attrs = ['time', 'rule', 'priority'] if self.json_include_output_property: - attrs = ['time', 'rule', 'priority', 'output'] - else: - attrs = ['time', 'rule', 'priority'] + attrs.append('output') + if self.json_include_tags_property: + attrs.append('tags') for attr in attrs: if not attr in obj: self.fail( @@ -614,8 +617,9 @@ def test(self): self.log.debug("Converted Rules: {}".format(psp_rules)) # Run falco - cmd = '{} {} {} -c {} {} -o json_output={} -o json_include_output_property={} -o priority={} -v'.format( - self.falco_binary_path, self.rules_args, self.disabled_args, self.conf_file, trace_arg, self.json_output, self.json_include_output_property, self.priority) + cmd = '{} {} {} -c {} {} -o json_output={} -o json_include_output_property={} -o json_include_tags_property={} -o priority={} -v'.format( + self.falco_binary_path, self.rules_args, self.disabled_args, self.conf_file, trace_arg, self.json_output, + self.json_include_output_property, self.json_include_tags_property, self.priority) for tag in self.disable_tags: cmd += ' -T {}'.format(tag) diff --git a/test/falco_tests.yaml b/test/falco_tests.yaml index 2f3b4e5bfd4..df0c19fa509 100644 --- a/test/falco_tests.yaml +++ b/test/falco_tests.yaml @@ -1111,6 +1111,25 @@ trace_files: !mux trace_file: trace_files/cat_write.scap stdout_contains: "^(?!.*Warning An open of /dev/null was seen.*)" + json_output_no_tags_property: + json_output: True + json_include_tags_property: False + detect: True + detect_level: WARNING + rules_file: + - rules/rule_append.yaml + trace_file: trace_files/cat_write.scap + stdout_contains: "^(?!.*\"tags\":[ ]*\\[.*\\],.*)" + + json_output_empty_tags_property: + json_output: True + detect: True + detect_level: WARNING + rules_file: + - rules/rule_append.yaml + trace_file: trace_files/cat_write.scap + stdout_contains: "^(.*\"tags\":[ ]*\\[\\],.*)" + in_operator_netmasks: detect: True detect_level: INFO