mirror of
https://github.com/falcosecurity/falco.git
synced 2026-04-02 10:02:12 +00:00
Compare commits
2 Commits
fix/cli-o-
...
fix/http-o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
369f69e8c8 | ||
|
|
9a664771c0 |
@@ -175,18 +175,14 @@ include(njson)
|
||||
# yaml-cpp
|
||||
include(yaml-cpp)
|
||||
|
||||
if(NOT WIN32
|
||||
AND NOT APPLE
|
||||
AND NOT MINIMAL_BUILD
|
||||
AND NOT EMSCRIPTEN
|
||||
)
|
||||
if(NOT MINIMAL_BUILD AND NOT EMSCRIPTEN)
|
||||
# OpenSSL
|
||||
include(openssl)
|
||||
|
||||
# libcurl
|
||||
include(curl)
|
||||
|
||||
# todo(jasondellaluce,rohith-raju): support webserver for non-linux builds too cpp-httlib
|
||||
# cpp-httplib
|
||||
include(cpp-httplib)
|
||||
endif()
|
||||
|
||||
@@ -202,14 +198,6 @@ include(valijson)
|
||||
if(USE_GPERFTOOLS)
|
||||
include(gperftools)
|
||||
endif()
|
||||
if(NOT MINIMAL_BUILD)
|
||||
if(NOT WIN32
|
||||
AND NOT APPLE
|
||||
AND NOT EMSCRIPTEN
|
||||
)
|
||||
include(cares)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Installation
|
||||
if(WIN32)
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright (C) 2023 The Falco Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
# in compliance with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
# or implied. See the License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
#
|
||||
|
||||
option(USE_BUNDLED_CARES "Enable building of the bundled c-ares" ${USE_BUNDLED_DEPS})
|
||||
|
||||
if(CARES_INCLUDE)
|
||||
# we already have c-ares
|
||||
elseif(NOT USE_BUNDLED_CARES)
|
||||
find_path(CARES_INCLUDE NAMES cares/ares.h ares.h)
|
||||
find_library(CARES_LIB NAMES cares)
|
||||
if(CARES_INCLUDE AND CARES_LIB)
|
||||
message(STATUS "Found c-ares: include: ${CARES_INCLUDE}, lib: ${CARES_LIB}")
|
||||
else()
|
||||
message(FATAL_ERROR "Couldn't find system c-ares")
|
||||
endif()
|
||||
else()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(CARES_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set(CARES_STATIC_OPTION "Off")
|
||||
else()
|
||||
set(CARES_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
set(CARES_STATIC_OPTION "On")
|
||||
endif()
|
||||
set(CARES_SRC "${PROJECT_BINARY_DIR}/c-ares-prefix/src/c-ares")
|
||||
set(CARES_INCLUDE "${CARES_SRC}/include/")
|
||||
set(CARES_LIB "${CARES_SRC}/lib/libcares${CARES_LIB_SUFFIX}")
|
||||
|
||||
if(NOT TARGET c-ares)
|
||||
message(STATUS "Using bundled c-ares in '${CARES_SRC}'")
|
||||
ExternalProject_Add(
|
||||
c-ares
|
||||
PREFIX "${PROJECT_BINARY_DIR}/c-ares-prefix"
|
||||
URL "https://github.com/c-ares/c-ares/releases/download/v1.33.1/c-ares-1.33.1.tar.gz"
|
||||
URL_HASH "SHA256=06869824094745872fa26efd4c48e622b9bd82a89ef0ce693dc682a23604f415"
|
||||
BUILD_IN_SOURCE 1
|
||||
CMAKE_ARGS -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW
|
||||
-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
-DCARES_SHARED=${BUILD_SHARED_LIBS}
|
||||
-DCARES_STATIC=${CARES_STATIC_OPTION}
|
||||
-DCARES_STATIC_PIC=${ENABLE_PIC}
|
||||
-DCARES_BUILD_TOOLS=Off
|
||||
-DCARES_INSTALL=Off
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
BUILD_BYPRODUCTS ${CARES_INCLUDE} ${CARES_LIB}
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
install(
|
||||
FILES "${CARES_LIB}"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
|
||||
COMPONENT "libs-deps"
|
||||
)
|
||||
install(
|
||||
DIRECTORY "${CARES_INCLUDE}"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBS_PACKAGE_NAME}"
|
||||
COMPONENT "libs-deps"
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(NOT TARGET c-ares)
|
||||
add_custom_target(c-ares)
|
||||
endif()
|
||||
|
||||
include_directories("${CARES_INCLUDE}")
|
||||
@@ -102,58 +102,6 @@ TEST(Configuration, modify_yaml_fields) {
|
||||
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
|
||||
}
|
||||
|
||||
static std::string escaped_keys_yaml =
|
||||
"annotations:\n"
|
||||
" kubernetes.io/role: master\n"
|
||||
" example[0]: bracket_val\n"
|
||||
"nested:\n"
|
||||
" level1.with.dots:\n"
|
||||
" inner: value\n"
|
||||
"escape_test:\n"
|
||||
" back\\slash: bslash_val\n";
|
||||
|
||||
TEST(Configuration, escaped_keys_read) {
|
||||
yaml_helper conf;
|
||||
conf.load_from_string(escaped_keys_yaml);
|
||||
|
||||
/* Key containing literal dots */
|
||||
ASSERT_STREQ(conf.get_scalar<std::string>("annotations.kubernetes\\.io/role", "none").c_str(),
|
||||
"master");
|
||||
|
||||
/* Key containing literal bracket */
|
||||
ASSERT_STREQ(conf.get_scalar<std::string>("annotations.example\\[0]", "none").c_str(),
|
||||
"bracket_val");
|
||||
|
||||
/* Multiple escaped dots */
|
||||
ASSERT_STREQ(conf.get_scalar<std::string>("nested.level1\\.with\\.dots.inner", "none").c_str(),
|
||||
"value");
|
||||
|
||||
/* Key containing literal backslash */
|
||||
ASSERT_STREQ(conf.get_scalar<std::string>("escape_test.back\\\\slash", "none").c_str(),
|
||||
"bslash_val");
|
||||
}
|
||||
|
||||
TEST(Configuration, escaped_keys_write) {
|
||||
yaml_helper conf;
|
||||
conf.load_from_string(escaped_keys_yaml);
|
||||
|
||||
/* Modify a value accessed via escaped key */
|
||||
conf.set_scalar<std::string>("annotations.kubernetes\\.io/role", "worker");
|
||||
ASSERT_STREQ(conf.get_scalar<std::string>("annotations.kubernetes\\.io/role", "none").c_str(),
|
||||
"worker");
|
||||
}
|
||||
|
||||
TEST(Configuration, escaped_keys_errors) {
|
||||
yaml_helper conf;
|
||||
conf.load_from_string(escaped_keys_yaml);
|
||||
|
||||
/* Trailing backslash */
|
||||
EXPECT_ANY_THROW(conf.get_scalar<std::string>("annotations\\", "none"));
|
||||
|
||||
/* Invalid escape sequence */
|
||||
EXPECT_ANY_THROW(conf.get_scalar<std::string>("annotations\\x", "none"));
|
||||
}
|
||||
|
||||
TEST(Configuration, configuration_webserver_ip) {
|
||||
falco_configuration falco_config;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ limitations under the License.
|
||||
#include <libsinsp/utils.h>
|
||||
|
||||
#include <re2/re2.h>
|
||||
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
#if !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
#include <cstring>
|
||||
@@ -136,7 +136,7 @@ uint64_t parse_prometheus_interval(std::string interval_str) {
|
||||
return interval;
|
||||
}
|
||||
|
||||
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
#if !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()) {
|
||||
|
||||
@@ -26,7 +26,7 @@ limitations under the License.
|
||||
namespace falco::utils {
|
||||
uint64_t parse_prometheus_interval(std::string interval_str);
|
||||
|
||||
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
#if !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
std::string calculate_file_sha256sum(const std::string& filename);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -369,23 +369,17 @@ private:
|
||||
* nested nodes, with arbitrary depth. The key string follows
|
||||
* this regular language:
|
||||
*
|
||||
* Key := NodeKey ('.' NodeKey)*
|
||||
* NodeKey := (Char | EscSeq)+ ('[' (integer)+? ']')*
|
||||
* EscSeq := '\' ('.' | '[' | '\')
|
||||
* Key := NodeKey ('.' NodeKey)*
|
||||
* NodeKey := (any)+ ('[' (integer)+? ']')*
|
||||
*
|
||||
* If can_append is true, an empty NodeKey will append a new entry
|
||||
* to the sequence, it is rejected otherwise.
|
||||
*
|
||||
* Backslash escaping allows literal dots, brackets, and backslashes
|
||||
* in key names, following the Helm --set conventions, e.g.:
|
||||
* falco -o 'annotations.kubernetes\.io/role=master'
|
||||
*
|
||||
* Some examples of accepted key strings:
|
||||
* - NodeName
|
||||
* - ListValue[3].subvalue
|
||||
* - MatrixValue[1][3]
|
||||
* - value1.subvalue2.subvalue3
|
||||
* - annotations.kubernetes\.io/role
|
||||
*/
|
||||
void get_node(YAML::Node& ret, const std::string& key, bool can_append = false) const {
|
||||
try {
|
||||
@@ -393,33 +387,6 @@ private:
|
||||
ret.reset(m_root);
|
||||
for(std::string::size_type i = 0; i < key.size(); ++i) {
|
||||
char c = key[i];
|
||||
|
||||
// Handle backslash escaping
|
||||
if(c == '\\') {
|
||||
if(i + 1 >= key.size()) {
|
||||
throw std::runtime_error("Parsing error: trailing backslash at pos " +
|
||||
std::to_string(i));
|
||||
}
|
||||
char next = key[i + 1];
|
||||
if(next != '.' && next != '[' && next != '\\') {
|
||||
throw std::runtime_error("Parsing error: invalid escape sequence '\\" +
|
||||
std::string(1, next) + "' at pos " +
|
||||
std::to_string(i));
|
||||
}
|
||||
nodeKey += next;
|
||||
++i;
|
||||
// If this escaped char is the last in the key, shift now
|
||||
if(i == key.size() - 1) {
|
||||
if(nodeKey.empty()) {
|
||||
throw std::runtime_error("Parsing error: unexpected character at pos " +
|
||||
std::to_string(i));
|
||||
}
|
||||
ret.reset(ret[nodeKey]);
|
||||
nodeKey.clear();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
bool should_shift = c == '.' || c == '[' || i == key.size() - 1;
|
||||
|
||||
if(c != '.' && c != '[') {
|
||||
|
||||
@@ -83,22 +83,16 @@ if(NOT WIN32)
|
||||
target_sources(falco_application PRIVATE outputs_program.cpp outputs_syslog.cpp)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT MINIMAL_BUILD)
|
||||
if(NOT EMSCRIPTEN AND NOT MINIMAL_BUILD)
|
||||
target_sources(falco_application PRIVATE outputs_http.cpp falco_metrics.cpp webserver.cpp)
|
||||
|
||||
list(APPEND FALCO_INCLUDE_DIRECTORIES FALCO_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}"
|
||||
"${CARES_INCLUDE}"
|
||||
)
|
||||
list(APPEND FALCO_INCLUDE_DIRECTORIES FALCO_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
|
||||
|
||||
if(TARGET c-ares)
|
||||
list(APPEND FALCO_DEPENDENCIES c-ares)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND USE_BUNDLED_CURL)
|
||||
if(USE_BUNDLED_CURL)
|
||||
list(APPEND FALCO_DEPENDENCIES curl)
|
||||
endif()
|
||||
|
||||
list(APPEND FALCO_LIBRARIES httplib::httplib "${CURL_LIBRARIES}" "${CARES_LIB}")
|
||||
list(APPEND FALCO_LIBRARIES httplib::httplib "${CURL_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
|
||||
@@ -82,7 +82,7 @@ falco::app::run_result falco::app::actions::load_rules_files(falco::app::state&
|
||||
if(res->has_warnings()) {
|
||||
falco_logger::log(falco_logger::level::WARNING, res->as_string(true, rc) + "\n");
|
||||
}
|
||||
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
#if !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
s.config->m_loaded_rules_filenames_sha256sum.insert(
|
||||
{filename, falco::utils::calculate_file_sha256sum(filename)});
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
|
||||
#include "actions.h"
|
||||
|
||||
#if defined(__linux__) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#include "webserver.h"
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@ using namespace falco::app;
|
||||
using namespace falco::app::actions;
|
||||
|
||||
falco::app::run_result falco::app::actions::start_webserver(falco::app::state& state) {
|
||||
#if defined(__linux__) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
if(state.is_capture_mode() || !state.config->m_webserver_enabled) {
|
||||
return run_result::ok();
|
||||
}
|
||||
@@ -50,7 +50,7 @@ falco::app::run_result falco::app::actions::start_webserver(falco::app::state& s
|
||||
}
|
||||
|
||||
falco::app::run_result falco::app::actions::stop_webserver(falco::app::state& state) {
|
||||
#if defined(__linux__) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
if(state.is_capture_mode() || !state.config->m_webserver_enabled) {
|
||||
return run_result::ok();
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ void options::define(cxxopts::Options& opts)
|
||||
("markdown", "DEPRECATED: use --format markdown instead. Print output in Markdown format when used in conjunction with --list or --list-events options. It has no effect when used with other options.", cxxopts::value<bool>(markdown))
|
||||
("format", "Print output in the specified <format> when used in conjunction with --list or --list-events options. Valid values are 'text', 'markdown', or 'json'. It has no effect when used with other options. Cannot be used together with --markdown.", cxxopts::value(format), "<format>")
|
||||
("N", "Only print field names when used in conjunction with the --list option. It has no effect when used with other options.", cxxopts::value(names_only)->default_value("false"))
|
||||
("o,option", "Set the value of option <opt> to <val>. Overrides values in the configuration file. <opt> can be identified using its location in the configuration file using dot notation. Elements of list entries can be accessed via square brackets []. Use backslash (\\) to escape literal dots or brackets in key names.\n E.g. base.id=val\n base.subvalue.subvalue2=val\n base.list[1]=val\n base.dotted\\.key=val", cxxopts::value(cmdline_config_options), "<opt>=<val>")
|
||||
("o,option", "Set the value of option <opt> to <val>. Overrides values in the configuration file. <opt> can be identified using its location in the configuration file using dot notation. Elements of list entries can be accessed via square brackets [].\n E.g. base.id = val\n base.subvalue.subvalue2 = val\n base.list[1]=val", cxxopts::value(cmdline_config_options), "<opt>=<val>")
|
||||
("plugin-info", "Print info for the plugin specified by <plugin_name> and exit.\nThis includes all descriptive information like name and author, along with the\nschema format for the init configuration and a list of suggested open parameters.\n<plugin_name> can be the plugin's name or its configured 'library_path'.", cxxopts::value(print_plugin_info), "<plugin_name>")
|
||||
("p,print", "DEPRECATED: use -o append_output... instead. Print additional information in the rule's output.\nUse -pc or -pcontainer to append container details to syscall events.\nUse -pk or -pkubernetes to add both container and Kubernetes details to syscall events.\nThe details will be directly appended to the rule's output.\nAlternatively, use -p <output_format> for a custom format. In this case, the given <output_format> will be appended to the rule's output without any replacement to all events, including plugin events.", cxxopts::value(print_additional), "<output_format>")
|
||||
("P,pidfile", "Write PID to specified <pid_file> path. By default, no PID file is created.", cxxopts::value(pidfilename)->default_value(""), "<pid_file>")
|
||||
|
||||
@@ -23,7 +23,7 @@ limitations under the License.
|
||||
#include "restart_handler.h"
|
||||
#include "../configuration.h"
|
||||
#include "../stats_writer.h"
|
||||
#if defined(__linux__) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#include "../webserver.h"
|
||||
#endif
|
||||
|
||||
@@ -109,7 +109,7 @@ struct state {
|
||||
// Helper responsible for watching of handling hot application restarts
|
||||
std::shared_ptr<restart_handler> restarter;
|
||||
|
||||
#if defined(__linux__) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
falco_webserver webserver;
|
||||
#endif
|
||||
// Set by start_webserver to start prometheus metrics
|
||||
|
||||
@@ -211,7 +211,7 @@ void falco_configuration::merge_config_files(const std::string &config_name,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
#if !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)});
|
||||
|
||||
@@ -115,7 +115,7 @@ std::string falco_metrics::falco_to_text_prometheus(
|
||||
"falco",
|
||||
{{"version", FALCO_VERSION}});
|
||||
|
||||
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
#if !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
|
||||
// Note that the rule counter metrics are retrieved from the state, not from any inspector
|
||||
// Distinguish between config and rules files using labels, following Prometheus best
|
||||
// practices: https://prometheus.io/docs/practices/naming/#labels
|
||||
|
||||
@@ -28,7 +28,7 @@ limitations under the License.
|
||||
#include "outputs_program.h"
|
||||
#include "outputs_syslog.h"
|
||||
#endif
|
||||
#if defined(__linux__) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#include "outputs_http.h"
|
||||
#endif
|
||||
|
||||
@@ -93,7 +93,7 @@ void falco_outputs::add_output(const falco::outputs::config &oc) {
|
||||
oo = std::make_unique<falco::outputs::output_syslog>();
|
||||
}
|
||||
#endif
|
||||
#if defined(__linux__) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
else if(oc.name == "http") {
|
||||
oo = std::make_unique<falco::outputs::output_http>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user