mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-10 18:42:33 +00:00
new(userspace/falco): added an option to listen to changes on the config file and rules files, and trigger a Falco reload.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
This commit is contained in:
parent
8c6cfae18f
commit
e32f5a66c5
@ -18,6 +18,8 @@ limitations under the License.
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
|
||||||
@ -30,6 +32,7 @@ using namespace falco::app;
|
|||||||
|
|
||||||
static application dummy;
|
static application dummy;
|
||||||
static std::reference_wrapper<application> s_app = dummy;
|
static std::reference_wrapper<application> s_app = dummy;
|
||||||
|
static int inot_fd;
|
||||||
|
|
||||||
static void signal_callback(int signal)
|
static void signal_callback(int signal)
|
||||||
{
|
{
|
||||||
@ -85,10 +88,87 @@ application::run_result application::create_signal_handlers()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
application::run_result application::attach_inotify_signals()
|
||||||
|
{
|
||||||
|
run_result ret;
|
||||||
|
if (m_options.monitor_files)
|
||||||
|
{
|
||||||
|
inot_fd = inotify_init();
|
||||||
|
if (inot_fd == -1)
|
||||||
|
{
|
||||||
|
ret.success = false;
|
||||||
|
ret.errstr = std::string("Could not create inotify handler.");
|
||||||
|
ret.proceed = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sigaction sa;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
sa.sa_handler = restart_falco;
|
||||||
|
if (sigaction(SIGIO, &sa, NULL) == -1)
|
||||||
|
{
|
||||||
|
ret.success = false;
|
||||||
|
ret.errstr = std::string("Failed to link SIGIO to inotify handler.");
|
||||||
|
ret.proceed = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set owner process that is to receive "I/O possible" signal */
|
||||||
|
if (fcntl(inot_fd, F_SETOWN, getpid()) == -1)
|
||||||
|
{
|
||||||
|
ret.success = false;
|
||||||
|
ret.errstr = std::string("Failed to setting owner on inotify handler.");
|
||||||
|
ret.proceed = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable "I/O possible" signaling and make I/O nonblocking
|
||||||
|
* for file descriptor
|
||||||
|
*/
|
||||||
|
int flags = fcntl(inot_fd, F_GETFL);
|
||||||
|
if (fcntl(inot_fd, F_SETFL, flags | O_ASYNC | O_NONBLOCK) == -1)
|
||||||
|
{
|
||||||
|
ret.success = false;
|
||||||
|
ret.errstr = std::string("Failed to setting flags on inotify handler.");
|
||||||
|
ret.proceed = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add watchers */
|
||||||
|
int wd = inotify_add_watch(inot_fd, m_options.conf_filename.c_str(), IN_CLOSE_WRITE);
|
||||||
|
if (wd == -1)
|
||||||
|
{
|
||||||
|
ret.success = false;
|
||||||
|
ret.errstr = std::string("Failed to watch conf file.");
|
||||||
|
ret.proceed = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
falco_logger::log(LOG_DEBUG, "Watching " + m_options.conf_filename +"\n");
|
||||||
|
|
||||||
|
for (const auto &rule : m_state->config->m_rules_filenames) {
|
||||||
|
wd = inotify_add_watch(inot_fd, rule.c_str(), IN_CLOSE_WRITE);
|
||||||
|
if (wd == -1)
|
||||||
|
{
|
||||||
|
ret.success = false;
|
||||||
|
ret.errstr = std::string("Failed to watch rule file: ") + rule;
|
||||||
|
ret.proceed = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
falco_logger::log(LOG_DEBUG, "Watching " + rule +"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool application::unregister_signal_handlers(std::string &errstr)
|
bool application::unregister_signal_handlers(std::string &errstr)
|
||||||
{
|
{
|
||||||
run_result ret;
|
run_result ret;
|
||||||
|
|
||||||
|
close(inot_fd);
|
||||||
|
|
||||||
if(! create_handler(SIGINT, SIG_DFL, ret) ||
|
if(! create_handler(SIGINT, SIG_DFL, ret) ||
|
||||||
! create_handler(SIGTERM, SIG_DFL, ret) ||
|
! create_handler(SIGTERM, SIG_DFL, ret) ||
|
||||||
! create_handler(SIGUSR1, SIG_DFL, ret) ||
|
! create_handler(SIGUSR1, SIG_DFL, ret) ||
|
||||||
|
@ -22,7 +22,7 @@ application::run_result application::load_config()
|
|||||||
{
|
{
|
||||||
run_result ret;
|
run_result ret;
|
||||||
|
|
||||||
if (m_options.conf_filename.size())
|
if (!m_options.conf_filename.empty())
|
||||||
{
|
{
|
||||||
m_state->config->init(m_options.conf_filename, m_options.cmdline_config_options);
|
m_state->config->init(m_options.conf_filename, m_options.cmdline_config_options);
|
||||||
falco_logger::set_time_format_iso_8601(m_state->config->m_time_format_iso_8601);
|
falco_logger::set_time_format_iso_8601(m_state->config->m_time_format_iso_8601);
|
||||||
|
@ -72,12 +72,12 @@ application::run_result application::load_rules_files()
|
|||||||
|
|
||||||
string all_rules;
|
string all_rules;
|
||||||
|
|
||||||
if (m_options.rules_filenames.size())
|
if (!m_options.rules_filenames.empty())
|
||||||
{
|
{
|
||||||
m_state->config->m_rules_filenames = m_options.rules_filenames;
|
m_state->config->m_rules_filenames = m_options.rules_filenames;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_state->config->m_rules_filenames.size() == 0)
|
if(m_state->config->m_rules_filenames.empty())
|
||||||
{
|
{
|
||||||
ret.success = false;
|
ret.success = false;
|
||||||
ret.errstr = "You must specify at least one rules file/directory via -r or a rules_file entry in falco.yaml";
|
ret.errstr = "You must specify at least one rules file/directory via -r or a rules_file entry in falco.yaml";
|
||||||
|
@ -181,6 +181,7 @@ void cmdline_options::define()
|
|||||||
#endif
|
#endif
|
||||||
("M", "Stop collecting after <num_seconds> reached.", cxxopts::value(duration_to_tot)->default_value("0"), "<num_seconds>")
|
("M", "Stop collecting after <num_seconds> reached.", cxxopts::value(duration_to_tot)->default_value("0"), "<num_seconds>")
|
||||||
("markdown", "When used with --list/--list-syscall-events, print the content in Markdown format", cxxopts::value<bool>(markdown))
|
("markdown", "When used with --list/--list-syscall-events, print the content in Markdown format", cxxopts::value<bool>(markdown))
|
||||||
|
("monitor_files", "Monitor rules and config files to reload Falco on change.", cxxopts::value<bool>(monitor_files))
|
||||||
("N", "When used with --list, only print field names.", cxxopts::value(names_only)->default_value("false"))
|
("N", "When used with --list, only print field names.", cxxopts::value(names_only)->default_value("false"))
|
||||||
("o,option", "Set the value of option <opt> to <val>. Overrides values in configuration file. <opt> can be identified using its location in configuration file using dot notation. Elements which are entries of lists 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>")
|
("o,option", "Set the value of option <opt> to <val>. Overrides values in configuration file. <opt> can be identified using its location in configuration file using dot notation. Elements which are entries of lists 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>")
|
||||||
("p,print", "Add additional information to each falco notification's output.\nWith -pc or -pcontainer will use a container-friendly format.\nWith -pk or -pkubernetes will use a kubernetes-friendly format.\nWith -pm or -pmesos will use a mesos-friendly format.\nAdditionally, specifying -pc/-pk/-pm will change the interpretation of %container.info in rule output fields.", cxxopts::value(print_additional), "<output_format>")
|
("p,print", "Add additional information to each falco notification's output.\nWith -pc or -pcontainer will use a container-friendly format.\nWith -pk or -pkubernetes will use a kubernetes-friendly format.\nWith -pm or -pmesos will use a mesos-friendly format.\nAdditionally, specifying -pc/-pk/-pm will change the interpretation of %container.info in rule output fields.", cxxopts::value(print_additional), "<output_format>")
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
// Each of these maps directly to a command line option.
|
// Each of these maps directly to a command line option.
|
||||||
bool help;
|
bool help;
|
||||||
std::string conf_filename;
|
std::string conf_filename;
|
||||||
|
bool monitor_files;
|
||||||
bool all_events;
|
bool all_events;
|
||||||
sinsp_evt::param_fmt event_buffer_format;
|
sinsp_evt::param_fmt event_buffer_format;
|
||||||
std::vector<std::string> cri_socket_paths;
|
std::vector<std::string> cri_socket_paths;
|
||||||
|
@ -138,6 +138,7 @@ bool application::run(std::string &errstr, bool &restart)
|
|||||||
std::bind(&application::print_ignored_events, this),
|
std::bind(&application::print_ignored_events, this),
|
||||||
std::bind(&application::print_support, this),
|
std::bind(&application::print_support, this),
|
||||||
std::bind(&application::validate_rules_files, this),
|
std::bind(&application::validate_rules_files, this),
|
||||||
|
std::bind(&application::attach_inotify_signals, this),
|
||||||
std::bind(&application::daemonize, this),
|
std::bind(&application::daemonize, this),
|
||||||
std::bind(&application::init_outputs, this),
|
std::bind(&application::init_outputs, this),
|
||||||
std::bind(&application::open_inspector, this),
|
std::bind(&application::open_inspector, this),
|
||||||
|
@ -125,6 +125,7 @@ private:
|
|||||||
// These methods comprise the code the application "runs". The
|
// These methods comprise the code the application "runs". The
|
||||||
// order in which the methods run is in application.cpp.
|
// order in which the methods run is in application.cpp.
|
||||||
run_result create_signal_handlers();
|
run_result create_signal_handlers();
|
||||||
|
run_result attach_inotify_signals();
|
||||||
run_result daemonize();
|
run_result daemonize();
|
||||||
run_result init_falco_engine();
|
run_result init_falco_engine();
|
||||||
run_result init_inspector();
|
run_result init_inspector();
|
||||||
|
Loading…
Reference in New Issue
Block a user