Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new(metrics): add file sha256sum metrics for loaded config and rules files #3187

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 35 additions & 1 deletion userspace/engine/falco_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ limitations under the License.
#include <libsinsp/utils.h>

#include <re2/re2.h>

#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
#include <openssl/sha.h>
#endif
#include <cstring>
#include <fstream>
#include <iomanip>
Expand Down Expand Up @@ -117,6 +119,38 @@ uint64_t parse_prometheus_interval(std::string interval_str)
return interval;
}

#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
std::string calculate_file_sha256sum(const std::string& filename)
{
std::ifstream file(filename, std::ios::binary);
if (!file.is_open())
{
return "";
}

SHA256_CTX sha256_context;
SHA256_Init(&sha256_context);

constexpr size_t buffer_size = 4096;
char buffer[buffer_size];
while (file.read(buffer, buffer_size))
{
SHA256_Update(&sha256_context, buffer, buffer_size);
}
SHA256_Update(&sha256_context, buffer, file.gcount());

unsigned char digest[SHA256_DIGEST_LENGTH];
SHA256_Final(digest, &sha256_context);

std::stringstream ss;
for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
{
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned>(digest[i]);
}
return ss.str();
}
#endif

std::string wrap_text(const std::string& in, uint32_t indent, uint32_t line_len)
{
std::istringstream is(in);
Expand Down
4 changes: 4 additions & 0 deletions userspace/engine/falco_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ namespace falco::utils
{
uint64_t parse_prometheus_interval(std::string interval_str);

#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
std::string calculate_file_sha256sum(const std::string& filename);
#endif

std::string wrap_text(const std::string& in, uint32_t indent, uint32_t linelen);

void readfile(const std::string& filename, std::string& data);
Expand Down
4 changes: 4 additions & 0 deletions userspace/falco/app/actions/load_rules_files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.

#include "actions.h"
#include "helpers.h"
#include "falco_utils.h"

#include <libsinsp/plugin_manager.h>

Expand Down Expand Up @@ -83,6 +84,9 @@ falco::app::run_result falco::app::actions::load_rules_files(falco::app::state&
{
falco_logger::log(falco_logger::level::WARNING,res->as_string(true, rc) + "\n");
}
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
s.config->m_loaded_rules_filenames_sha256sum.insert({filename, falco::utils::calculate_file_sha256sum(filename)});
#endif
}

// note: we have an egg-and-chicken problem here. We would like to check
Expand Down
8 changes: 8 additions & 0 deletions userspace/falco/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ void falco_configuration::merge_configs_files(const std::string& config_name, st
}
}
}

#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
for(auto &filename : m_loaded_configs_filenames)
{
m_loaded_configs_filenames_sha256sum.insert({filename, falco::utils::calculate_file_sha256sum(filename)});
}
#endif
}

void falco_configuration::init_logger()
Expand Down Expand Up @@ -270,6 +277,7 @@ void falco_configuration::load_yaml(const std::string& config_name)

m_rules_filenames.clear();
m_loaded_rules_filenames.clear();
m_loaded_rules_filenames_sha256sum.clear();
m_loaded_rules_folders.clear();
for(auto &file : rules_files)
{
Expand Down
4 changes: 4 additions & 0 deletions userspace/falco/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,17 @@ class falco_configuration

// Config list as passed by the user. Filenames.
std::list<std::string> m_loaded_configs_filenames;
// Map with filenames and their sha256 of the loaded configs files
std::unordered_map<std::string, std::string> m_loaded_configs_filenames_sha256sum;
// Config list as passed by the user. Folders.
std::list<std::string> m_loaded_configs_folders;

// Rules list as passed by the user
std::list<std::string> m_rules_filenames;
// Actually loaded rules, with folders inspected
std::list<std::string> m_loaded_rules_filenames;
// Map with filenames and their sha256 of the loaded rules files
std::unordered_map<std::string, std::string> m_loaded_rules_filenames_sha256sum;
// List of loaded rule folders
std::list<std::string> m_loaded_rules_folders;
bool m_json_output;
Expand Down
20 changes: 20 additions & 0 deletions userspace/falco/falco_metrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ limitations under the License.

#include <libsinsp/sinsp.h>

namespace fs = std::filesystem;

/*!
\class falco_metrics
\brief This class is used to convert the metrics provided by the application
Expand Down Expand Up @@ -82,6 +84,24 @@ std::string falco_metrics::to_text(const falco::app::state& state)
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("kernel_release", "falcosecurity", "falco", {{"kernel_release", agent_info->uname_r}});
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("hostname", "falcosecurity", "evt", {{"hostname", machine_info->hostname}});

#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
for (const auto& item : state.config.get()->m_loaded_rules_filenames_sha256sum)
{
fs::path fs_path = item.first;
std::string metric_name_file_sha256 = fs_path.filename().stem();
metric_name_file_sha256 = "falco.sha256_rule_file." + metric_name_file_sha256;
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus(metric_name_file_sha256, "falcosecurity", "falco", {{metric_name_file_sha256, item.second}});
}

for (const auto& item : state.config.get()->m_loaded_configs_filenames_sha256sum)
{
fs::path fs_path = item.first;
std::string metric_name_file_sha256 = fs_path.filename().stem();
metric_name_file_sha256 = "falco.sha256_config_file." + metric_name_file_sha256;
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus(metric_name_file_sha256, "falcosecurity", "falco", {{metric_name_file_sha256, item.second}});
}
#endif

for (const std::string& source: inspector->event_sources())
{
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("evt_source", "falcosecurity", "falco", {{"evt_source", source}});
Expand Down
19 changes: 19 additions & 0 deletions userspace/falco/stats_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ limitations under the License.
#include <libscap/strl.h>
#include <libscap/scap_vtable.h>

namespace fs = std::filesystem;

// note: ticker_t is an uint16_t, which is enough because we don't care about
// overflows here. Threads calling stats_writer::handle() will just
// check that this value changed since their last observation.
Expand Down Expand Up @@ -328,6 +330,23 @@ void stats_writer::collector::get_metrics_output_fields_wrapper(
output_fields["falco.host_num_cpus"] = machine_info->num_cpus;
output_fields["falco.outputs_queue_num_drops"] = m_writer->m_outputs->get_outputs_queue_num_drops();

#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
for (const auto& item : m_writer->m_config->m_loaded_rules_filenames_sha256sum)
{
fs::path fs_path = item.first;
std::string metric_name_file_sha256 = fs_path.filename().stem();
metric_name_file_sha256 = "falco.sha256_rule_file." + metric_name_file_sha256;
output_fields[metric_name_file_sha256] = item.second;
}

for (const auto& item : m_writer->m_config->m_loaded_configs_filenames_sha256sum)
{
fs::path fs_path = item.first;
std::string metric_name_file_sha256 = fs_path.filename().stem();
metric_name_file_sha256 = "falco.sha256_config_file." + metric_name_file_sha256;
output_fields[metric_name_file_sha256] = item.second;
}
#endif
output_fields["evt.source"] = src;
for (size_t i = 0; i < sizeof(all_driver_engines) / sizeof(const char*); i++)
{
Expand Down