mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-26 06:32:05 +00:00
Compare commits
12 Commits
ekoops-pat
...
0.39.0-rc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1b208f8fb | ||
|
|
ff65dc75ae | ||
|
|
a1ff7c7384 | ||
|
|
fb47e816ae | ||
|
|
39dfd6765a | ||
|
|
f4477f1ac2 | ||
|
|
92fa3b5347 | ||
|
|
fad91ea080 | ||
|
|
5e9a8fd665 | ||
|
|
241f620956 | ||
|
|
80816e67d6 | ||
|
|
5874dc1f95 |
@@ -34,8 +34,8 @@ else()
|
||||
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DDRIVER_VERSION=dev ..`
|
||||
if(NOT DRIVER_VERSION)
|
||||
set(DRIVER_VERSION "0.18.0-rc2")
|
||||
set(DRIVER_CHECKSUM "SHA256=e016ee1113eb5a14c85d9c4828244f5fba37cd663ecd38f5b58fbc4142348782")
|
||||
set(DRIVER_VERSION "7.3.0+driver")
|
||||
set(DRIVER_CHECKSUM "SHA256=8f572d9a83feda635a3fa53b859d61e37af127c241e35068aadee3bc50d212c0")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
|
||||
@@ -35,8 +35,8 @@ else()
|
||||
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||
if(NOT FALCOSECURITY_LIBS_VERSION)
|
||||
set(FALCOSECURITY_LIBS_VERSION "0.18.0-rc2")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=e016ee1113eb5a14c85d9c4828244f5fba37cd663ecd38f5b58fbc4142348782")
|
||||
set(FALCOSECURITY_LIBS_VERSION "0.18.0")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=0af0d46edcf97c01e3b5307732ff451d5175e8231ee6b8eec0a498d4c48f308b")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
|
||||
@@ -24,3 +24,4 @@ StandardOutput=null
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=falco.service
|
||||
@@ -24,3 +24,4 @@ StandardOutput=null
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=falco.service
|
||||
|
||||
@@ -24,3 +24,4 @@ StandardOutput=null
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=falco.service
|
||||
|
||||
@@ -97,6 +97,34 @@ TEST(Configuration, schema_wrong_embedded_key)
|
||||
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_failed);
|
||||
}
|
||||
|
||||
TEST(Configuration, plugin_init_config)
|
||||
{
|
||||
falco_configuration falco_config;
|
||||
config_loaded_res res;
|
||||
|
||||
std::string config = R"(
|
||||
plugins:
|
||||
- name: k8saudit
|
||||
library_path: libk8saudit.so
|
||||
init_config:
|
||||
maxEventSize: 262144
|
||||
sslCertificate: /etc/falco/falco.pem
|
||||
)";
|
||||
|
||||
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
|
||||
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
|
||||
|
||||
config = R"(
|
||||
plugins:
|
||||
- name: k8saudit
|
||||
library_path: libk8saudit.so
|
||||
init_config: '{"maxEventSize": 262144, "sslCertificate": "/etc/falco/falco.pem"}'
|
||||
)";
|
||||
|
||||
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
|
||||
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
|
||||
}
|
||||
|
||||
TEST(Configuration, schema_yaml_helper_validator)
|
||||
{
|
||||
yaml_helper conf;
|
||||
|
||||
@@ -35,6 +35,12 @@ const char rule_schema_string[] = LONG_STRING_CONST(
|
||||
"required_engine_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"required_plugin_versions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/RequiredPluginVersion"
|
||||
}
|
||||
},
|
||||
"macro": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -68,6 +74,9 @@ const char rule_schema_string[] = LONG_STRING_CONST(
|
||||
"priority": {
|
||||
"$ref": "#/definitions/Priority"
|
||||
},
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"exceptions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -166,6 +175,46 @@ const char rule_schema_string[] = LONG_STRING_CONST(
|
||||
},
|
||||
"minProperties": 1,
|
||||
"title": "Override"
|
||||
},
|
||||
"RequiredPluginVersion": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"alternatives": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Alternative"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
],
|
||||
"title": "RequiredPluginVersion"
|
||||
},
|
||||
"Alternative": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
],
|
||||
"title": "Alternative"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ limitations under the License.
|
||||
#include "actions.h"
|
||||
#include "helpers.h"
|
||||
#include "../app.h"
|
||||
#include <libsinsp/plugin_manager.h>
|
||||
|
||||
using namespace falco::app;
|
||||
using namespace falco::app::actions;
|
||||
@@ -73,6 +74,25 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
+ ") syscalls in rules: " + concat_set_in_order(rules_names) + "\n");
|
||||
}
|
||||
|
||||
/* Load PPM event codes needed by plugins with parsing capability */
|
||||
libsinsp::events::set<ppm_event_code> plugin_ev_codes;
|
||||
for (const auto &p : s.offline_inspector->get_plugin_manager()->plugins())
|
||||
{
|
||||
if(!(p->caps() & CAP_PARSING))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
plugin_ev_codes.merge(p->parse_event_codes());
|
||||
}
|
||||
const auto plugin_sc_set = libsinsp::events::event_set_to_sc_set(plugin_ev_codes);
|
||||
const auto plugin_names = libsinsp::events::sc_set_to_event_names(plugin_sc_set);
|
||||
if (!plugin_sc_set.empty())
|
||||
{
|
||||
falco_logger::log(falco_logger::level::DEBUG, "(" + std::to_string(plugin_names.size())
|
||||
+ ") syscalls required by plugins: " + concat_set_in_order(plugin_names) + "\n");
|
||||
}
|
||||
|
||||
|
||||
/* DEFAULT OPTION:
|
||||
* Current `sinsp_state_sc_set()` approach includes multiple steps:
|
||||
* (1) Enforce all positive syscalls from each Falco rule
|
||||
@@ -111,9 +131,10 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
+ concat_set_in_order(invalid_positive_sc_set_names));
|
||||
}
|
||||
|
||||
// selected events are the union of the rules events set and the
|
||||
// selected events are the union of the rules events set plus
|
||||
// the parsing capability plugins events set and the
|
||||
// base events set (either the default or the user-defined one)
|
||||
s.selected_sc_set = rules_sc_set.merge(base_sc_set);
|
||||
s.selected_sc_set = rules_sc_set.merge(plugin_sc_set).merge(base_sc_set);
|
||||
|
||||
/* REPLACE DEFAULT STATE, nothing else. Need to override s.selected_sc_set and have a separate logic block. */
|
||||
if (s.config->m_base_syscalls_repair && user_positive_sc_set.empty())
|
||||
|
||||
@@ -163,11 +163,6 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
|
||||
std::unordered_set<std::string> used_plugins;
|
||||
const auto& all_plugins = s.offline_inspector->get_plugin_manager()->plugins();
|
||||
|
||||
if((s.config->m_metrics_flags & METRICS_V2_STATE_COUNTERS))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
for (const auto &src : s.loaded_sources)
|
||||
{
|
||||
auto src_info = s.source_infos.at(src);
|
||||
|
||||
@@ -585,6 +585,12 @@ falco::app::run_result falco::app::actions::process_events(falco::app::state& s)
|
||||
}
|
||||
}
|
||||
|
||||
// By deleting s.outputs, we make sure that the engine will wait until
|
||||
// regular output has been completely sent before printing stats, avoiding
|
||||
// intermixed stats with output.
|
||||
// Note that this will only work if this is the last reference held by the
|
||||
// shared pointer.
|
||||
s.outputs.reset();
|
||||
s.engine->print_stats();
|
||||
|
||||
return res;
|
||||
|
||||
@@ -95,6 +95,16 @@ bool options::parse(int argc, char **argv, std::string &errstr)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_cmdline_parsed.count("cri") > 0)
|
||||
{
|
||||
falco_logger::log(falco_logger::level::WARNING, "The --cri option is deprecated and will be removed in Falco 0.40.0. Use -o container_engines.cri.sockets[]=<socket_path> instead.");
|
||||
}
|
||||
|
||||
if (m_cmdline_parsed.count("disable-cri-async") > 0)
|
||||
{
|
||||
falco_logger::log(falco_logger::level::WARNING, "The --disable-cri-async option is deprecated and will be removed in Falco 0.40.0. Use -o container_engines.cri.disable_async=true instead.");
|
||||
}
|
||||
|
||||
list_fields = m_cmdline_parsed.count("list") > 0;
|
||||
|
||||
return true;
|
||||
@@ -119,8 +129,8 @@ void options::define(cxxopts::Options& opts)
|
||||
("A", "Monitor all events supported by Falco and defined in rules and configs. Some events are ignored by default when -A is not specified (the -i option lists these events ignored). Using -A can impact performance. This option has no effect when reproducing events from a capture file.", cxxopts::value(all_events)->default_value("false"))
|
||||
("b,print-base64", "Print data buffers in base64. This is useful for encoding binary data that needs to be used over media designed to consume this format.")
|
||||
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
("cri", "Path to CRI socket for container metadata. Use the specified <path> to fetch data from a CRI-compatible runtime. If not specified, built-in defaults for commonly known paths are used. This option can be passed multiple times to specify a list of sockets to be tried until a successful one is found.", cxxopts::value(cri_socket_paths), "<path>")
|
||||
("disable-cri-async", "Turn off asynchronous CRI metadata fetching. This is useful to let the input event wait for the container metadata fetch to finish before moving forward. Async fetching, in some environments leads to empty fields for container metadata when the fetch is not fast enough to be completed asynchronously. This can have a performance penalty on your environment depending on the number of containers and the frequency at which they are created/started/stopped.", cxxopts::value(disable_cri_async)->default_value("false"))
|
||||
("cri", "DEPRECATED: use -o container_engines.cri.sockets[]=<socket_path> instead. Path to CRI socket for container metadata. Use the specified <path> to fetch data from a CRI-compatible runtime. If not specified, built-in defaults for commonly known paths are used. This option can be passed multiple times to specify a list of sockets to be tried until a successful one is found.", cxxopts::value(cri_socket_paths), "<path>")
|
||||
("disable-cri-async", "DEPRECATED: use -o container_engines.cri.disable_async=true instead. Turn off asynchronous CRI metadata fetching. This is useful to let the input event wait for the container metadata fetch to finish before moving forward. Async fetching, in some environments leads to empty fields for container metadata when the fetch is not fast enough to be completed asynchronously. This can have a performance penalty on your environment depending on the number of containers and the frequency at which they are created/started/stopped.", cxxopts::value(disable_cri_async)->default_value("false"))
|
||||
#endif
|
||||
("disable-source", "Turn off a specific <event_source>. By default, all loaded sources get enabled. Available sources are 'syscall' plus all sources defined by loaded plugins supporting the event sourcing capability. This option can be passed multiple times, but turning off all event sources simultaneously is not permitted. This option can not be mixed with --enable-source. This option has no effect when reproducing events from a capture file.", cxxopts::value(disable_sources), "<event_source>")
|
||||
("dry-run", "Run Falco without processing events. It can help check that the configuration and rules do not have any errors.", cxxopts::value(dry_run)->default_value("false"))
|
||||
|
||||
@@ -587,7 +587,14 @@ const char config_schema_string[] = LONG_STRING_CONST(
|
||||
"type": "string"
|
||||
},
|
||||
"init_config": {
|
||||
"type": "string"
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"open_params": {
|
||||
"type": "string"
|
||||
|
||||
@@ -19,8 +19,6 @@ limitations under the License.
|
||||
|
||||
#include "falco_metrics.h"
|
||||
|
||||
#include "falco_utils.h"
|
||||
|
||||
#include "app/state.h"
|
||||
|
||||
#include <libsinsp/sinsp.h>
|
||||
@@ -102,48 +100,15 @@ std::string falco_metrics::to_text(const falco::app::state& state)
|
||||
for (const auto& item : state.config.get()->m_loaded_rules_filenames_sha256sum)
|
||||
{
|
||||
fs::path fs_path = item.first;
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("sha256_rules_files", "falcosecurity", "falco", {{"file_name", fs_path.filename().stem()}, {"sha256", item.second}});
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("sha256_rules_files", "falcosecurity", "falco", {{"file_name", fs_path.filename()}, {"sha256", item.second}});
|
||||
}
|
||||
|
||||
for (const auto& item : state.config.get()->m_loaded_configs_filenames_sha256sum)
|
||||
{
|
||||
fs::path fs_path = item.first;
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("sha256_config_files", "falcosecurity", "falco", {{"file_name", fs_path.filename().stem()}, {"sha256", item.second}});
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("sha256_config_files", "falcosecurity", "falco", {{"file_name", fs_path.filename()}, {"sha256", item.second}});
|
||||
}
|
||||
|
||||
static std::string ifinfo_json_escaped;
|
||||
auto ipv4list = inspector->get_ifaddr_list().get_ipv4_list();
|
||||
auto ipv6list = inspector->get_ifaddr_list().get_ipv6_list();
|
||||
nlohmann::json ipv4_json;
|
||||
nlohmann::json ipv6_json;
|
||||
if(ipv4list)
|
||||
{
|
||||
for (const auto& item : *ipv4list)
|
||||
{
|
||||
if(item.m_name == "lo")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ipv4_json[item.m_name] = item.addr_to_string();
|
||||
}
|
||||
}
|
||||
|
||||
if(ipv6list)
|
||||
{
|
||||
for (const auto& item : *ipv6list)
|
||||
{
|
||||
if(item.m_name == "lo")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ipv6_json[item.m_name] = item.addr_to_string();
|
||||
}
|
||||
}
|
||||
nlohmann::json ifinfo_json;
|
||||
ifinfo_json["ipv4"] = ipv4_json;
|
||||
ifinfo_json["ipv6"] = ipv6_json;
|
||||
ifinfo_json_escaped = ifinfo_json.dump();
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("host_ifinfo_json", "falcosecurity", "falco", {{"host_ifinfo_json", ifinfo_json_escaped}});
|
||||
#endif
|
||||
|
||||
for (const std::string& source: inspector->event_sources())
|
||||
@@ -218,10 +183,10 @@ std::string falco_metrics::to_text(const falco::app::state& state)
|
||||
/* Examples ...
|
||||
# HELP falcosecurity_falco_rules_matches_total https://falco.org/docs/metrics/
|
||||
# TYPE falcosecurity_falco_rules_matches_total counter
|
||||
falcosecurity_falco_rules_matches_total{priority="4",rule_name="Read sensitive file untrusted",source="syscall",tags="T1555, container, filesystem, host, maturity_stable, mitre_credential_access"} 10
|
||||
falcosecurity_falco_rules_matches_total{priority="4",rule_name="Read sensitive file untrusted",source="syscall",tag_T1555="true",tag_container="true",tag_filesystem="true",tag_host="true",tag_maturity_stable="true",tag_mitre_credential_access="true"} 10
|
||||
# HELP falcosecurity_falco_rules_matches_total https://falco.org/docs/metrics/
|
||||
# TYPE falcosecurity_falco_rules_matches_total counter
|
||||
falcosecurity_falco_rules_matches_total{priority="5",rule_name="Unexpected UDP Traffic",source="syscall",tags="TA0011, container, host, maturity_incubating, mitre_exfiltration, network"} 1
|
||||
falcosecurity_falco_rules_matches_total{priority="5",rule_name="Unexpected UDP Traffic",source="syscall",tag_TA0011="true",tag_container="true",tag_host="true",tag_maturity_incubating="true",tag_mitre_exfiltration="true",tag_network="true"} 1
|
||||
*/
|
||||
auto metric = libs::metrics::libsinsp_metrics::new_metric("rules_matches",
|
||||
METRICS_V2_RULE_COUNTERS,
|
||||
@@ -230,12 +195,14 @@ std::string falco_metrics::to_text(const falco::app::state& state)
|
||||
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
|
||||
rules_by_id[i]->load());
|
||||
prometheus_metrics_converter.convert_metric_to_unit_convention(metric);
|
||||
const std::map<std::string, std::string>& const_labels = {
|
||||
std::map<std::string, std::string> const_labels = {
|
||||
{"rule_name", rule->name},
|
||||
{"priority", std::to_string(rule->priority)},
|
||||
{"source", rule->source},
|
||||
{"tags", concat_set_in_order(rule->tags)}
|
||||
};
|
||||
std::for_each(rule->tags.cbegin(), rule->tags.cend(), [&const_labels](std::string const& tag) {
|
||||
const_labels.emplace(std::string{"tag_"} + tag, "true");
|
||||
});
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus(metric, "falcosecurity", "falco", const_labels);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ void stats_writer::collector::get_metrics_output_fields_wrapper(
|
||||
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();
|
||||
std::string metric_name_file_sha256 = fs_path.filename();
|
||||
metric_name_file_sha256 = "falco.sha256_rules_file." + falco::utils::sanitize_rule_name(metric_name_file_sha256);
|
||||
output_fields[metric_name_file_sha256] = item.second;
|
||||
}
|
||||
@@ -353,44 +353,11 @@ void stats_writer::collector::get_metrics_output_fields_wrapper(
|
||||
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();
|
||||
std::string metric_name_file_sha256 = fs_path.filename();
|
||||
metric_name_file_sha256 = "falco.sha256_config_file." + falco::utils::sanitize_rule_name(metric_name_file_sha256);
|
||||
output_fields[metric_name_file_sha256] = item.second;
|
||||
}
|
||||
|
||||
auto ipv4list = inspector->get_ifaddr_list().get_ipv4_list();
|
||||
auto ipv6list = inspector->get_ifaddr_list().get_ipv6_list();
|
||||
nlohmann::json ipv4_json;
|
||||
nlohmann::json ipv6_json;
|
||||
if(ipv4list)
|
||||
{
|
||||
for (const auto& item : *ipv4list)
|
||||
{
|
||||
if(item.m_name == "lo")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ipv4_json[item.m_name] = item.addr_to_string();
|
||||
}
|
||||
}
|
||||
|
||||
if(ipv6list)
|
||||
{
|
||||
for (const auto& item : *ipv6list)
|
||||
{
|
||||
if(item.m_name == "lo")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ipv6_json[item.m_name] = item.addr_to_string();
|
||||
}
|
||||
}
|
||||
nlohmann::json ifinfo_json;
|
||||
ifinfo_json["ipv4"] = ipv4_json;
|
||||
ifinfo_json["ipv6"] = ipv6_json;
|
||||
m_ifinfo_json_escaped = ifinfo_json.dump();
|
||||
output_fields["falco.host_ifinfo_json"] = m_ifinfo_json_escaped;
|
||||
|
||||
#endif
|
||||
output_fields["evt.source"] = src;
|
||||
for (size_t i = 0; i < sizeof(all_driver_engines) / sizeof(const char*); i++)
|
||||
|
||||
@@ -80,7 +80,6 @@ public:
|
||||
uint64_t m_last_n_evts = 0;
|
||||
uint64_t m_last_n_drops = 0;
|
||||
uint64_t m_last_num_evts = 0;
|
||||
std::string m_ifinfo_json_escaped;
|
||||
};
|
||||
|
||||
stats_writer(const stats_writer&) = delete;
|
||||
|
||||
Reference in New Issue
Block a user