From f6ffa75d74ed51fe3f8c4218082c984504956edd Mon Sep 17 00:00:00 2001 From: Melissa Kilby Date: Thu, 27 Jun 2024 18:48:31 +0000 Subject: [PATCH] new(config): add container_engines config to falco.yaml Signed-off-by: Melissa Kilby --- falco.yaml | 69 +++++++++++-------- .../falco/app/actions/init_inspectors.cpp | 16 +++++ userspace/falco/configuration.cpp | 41 ++++++++++- userspace/falco/configuration.h | 5 ++ 4 files changed, 101 insertions(+), 30 deletions(-) diff --git a/falco.yaml b/falco.yaml index a6c792b6..2a3ecca1 100644 --- a/falco.yaml +++ b/falco.yaml @@ -1206,33 +1206,44 @@ base_syscalls: falco_libs: thread_table_size: 262144 -# [Stable] Guidance for Kubernetes container engine command-line args settings +# [Incubating] `container_engines` # -# Modern cloud environments, particularly Kubernetes, heavily rely on -# containerized workload deployments. When capturing events with Falco, it -# becomes essential to identify the owner of the workload for which events are -# being captured, such as syscall events. Falco integrates with the container -# runtime to enrich its events with container information, including fields like -# `container.image.repository`, `container.image.tag`, ... , `k8s.ns.name`, -# `k8s.pod.name`, `k8s.pod.*` in the Falco output (Falco retrieves Kubernetes -# namespace and pod name directly from the container runtime, see -# https://falco.org/docs/reference/rules/supported-fields/#field-class-container). -# -# Furthermore, Falco exposes container events themselves as a data source for -# alerting. To achieve this integration with the container runtime, Falco -# requires access to the runtime socket. By default, for Kubernetes, Falco -# attempts to connect to the following sockets: -# "/run/containerd/containerd.sock", "/run/crio/crio.sock", -# "/run/k3s/containerd/containerd.sock". If you have a custom path, you can use -# the `--cri` option to specify the correct location. -# -# In some cases, you may encounter empty fields for container metadata. To -# address this, you can explore the `--disable-cri-async` option, which disables -# asynchronous fetching if the fetch operation is not completing quickly enough. -# -# To get more information on these command-line arguments, you can run `falco -# --help` in your terminal to view their current descriptions. -# -# !!! The options mentioned here are not available in the falco.yaml -# configuration file. Instead, they can can be used as a command-line argument -# when running the Falco command. +# This option allows you to explicitly enable or disable API lookups against container +# runtime sockets for each supported container runtime, tracked internally as `container_engines`. +# Access to these sockets enables Falco to provide container and Kubernetes fields, which +# are crucial for identifying workload owners in modern containerized environments. +# Refer to the fields docs: +# +# - [Kubernetes fields](https://falco.org/docs/reference/rules/supported-fields/#field-class-k8s) +# - [Container fields](https://falco.org/docs/reference/rules/supported-fields/#container) +# +# Additionally, Falco uses container events as a data source for alerting. +# +# For most container engines, you can enable or disable them, and Falco will search the +# default container runtime socket paths, such as `/var/run/docker.sock` for Docker. +# However, for Kubernetes settings, you can customize the CRI socket paths: +# +# - `container_engines.cri.cri`: Pass a list of container runtime sockets. +# - `container_engines.cri.disable-cri-async`: Since API lookups may not always be quick or +# perfect, resulting in empty fields for container metadata, you can use this option option +# to disable asynchronous fetching. Note that missing fields may still occasionally occur. +# +# The equivalent (stable) CLI args are `--cri` or `--disable-cri-async`. + +container_engines: + docker: + enabled: true + cri: + enabled: true + cri: ["/run/containerd/containerd.sock", "/run/crio/crio.sock", "/run/k3s/containerd/containerd.sock"] + disable-cri-async: false + podman: + enabled: true + lxc: + enabled: true + libvirt_lxc: + enabled: true + rocket: + enabled: true + bpm: + enabled: true diff --git a/userspace/falco/app/actions/init_inspectors.cpp b/userspace/falco/app/actions/init_inspectors.cpp index fe18f98b..972565c7 100644 --- a/userspace/falco/app/actions/init_inspectors.cpp +++ b/userspace/falco/app/actions/init_inspectors.cpp @@ -29,6 +29,22 @@ static void init_syscall_inspector(falco::app::state& s, std::shared_ptr { inspector->set_buffer_format(s.options.event_buffer_format); + // + // Container engines + // + + // Container engines configs via falco.yaml + inspector->set_container_engine_mask(s.config->m_container_engines_mask); + for (auto &p : s.config->m_container_engines_cri_socket_paths) + { + if (!p.empty()) + { + inspector->add_cri_socket_path(p); + } + } + inspector->set_cri_async(!s.config->m_container_engines_disable_cri_async); + + // Container engines configs via CLI args // If required, set the CRI paths for (auto &p : s.options.cri_socket_paths) { diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index a630aac2..492da083 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -82,7 +82,10 @@ falco_configuration::falco_configuration(): m_metrics_output_file(""), m_metrics_flags(0), m_metrics_convert_memory_to_mb(true), - m_metrics_include_empty_values(false) + m_metrics_include_empty_values(false), + m_container_engines_mask(0), + m_container_engines_cri_socket_paths({"/run/containerd/containerd.sock", "/run/crio/crio.sock","/run/k3s/containerd/containerd.sock"}), + m_container_engines_disable_cri_async(false) { m_config_schema = nlohmann::json::parse(schema_json_string); } @@ -636,7 +639,43 @@ void falco_configuration::load_yaml(const std::string& config_name) } } + m_watch_config_files = m_config.get_scalar("watch_config_files", true); + + m_container_engines_mask = 0; + if(m_config.get_scalar("container_engines.docker.enabled", true)) + { + m_container_engines_mask |= (1 << CT_DOCKER); + } + if(m_config.get_scalar("container_engines.podman.enabled", true)) + { + m_container_engines_mask |= (1 << CT_PODMAN); + } + if(m_config.get_scalar("container_engines.cri.enabled", true)) + { + m_container_engines_mask |= ((1 << CT_CRI) | + (1 << CT_CRIO) | + (1 << CT_CONTAINERD)); + m_container_engines_cri_socket_paths.clear(); + m_config.get_sequence>(m_container_engines_cri_socket_paths, "container_engines.cri.cri"); + m_container_engines_disable_cri_async = m_config.get_scalar("container_engines.cri.disable-cri-async", false); + } + if(m_config.get_scalar("container_engines.lxc.enabled", true)) + { + m_container_engines_mask |= (1 << CT_LXC); + } + if(m_config.get_scalar("container_engines.libvirt_lxc.enabled", true)) + { + m_container_engines_mask |= (1 << CT_LIBVIRT_LXC); + } + if(m_config.get_scalar("container_engines.rocket.enabled", true)) + { + m_container_engines_mask |= (1 << CT_RKT); + } + if(m_config.get_scalar("container_engines.bpm.enabled", true)) + { + m_container_engines_mask |= (1 << CT_BPM); + } } void falco_configuration::read_rules_file_directory(const std::string &path, std::list &rules_filenames, std::list &rules_folders) diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index ef7fd5f9..424ce661 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -186,6 +186,11 @@ public: bool m_metrics_include_empty_values; std::vector m_plugins; + // container engines + uint64_t m_container_engines_mask; + uint64_t m_container_engines_disable_cri_async; + std::vector m_container_engines_cri_socket_paths; + // Falco engine engine_kind_t m_engine_mode = engine_kind_t::KMOD; kmod_config m_kmod = {};