mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-31 06:01:52 +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 <signal.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "application.h"
|
||||
|
||||
@ -30,6 +32,7 @@ using namespace falco::app;
|
||||
|
||||
static application dummy;
|
||||
static std::reference_wrapper<application> s_app = dummy;
|
||||
static int inot_fd;
|
||||
|
||||
static void signal_callback(int signal)
|
||||
{
|
||||
@ -85,10 +88,87 @@ application::run_result application::create_signal_handlers()
|
||||
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)
|
||||
{
|
||||
run_result ret;
|
||||
|
||||
close(inot_fd);
|
||||
|
||||
if(! create_handler(SIGINT, SIG_DFL, ret) ||
|
||||
! create_handler(SIGTERM, SIG_DFL, ret) ||
|
||||
! create_handler(SIGUSR1, SIG_DFL, ret) ||
|
||||
|
@ -22,7 +22,7 @@ application::run_result application::load_config()
|
||||
{
|
||||
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);
|
||||
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;
|
||||
|
||||
if (m_options.rules_filenames.size())
|
||||
if (!m_options.rules_filenames.empty())
|
||||
{
|
||||
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.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
|
||||
("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))
|
||||
("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"))
|
||||
("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>")
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
// Each of these maps directly to a command line option.
|
||||
bool help;
|
||||
std::string conf_filename;
|
||||
bool monitor_files;
|
||||
bool all_events;
|
||||
sinsp_evt::param_fmt event_buffer_format;
|
||||
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_support, this),
|
||||
std::bind(&application::validate_rules_files, this),
|
||||
std::bind(&application::attach_inotify_signals, this),
|
||||
std::bind(&application::daemonize, this),
|
||||
std::bind(&application::init_outputs, this),
|
||||
std::bind(&application::open_inspector, this),
|
||||
|
@ -125,6 +125,7 @@ private:
|
||||
// These methods comprise the code the application "runs". The
|
||||
// order in which the methods run is in application.cpp.
|
||||
run_result create_signal_handlers();
|
||||
run_result attach_inotify_signals();
|
||||
run_result daemonize();
|
||||
run_result init_falco_engine();
|
||||
run_result init_inspector();
|
||||
|
Loading…
Reference in New Issue
Block a user