diff --git a/CMakeLists.txt b/CMakeLists.txt index bc4866e6c61..61d610dcd5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ if(NOT DEFINED FALCO_VERSION) endif() if(NOT DEFINED FALCO_ETC_DIR) - set(FALCO_ETC_DIR "/etc") + set(FALCO_ETC_DIR "/etc/falco") endif() if(NOT CMAKE_BUILD_TYPE) @@ -399,8 +399,8 @@ add_subdirectory("${SYSDIG_DIR}/userspace/libscap" "${PROJECT_BINARY_DIR}/usersp add_subdirectory("${SYSDIG_DIR}/userspace/libsinsp" "${PROJECT_BINARY_DIR}/userspace/libsinsp") set(FALCO_SINSP_LIBRARY sinsp) -set(FALCO_SHARE_DIR ${CMAKE_INSTALL_PREFIX}/share/falco) -set(FALCO_BIN_DIR ${CMAKE_INSTALL_PREFIX}/bin) +set(FALCO_SHARE_DIR share/falco) +set(FALCO_BIN_DIR bin) add_subdirectory(scripts) add_subdirectory(userspace/engine) add_subdirectory(userspace/falco) @@ -422,7 +422,7 @@ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Sysdig ") set(CPACK_DEBIAN_PACKAGE_SECTION "utils") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://www.sysdig.org") set(CPACK_DEBIAN_PACKAGE_DEPENDS "dkms (>= 2.1.0.0)") -set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${PROJECT_SOURCE_DIR}/scripts/debian/postrm") +set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${PROJECT_SOURCE_DIR}/scripts/debian/postrm;${PROJECT_SOURCE_DIR}/cpack/debian/conffiles") set(CPACK_RPM_PACKAGE_LICENSE "GPLv2") set(CPACK_RPM_PACKAGE_URL "http://www.sysdig.org") diff --git a/cpack/debian/conffiles b/cpack/debian/conffiles new file mode 100644 index 00000000000..ff73d1b287e --- /dev/null +++ b/cpack/debian/conffiles @@ -0,0 +1,3 @@ +/etc/falco/falco.yaml +/etc/falco/falco_rules.yaml +/etc/falco/falco_rules.local.yaml diff --git a/falco.yaml b/falco.yaml index d407b75bccc..3bbb9f20ee9 100644 --- a/falco.yaml +++ b/falco.yaml @@ -1,5 +1,15 @@ -# File containing Falco rules, loaded at startup. -rules_file: /etc/falco_rules.yaml +# File(s) containing Falco rules, loaded at startup. +# +# falco_rules.yaml ships with the falco package and is overridden with +# every new software version. falco_rules.local.yaml is only created +# if it doesn't exist. If you want to customize the set of rules, add +# your customizations to falco_rules.local.yaml. +# +# The files will be read in the order presented here, so make sure if +# you have overrides they appear in later files. +rules_file: + - /etc/falco/falco_rules.yaml + - /etc/falco/falco_rules.local.yaml # Whether to output events in json or text json_output: false diff --git a/rules/CMakeLists.txt b/rules/CMakeLists.txt index 94a0ad9cc3d..e15309a0b31 100644 --- a/rules/CMakeLists.txt +++ b/rules/CMakeLists.txt @@ -1,9 +1,10 @@ if(NOT DEFINED FALCO_ETC_DIR) - set(FALCO_ETC_DIR "/etc") + set(FALCO_ETC_DIR "/etc/falco") endif() if(NOT DEFINED FALCO_RULES_DEST_FILENAME) set(FALCO_RULES_DEST_FILENAME "falco_rules.yaml") + set(FALCO_LOCAL_RULES_DEST_FILENAME "falco_rules.local.yaml") endif() if(DEFINED FALCO_COMPONENT) @@ -11,9 +12,18 @@ install(FILES falco_rules.yaml COMPONENT "${FALCO_COMPONENT}" DESTINATION "${FALCO_ETC_DIR}" RENAME "${FALCO_RULES_DEST_FILENAME}") + +install(FILES falco_rules.local.yaml + COMPONENT "${FALCO_COMPONENT}" + DESTINATION "${FALCO_ETC_DIR}" + RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}") else() install(FILES falco_rules.yaml - DESTINATION "${FALCO_ETC_DIR}" - RENAME "${FALCO_RULES_DEST_FILENAME}") + DESTINATION "${FALCO_ETC_DIR}" + RENAME "${FALCO_RULES_DEST_FILENAME}") + +install(FILES falco_rules.local.yaml + DESTINATION "${FALCO_ETC_DIR}" + RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}") endif() diff --git a/rules/falco_rules.local.yaml b/rules/falco_rules.local.yaml new file mode 100644 index 00000000000..3c8e3bb5aa8 --- /dev/null +++ b/rules/falco_rules.local.yaml @@ -0,0 +1,13 @@ +#################### +# Your custom rules! +#################### + +# Add new rules, like this one +# - rule: The program "sudo" is run in a container +# desc: An event will trigger every time you run sudo in a container +# condition: evt.type = execve and evt.dir=< and container.id != host and proc.name = sudo +# output: "Sudo run in container (user=%user.name %container.info parent=%proc.pname cmdline=%proc.cmdline)" +# priority: ERROR +# tags: [users, container] + +# Or override/append to any rule, macro, or list from the Default Rules diff --git a/test/falco_test.py b/test/falco_test.py index 7aaf359536d..c9ce8546dc6 100644 --- a/test/falco_test.py +++ b/test/falco_test.py @@ -295,7 +295,7 @@ def uninstall_package(self): res = process.run("docker rm falco-test") elif self.package.endswith(".deb"): - cmdline = "dpkg -r falco" + cmdline = "dpkg --purge falco" self.log.debug("Uninstalling debian package via \"{}\"".format(cmdline)) res = process.run(cmdline, timeout=120, sudo=True) diff --git a/userspace/engine/config_falco_engine.h.in b/userspace/engine/config_falco_engine.h.in index 137b9a2667b..56ad150867d 100644 --- a/userspace/engine/config_falco_engine.h.in +++ b/userspace/engine/config_falco_engine.h.in @@ -18,5 +18,5 @@ along with falco. If not, see . #pragma once -#define FALCO_ENGINE_LUA_DIR "${FALCO_SHARE_DIR}/lua/" +#define FALCO_ENGINE_LUA_DIR "${CMAKE_INSTALL_PREFIX}/${FALCO_SHARE_DIR}/lua/" #define FALCO_ENGINE_SOURCE_LUA_DIR "${PROJECT_SOURCE_DIR}/../falco/userspace/engine/lua/" diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index 74d828a0bc2..0f19dcc7610 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -51,7 +51,20 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio init_cmdline_options(cmdline_options); - m_rules_filenames.push_back(m_config->get_scalar("rules_file", "/etc/falco_rules.yaml")); + list rules_files; + + m_config->get_sequence>(rules_files, string("rules_file")); + + for(auto &file : rules_files) + { + // Here, we only include files that exist + struct stat buffer; + if(stat(file.c_str(), &buffer) == 0) + { + m_rules_filenames.push_back(file); + } + } + m_json_output = m_config->get_scalar("json_output", false); falco_outputs::output_config file_output; diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index 42f3b681bb2..e00ccfd9570 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -18,6 +18,9 @@ along with falco. If not, see . #pragma once +#include +#include +#include #include #include #include @@ -127,6 +130,27 @@ class yaml_configuration } } + // called with the last variadic arg (where the sequence is expected to be found) + template + void get_sequence(T& ret, const std::string& name) + { + YAML::Node child_node = m_root[name]; + if(child_node.IsDefined()) + { + if(child_node.IsSequence()) + { + for(const YAML::Node& item : child_node) + { + ret.insert(ret.end(), item.as()); + } + } + else if(child_node.IsScalar()) + { + ret.insert(ret.end(), child_node.as()); + } + } + } + private: YAML::Node m_root; };