mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-20 11:42:06 +00:00
Compare commits
26 Commits
proposal/r
...
feat/modul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1d676f949 | ||
|
|
73f70cd0ef | ||
|
|
b1edc405c2 | ||
|
|
efe39b4360 | ||
|
|
a04ac1def3 | ||
|
|
f710edcde2 | ||
|
|
7a3d5c62a0 | ||
|
|
435a3b01db | ||
|
|
acd3e7f23a | ||
|
|
deaae756c0 | ||
|
|
5a6c7af0c5 | ||
|
|
05565f3524 | ||
|
|
980fb2f3a9 | ||
|
|
ba5e59964d | ||
|
|
60721d52cb | ||
|
|
8d9f88d45a | ||
|
|
4c04821d48 | ||
|
|
fc2c1ac6cb | ||
|
|
295c7afc32 | ||
|
|
f10b170174 | ||
|
|
9f9d0e751b | ||
|
|
322a2cdd25 | ||
|
|
5c5c2e3309 | ||
|
|
71832bc3ad | ||
|
|
93a3d14c41 | ||
|
|
c7e7a868ed |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,10 +3,12 @@
|
||||
*.pyc
|
||||
|
||||
test/falco_tests.yaml
|
||||
test/falco_traces.yaml
|
||||
test/traces-negative
|
||||
test/traces-positive
|
||||
test/traces-info
|
||||
test/job-results
|
||||
test/build
|
||||
test/.phoronix-test-suite
|
||||
test/results*.json.*
|
||||
test/build
|
||||
|
||||
@@ -20,7 +20,7 @@ cmake_minimum_required(VERSION 3.3.2)
|
||||
project(falco)
|
||||
|
||||
if(NOT SYSDIG_DIR)
|
||||
get_filename_component(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig" REALPATH)
|
||||
get_filename_component(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig" REALPATH)
|
||||
endif()
|
||||
|
||||
# Custom CMake modules
|
||||
@@ -53,7 +53,7 @@ if(BUILD_WARNINGS_AS_ERRORS)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_COMMON_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "--std=c++0x ${CMAKE_COMMON_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "--std=c++11 ${CMAKE_COMMON_FLAGS}")
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "${DRAIOS_DEBUG_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${DRAIOS_DEBUG_FLAGS}")
|
||||
|
||||
20
falco.yaml
20
falco.yaml
@@ -80,7 +80,6 @@ buffered_outputs: false
|
||||
# The rate at which log/alert messages are emitted is governed by a
|
||||
# token bucket. The rate corresponds to one message every 30 seconds
|
||||
# with a burst of 10 messages.
|
||||
|
||||
syscall_event_drops:
|
||||
actions:
|
||||
- log
|
||||
@@ -88,6 +87,21 @@ syscall_event_drops:
|
||||
rate: .03333
|
||||
max_burst: 10
|
||||
|
||||
# Options to configure the kernel module check.
|
||||
# Falco uses a kernel module to obtain the info to match against the rules.
|
||||
# In order to correctly behave it needs to ensure that the kernel module is always present and well behaving.
|
||||
# The following options configure:
|
||||
# the frequency it should check for the kernel module
|
||||
# the maximum number of consecutive failures after which it should stop
|
||||
# the exponential backoff mechanism it have to use to check for the module and eventally to try to re-insert it automatically.
|
||||
module_check:
|
||||
frequency: 10
|
||||
max_consecutive_failures: 3
|
||||
backoff:
|
||||
max_attempts: 5
|
||||
init_delay: 100
|
||||
max_delay: 3000
|
||||
|
||||
# A throttling mechanism implemented as a token bucket limits the
|
||||
# rate of falco notifications. This throttling is controlled by the following configuration
|
||||
# options:
|
||||
@@ -99,14 +113,12 @@ syscall_event_drops:
|
||||
# an initial quiet period, and then up to 1 notification per second
|
||||
# afterward. It would gain the full burst back after 1000 seconds of
|
||||
# no activity.
|
||||
|
||||
outputs:
|
||||
rate: 1
|
||||
max_burst: 1000
|
||||
|
||||
# Where security notifications should go.
|
||||
# Multiple outputs can be enabled.
|
||||
|
||||
syslog_output:
|
||||
enabled: true
|
||||
|
||||
@@ -117,7 +129,6 @@ syslog_output:
|
||||
#
|
||||
# Also, the file will be closed and reopened if falco is signaled with
|
||||
# SIGUSR1.
|
||||
|
||||
file_output:
|
||||
enabled: false
|
||||
keep_alive: false
|
||||
@@ -136,7 +147,6 @@ stdout_output:
|
||||
# $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
|
||||
# $ cat certificate.pem key.pem > falco.pem
|
||||
# $ sudo cp falco.pem /etc/falco/falco.pem
|
||||
|
||||
webserver:
|
||||
enabled: true
|
||||
listen_port: 8765
|
||||
|
||||
@@ -19,7 +19,7 @@ configure_file(debian/postinst.in debian/postinst)
|
||||
configure_file(debian/prerm.in debian/prerm)
|
||||
|
||||
if(NOT SYSDIG_DIR)
|
||||
set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig")
|
||||
get_filename_component(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig" REALPATH)
|
||||
endif()
|
||||
|
||||
file(COPY "${PROJECT_SOURCE_DIR}/scripts/debian/falco"
|
||||
|
||||
1
test/.gitignore
vendored
1
test/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
falco_traces.yaml
|
||||
@@ -40,6 +40,8 @@ class FalcoTest(Test):
|
||||
build_type = "debug" if build_type == "debug" else "release"
|
||||
|
||||
build_dir = os.path.join('/build', build_type)
|
||||
if not os.path.exists(build_dir):
|
||||
build_dir = '../build'
|
||||
self.falcodir = self.params.get('falcodir', '/', default=os.path.join(self.basedir, build_dir))
|
||||
|
||||
self.stdout_is = self.params.get('stdout_is', '*', default='')
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
if(NOT SYSDIG_DIR)
|
||||
set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig")
|
||||
get_filename_component(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig" REALPATH)
|
||||
endif()
|
||||
|
||||
set(FALCO_ENGINE_SOURCE_FILES
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
if(NOT SYSDIG_DIR)
|
||||
set(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig")
|
||||
get_filename_component(SYSDIG_DIR "${PROJECT_SOURCE_DIR}/../sysdig" REALPATH)
|
||||
endif()
|
||||
|
||||
configure_file("${SYSDIG_DIR}/userspace/sysdig/config_sysdig.h.in" config_sysdig.h)
|
||||
@@ -27,6 +27,8 @@ add_executable(falco
|
||||
falco_outputs.cpp
|
||||
event_drops.cpp
|
||||
statsfilewriter.cpp
|
||||
timer.cpp
|
||||
module_utils.cpp
|
||||
falco.cpp
|
||||
"${SYSDIG_DIR}/userspace/sysdig/fields_info.cpp"
|
||||
webserver.cpp)
|
||||
@@ -49,16 +51,11 @@ target_link_libraries(falco
|
||||
configure_file(config_falco.h.in config_falco.h)
|
||||
|
||||
add_custom_command(TARGET falco
|
||||
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/verify_engine_fields.sh ${CMAKE_SOURCE_DIR}
|
||||
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/verify_engine_fields ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Comparing engine fields checksum in falco_engine.h to actual fields"
|
||||
)
|
||||
|
||||
# add_custom_target(verify_engine_fields
|
||||
# DEPENDS verify_engine_fields.sh falco_engine.h)
|
||||
|
||||
# add_dependencies(verify_engine_fields falco)
|
||||
|
||||
install(TARGETS falco DESTINATION ${FALCO_BIN_DIR})
|
||||
install(DIRECTORY lua
|
||||
DESTINATION ${FALCO_SHARE_DIR}
|
||||
|
||||
@@ -27,4 +27,4 @@ limitations under the License.
|
||||
#define FALCO_INSTALL_CONF_FILE "/etc/falco/falco.yaml"
|
||||
#define FALCO_SOURCE_LUA_DIR "${PROJECT_SOURCE_DIR}/userspace/falco/lua/"
|
||||
|
||||
#define PROBE_NAME "${PROBE_NAME}"
|
||||
#define PROBE_NAME "@PROBE_NAME@"
|
||||
|
||||
@@ -220,6 +220,15 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
|
||||
m_syscall_evt_drop_rate = m_config->get_scalar<double>("syscall_event_drops", "rate", 0.3333);
|
||||
m_syscall_evt_drop_max_burst = m_config->get_scalar<double>("syscall_event_drops", "max_burst", 10);
|
||||
|
||||
m_module_check_frequency = m_config->get_scalar<uint64_t>("module_check", "frequency", 10);
|
||||
if(m_module_check_frequency < 10) {
|
||||
throw invalid_argument("Module check frequency must be higher than 10 seconds");
|
||||
}
|
||||
m_module_check_max_consecutive_failures = m_config->get_scalar<int>("module_check", "max_consecutive_failures", 3);
|
||||
m_module_check_backoff_max_attempts = m_config->get_scalar<int>("module_check", "backoff", "max_attempts", 5);
|
||||
m_module_check_backoff_init_delay = m_config->get_scalar<uint64_t>("module_check", "backoff", "init_delay", 100);
|
||||
m_module_check_backoff_max_delay = m_config->get_scalar<uint64_t>("module_check", "backoff", "max_delay", 3000);
|
||||
|
||||
m_syscall_evt_simulate_drops = m_config->get_scalar<bool>("syscall_event_drops", "simulate_drops", false);
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,47 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a scalar value defined inside a 3 level nested structure like:
|
||||
* file_output:
|
||||
* enabled: true
|
||||
* filename: output_file.txt
|
||||
*
|
||||
* get_scalar<bool>("file_output", "enabled", false)
|
||||
*/
|
||||
template<typename T>
|
||||
const T get_scalar(const std::string& key, const std::string& subkey, const std::string& subsubkey, const T& default_value)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto node = m_root[key][subkey][subsubkey];
|
||||
if (node.IsDefined())
|
||||
{
|
||||
return node.as<T>();
|
||||
}
|
||||
}
|
||||
catch (const YAML::BadConversion& ex)
|
||||
{
|
||||
std::cerr << "Cannot read config file (" + m_path + "): wrong type at key " + key + "\n";
|
||||
throw;
|
||||
}
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the second-level node identified by key[key][subkey] to value.
|
||||
*/
|
||||
template<typename T>
|
||||
void set_scalar(const std::string& key, const std::string& subkey, const std::string& subsubkey, const T& value)
|
||||
{
|
||||
auto node = m_root;
|
||||
if (node.IsDefined())
|
||||
{
|
||||
node[key][subkey][subsubkey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// called with the last variadic arg (where the sequence is expected to be found)
|
||||
template <typename T>
|
||||
void get_sequence_from_node(T& ret, const YAML::Node &node)
|
||||
@@ -216,6 +257,12 @@ class falco_configuration
|
||||
double m_syscall_evt_drop_rate;
|
||||
double m_syscall_evt_drop_max_burst;
|
||||
|
||||
uint64_t m_module_check_frequency;
|
||||
int m_module_check_max_consecutive_failures;
|
||||
int m_module_check_backoff_max_attempts;
|
||||
uint64_t m_module_check_backoff_init_delay;
|
||||
uint64_t m_module_check_backoff_max_delay;
|
||||
|
||||
// Only used for testing
|
||||
bool m_syscall_evt_simulate_drops;
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@ limitations under the License.
|
||||
#include "config_falco.h"
|
||||
#include "statsfilewriter.h"
|
||||
#include "webserver.h"
|
||||
#include "timer.h"
|
||||
#include "retry.h"
|
||||
#include "module_utils.h"
|
||||
|
||||
typedef function<void(sinsp* inspector)> open_t;
|
||||
|
||||
@@ -228,6 +231,8 @@ uint64_t do_inspect(falco_engine *engine,
|
||||
string &stats_filename,
|
||||
uint64_t stats_interval,
|
||||
bool all_events,
|
||||
bool verbose,
|
||||
bool disable_syscall,
|
||||
int &result)
|
||||
{
|
||||
uint64_t num_evts = 0;
|
||||
@@ -253,11 +258,42 @@ uint64_t do_inspect(falco_engine *engine,
|
||||
}
|
||||
}
|
||||
|
||||
// Module check settings
|
||||
utils::timer t;
|
||||
t.reset();
|
||||
|
||||
uint64_t frequency = config.m_module_check_frequency;
|
||||
auto num_failures = 0;
|
||||
auto max_failures = config.m_module_check_max_consecutive_failures;
|
||||
auto max_attempts = config.m_module_check_backoff_max_attempts;
|
||||
auto ini_delay = config.m_module_check_backoff_init_delay;
|
||||
auto max_delay = config.m_module_check_backoff_max_delay;
|
||||
|
||||
//
|
||||
// Loop through the events
|
||||
//
|
||||
while(1)
|
||||
while(true)
|
||||
{
|
||||
// Check module every x seconds
|
||||
if(!disable_syscall && t.seconds_elapsed() > frequency)
|
||||
{
|
||||
// Check module is present and loaded with exponential backoff (eg., 100, 200, 400, ...)
|
||||
// When module is missing or unloaded, try to insert it
|
||||
// Retries at most <max_attempts> times
|
||||
// Stops early if module is found
|
||||
auto found = utils::retry(max_attempts, ini_delay, max_delay, utils::module_predicate, utils::has_module, verbose, true);
|
||||
|
||||
// Count how many intervals the module is missing, reset counter when module has been found
|
||||
num_failures = found ? 0 : num_failures + 1;
|
||||
// Stop falco if module is missing from <count * stop_after> checks
|
||||
if (num_failures >= max_failures)
|
||||
{
|
||||
result = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
// Reset timer
|
||||
t.reset();
|
||||
}
|
||||
|
||||
rc = inspector->next(&ev);
|
||||
|
||||
@@ -271,7 +307,7 @@ uint64_t do_inspect(falco_engine *engine,
|
||||
|
||||
if (g_terminate || g_restart)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "SIGHUP Received, restarting...\n");
|
||||
falco_logger::log(LOG_INFO, "SIGHUP received, restarting...\n");
|
||||
break;
|
||||
}
|
||||
else if(rc == SCAP_TIMEOUT)
|
||||
@@ -292,10 +328,11 @@ uint64_t do_inspect(falco_engine *engine,
|
||||
throw sinsp_exception(inspector->getlasterr().c_str());
|
||||
}
|
||||
|
||||
if (duration_start == 0)
|
||||
if(duration_start == 0)
|
||||
{
|
||||
duration_start = ev->get_ts();
|
||||
} else if(duration_to_tot_ns > 0)
|
||||
}
|
||||
else if(duration_to_tot_ns > 0)
|
||||
{
|
||||
if(ev->get_ts() - duration_start >= duration_to_tot_ns)
|
||||
{
|
||||
@@ -1068,6 +1105,17 @@ int falco_init(int argc, char **argv)
|
||||
if (disable_k8s_audit) {
|
||||
open_f = open_cb;
|
||||
}
|
||||
|
||||
// Check that the kernel module is present at startup, otherwise try to add it
|
||||
if(!utils::has_module(verbose, false))
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Module not found. Trying to load it ...\n");
|
||||
if(!utils::ins_module())
|
||||
{
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1075,11 +1123,7 @@ int falco_init(int argc, char **argv)
|
||||
}
|
||||
catch(sinsp_exception &e)
|
||||
{
|
||||
if(system("modprobe " PROBE_NAME " > /dev/null 2> /dev/null"))
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Unable to load the driver. Exiting.\n");
|
||||
}
|
||||
open_f(inspector);
|
||||
rethrow_exception(current_exception());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1170,9 +1214,7 @@ int falco_init(int argc, char **argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t num_evts;
|
||||
|
||||
num_evts = do_inspect(engine,
|
||||
uint64_t num_evts = do_inspect(engine,
|
||||
outputs,
|
||||
inspector,
|
||||
config,
|
||||
@@ -1181,6 +1223,8 @@ int falco_init(int argc, char **argv)
|
||||
stats_filename,
|
||||
stats_interval,
|
||||
all_events,
|
||||
verbose,
|
||||
disable_syscall,
|
||||
result);
|
||||
|
||||
duration = ((double)clock()) / CLOCKS_PER_SEC - duration;
|
||||
@@ -1189,11 +1233,11 @@ int falco_init(int argc, char **argv)
|
||||
|
||||
if(verbose)
|
||||
{
|
||||
fprintf(stderr, "Driver Events:%" PRIu64 "\nDriver Drops:%" PRIu64 "\n",
|
||||
fprintf(stdout, "Driver events: %" PRIu64 "\nDriver drops: %" PRIu64 "\n",
|
||||
cstats.n_evts,
|
||||
cstats.n_drops);
|
||||
|
||||
fprintf(stderr, "Elapsed time: %.3lf, Captured Events: %" PRIu64 ", %.2lf eps\n",
|
||||
fprintf(stdout, "Elapsed time: %.3lf\nCaptured events: %" PRIu64 "\nEps: %.2lf\n",
|
||||
duration,
|
||||
num_evts,
|
||||
num_evts / duration);
|
||||
|
||||
120
userspace/falco/module_utils.cpp
Normal file
120
userspace/falco/module_utils.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright (C) 2016-2019 Draios Inc dba Sysdig.
|
||||
|
||||
This file is part of falco.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "config_falco.h"
|
||||
#include "logger.h"
|
||||
#include "module_utils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
bool has_module(bool verbose, bool strict)
|
||||
{
|
||||
// Comparing considering underscores (95) equal to dashes (45), and viceversa
|
||||
std::function<bool(const char &, const char &)> comparator = [](const char &a, const char &b) {
|
||||
return a == b || (a == 45 && b == 95) || (b == 95 && a == 45);
|
||||
};
|
||||
|
||||
std::ifstream modules(db);
|
||||
std::string line;
|
||||
|
||||
while(std::getline(modules, line))
|
||||
{
|
||||
bool shorter = module.length() <= line.length();
|
||||
if(shorter && std::equal(module.begin(), module.end(), line.begin(), comparator))
|
||||
{
|
||||
bool result = true;
|
||||
if(!strict)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Kernel module found: true (not strict)\n");
|
||||
modules.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
std::istringstream iss(line);
|
||||
std::vector<std::string> cols(std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>());
|
||||
|
||||
// Check the module's number of instances - ie., whether it is loaded or not
|
||||
auto ninstances = cols.at(2);
|
||||
result = result && std::stoi(ninstances) > 0;
|
||||
|
||||
// Check the module's load state
|
||||
auto state = cols.at(4);
|
||||
std::transform(state.begin(), state.end(), state.begin(), ::tolower);
|
||||
result = result && (state == module_state_live);
|
||||
|
||||
if(verbose)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Kernel module instances: " + ninstances + "\n");
|
||||
falco_logger::log(LOG_INFO, "Kernel module load state: " + state + "\n");
|
||||
}
|
||||
|
||||
// Check the module's taint state
|
||||
if(cols.size() > 6)
|
||||
{
|
||||
auto taint = cols.at(6);
|
||||
auto died = taint.find(taint_die) != std::string::npos;
|
||||
auto warn = taint.find(taint_warn) != std::string::npos;
|
||||
auto unloaded = taint.find(taint_forced_rmmod) != std::string::npos;
|
||||
result = result && !died && !warn && !unloaded;
|
||||
|
||||
if(verbose)
|
||||
{
|
||||
taint.erase(0, taint.find_first_not_of('('));
|
||||
taint.erase(taint.find_last_not_of(')') + 1);
|
||||
falco_logger::log(LOG_INFO, "Kernel module taint state: " + taint + "\n");
|
||||
std::ostringstream message;
|
||||
message << std::boolalpha << "Kernel module presence: " << result << "\n";
|
||||
falco_logger::log(LOG_INFO, message.str());
|
||||
}
|
||||
}
|
||||
|
||||
modules.close();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
modules.close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ins_module()
|
||||
{
|
||||
if(system("modprobe " PROBE_NAME " > /dev/null 2> /dev/null"))
|
||||
{
|
||||
// todo > fallback to a custom directory where to look for the module using `modprobe -d build/driver`
|
||||
falco_logger::log(LOG_ERR, "Unable to load the module.\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool module_predicate(bool has_module)
|
||||
{
|
||||
if(has_module)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Retry only when we have been not able to insert the module
|
||||
return !ins_module();
|
||||
}
|
||||
} // namespace utils
|
||||
37
userspace/falco/module_utils.h
Normal file
37
userspace/falco/module_utils.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2016-2019 Draios Inc dba Sysdig.
|
||||
|
||||
This file is part of falco.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
const std::string db("/proc/modules");
|
||||
const std::string module(PROBE_NAME);
|
||||
const std::string module_state_live("live");
|
||||
// Module's taint state constants
|
||||
// see: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/panic.c#n351
|
||||
const std::string taint_die("D");
|
||||
const std::string taint_forced_rmmod("R");
|
||||
const std::string taint_warn("W");
|
||||
bool has_module(bool verbose, bool strict);
|
||||
bool ins_module();
|
||||
bool module_predicate(bool has_module);
|
||||
} // namespace utils
|
||||
85
userspace/falco/retry.h
Normal file
85
userspace/falco/retry.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright (C) 2016-2019 Draios Inc dba Sysdig.
|
||||
|
||||
This file is part of falco.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#if __cplusplus < 201402L
|
||||
template< class T >
|
||||
using decay_t = typename decay<T>::type;
|
||||
|
||||
template< bool B, class T = void >
|
||||
using enable_if_t = typename enable_if<B,T>::type;
|
||||
#endif
|
||||
|
||||
#if __cplusplus != 201402L || __cplusplus != 201703L
|
||||
template< class F, class... ArgTypes>
|
||||
using result_of_t = typename result_of<F, ArgTypes...>::type;
|
||||
#endif
|
||||
|
||||
namespace utils
|
||||
{
|
||||
template<
|
||||
typename Predicate,
|
||||
typename Callable,
|
||||
typename... Args,
|
||||
// figure out the callable return type
|
||||
typename R = decay_t<result_of_t<Callable &(Args...)>>,
|
||||
// require that Predicate is actually a Predicate
|
||||
enable_if_t<std::is_convertible<result_of_t<Predicate &(R)>, bool>::value, int> = 0>
|
||||
R retry(int max_retries,
|
||||
uint64_t initial_delay_ms,
|
||||
uint64_t max_backoff_ms,
|
||||
Predicate &&retriable,
|
||||
Callable &&callable,
|
||||
Args &&... args)
|
||||
{
|
||||
int retries = 0;
|
||||
while(true)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Retry no.: " + std::to_string(retries) + "\n");
|
||||
bool result = callable(std::forward<Args>(args)...);
|
||||
|
||||
if(!retriable(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if(retries >= max_retries)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
int64_t delay = 0;
|
||||
if(initial_delay_ms > 0)
|
||||
{
|
||||
delay = std::min(initial_delay_ms << retries, max_backoff_ms);
|
||||
}
|
||||
|
||||
std::ostringstream message;
|
||||
message << "Waiting " << delay << "ms ... \n";
|
||||
falco_logger::log(LOG_INFO, message.str());
|
||||
// Blocking for `delay` ms
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
|
||||
retries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
userspace/falco/timer.cpp
Normal file
34
userspace/falco/timer.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright (C) 2016-2019 Draios Inc dba Sysdig.
|
||||
|
||||
This file is part of falco.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
void timer::reset()
|
||||
{
|
||||
start = clock::now();
|
||||
}
|
||||
|
||||
unsigned long long timer::seconds_elapsed() const
|
||||
{
|
||||
return std::chrono::duration_cast<seconds>(clock::now() - start).count();
|
||||
}
|
||||
} // namespace utils
|
||||
37
userspace/falco/timer.h
Normal file
37
userspace/falco/timer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2016-2019 Draios Inc dba Sysdig.
|
||||
|
||||
This file is part of falco.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
struct timer
|
||||
{
|
||||
typedef std::chrono::steady_clock clock;
|
||||
typedef std::chrono::seconds seconds;
|
||||
|
||||
void reset();
|
||||
|
||||
unsigned long long seconds_elapsed() const;
|
||||
|
||||
private:
|
||||
clock::time_point start;
|
||||
};
|
||||
} // namespace utils
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
set -eu -o pipefail
|
||||
|
||||
SOURCE_DIR=$1
|
||||
OPENSSL=../../openssl-prefix/src/openssl/target/bin/openssl
|
||||
@@ -11,13 +11,13 @@ if ! command -v ${OPENSSL} version > /dev/null 2>&1; then
|
||||
fi
|
||||
|
||||
NEW_CHECKSUM=$(./falco --list -N | ${OPENSSL} dgst -sha256 | awk '{print $2}')
|
||||
CUR_CHECKSUM=$(grep FALCO_FIELDS_CHECKSUM ${SOURCE_DIR}/userspace/engine/falco_engine_version.h | awk '{print $3}' | sed -e 's/"//g')
|
||||
CUR_CHECKSUM=$(grep FALCO_FIELDS_CHECKSUM "${SOURCE_DIR}/userspace/engine/falco_engine_version.h" | awk '{print $3}' | sed -e 's/"//g')
|
||||
|
||||
|
||||
if [ $NEW_CHECKSUM != $CUR_CHECKSUM ]; then
|
||||
if [ "$NEW_CHECKSUM" != "$CUR_CHECKSUM" ]; then
|
||||
echo "Set of fields supported by falco/sysdig libraries has changed (new checksum $NEW_CHECKSUM != old checksum $CUR_CHECKSUM)."
|
||||
echo "Update checksum and/or version in falco_engine_version.h."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
exit 0
|
||||
@@ -175,12 +175,6 @@ void falco_webserver::init(falco_configuration *config,
|
||||
m_outputs = outputs;
|
||||
}
|
||||
|
||||
template<typename T, typename ...Args>
|
||||
std::unique_ptr<T> make_unique( Args&& ...args )
|
||||
{
|
||||
return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
|
||||
}
|
||||
|
||||
void falco_webserver::start()
|
||||
{
|
||||
if(m_server)
|
||||
|
||||
@@ -25,6 +25,14 @@ limitations under the License.
|
||||
#include "falco_engine.h"
|
||||
#include "falco_outputs.h"
|
||||
|
||||
#if __cplusplus < 201402L
|
||||
template<typename T, typename... Ts>
|
||||
std::unique_ptr<T> make_unique(Ts&&... params)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::forward<Ts>(params)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
class k8s_audit_handler : public CivetHandler
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user