mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-01 19:25:19 +00:00
Add daemonization, fix any bugs found.
Add support for daemonizing via the --daemon flag. If daemonized, the pid is written to the file provided via the --pidfile flag. When daemonized, falco immediately returns an error if stderr output or logging was chosen on the command line. Clean up handling of outputs to match the expected use case (daemon): - syslog output is enabled by default - stdout output is disabled by default - If not configured at all, both outputs are enabled. Also fix some bugs I found while running via packages: - There were still some references to the old rules filename falco_rules.conf. - The redhat package mistakenly defined some system directories like /etc, /etc/init.d. Add them to the exclusion list (See https://cmake.org/Bug/view.php?id=13609 for context). - Clean up some of the error messages to be more consistent. After this I was able to build and install debian and rpm packages. Starting the falco service ran falco as a daemon with syslog output.
This commit is contained in:
parent
cfc89127e7
commit
a787dc84d5
@ -209,6 +209,7 @@ set(CPACK_RPM_PACKAGE_REQUIRES "sysdig")
|
||||
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/postinstall")
|
||||
set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/preuninstall")
|
||||
set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/scripts/rpm/postuninstall")
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/src /usr/share/man /usr/share/man/man8)
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/src /usr/share/man /usr/share/man/man8 /etc /usr /usr/bin /usr/share /etc/rc.d /etc/rc.d/init.d )
|
||||
set(CPACK_RPM_PACKAGE_RELOCATABLE "OFF")
|
||||
|
||||
include(CPack)
|
||||
|
@ -1,16 +1,16 @@
|
||||
rules_file: /etc/falco_rules.conf
|
||||
rules_file: /etc/falco_rules.yaml
|
||||
json_output: false
|
||||
|
||||
log_stderr: true
|
||||
log_syslog: true
|
||||
|
||||
syslog_output:
|
||||
enabled: false
|
||||
enabled: true
|
||||
|
||||
file_output:
|
||||
enabled: true
|
||||
filename: ./events.txt
|
||||
|
||||
stdout_output:
|
||||
enabled: true
|
||||
enabled: false
|
||||
|
||||
|
@ -20,7 +20,7 @@ DESC="Falco"
|
||||
NAME=falco
|
||||
DAEMON=/usr/bin/$NAME
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
DAEMON_ARGS="--daemon --falcopid=$PIDFILE"
|
||||
DAEMON_ARGS="--daemon --pidfile=$PIDFILE"
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Exit if the package is not installed
|
||||
|
@ -34,7 +34,7 @@ start() {
|
||||
[ -x $exec ] || exit 5
|
||||
# [ -f $config ] || exit 6
|
||||
echo -n $"Starting $prog: "
|
||||
daemon $exec --daemon --falcopid=$pidfile
|
||||
daemon $exec --daemon --pidfile=$pidfile
|
||||
retval=$?
|
||||
echo
|
||||
[ $retval -eq 0 ] && touch $lockfile
|
||||
|
@ -19,7 +19,7 @@ void falco_configuration::init(string conf_filename)
|
||||
string m_config_file = conf_filename;
|
||||
m_config = new yaml_configuration(m_config_file);
|
||||
|
||||
m_rules_filename = m_config->get_scalar<string>("rules_file", "/etc/falco_rules.conf");
|
||||
m_rules_filename = m_config->get_scalar<string>("rules_file", "/etc/falco_rules.yaml");
|
||||
m_json_output = m_config->get_scalar<bool>("json_output", false);
|
||||
|
||||
output_config file_output;
|
||||
|
@ -39,11 +39,13 @@ static void usage()
|
||||
printf(
|
||||
"Usage: falco [options] rules_filename\n\n"
|
||||
"Options:\n"
|
||||
" -h, --help Print this page\n"
|
||||
" -c Configuration file (default " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ")\n"
|
||||
" -o Output type (options are 'stdout', 'syslog', default is 'stdout')\n"
|
||||
" -e <events_file> Read the events from <events_file> (in .scap format) instead of tapping into live.\n"
|
||||
" -r <rules_file> Rules file (defaults to value set in configuration file, or /etc/falco_rules.conf).\n"
|
||||
" -h, --help Print this page\n"
|
||||
" -c Configuration file (default " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ")\n"
|
||||
" -o Output type (options are 'stdout', 'syslog', default is 'stdout')\n"
|
||||
" -d, --daemon Run as a daemon\n"
|
||||
" -p, --pidfile <pid_file> When run as a daemon, write pid to specified file\n"
|
||||
" -e <events_file> Read the events from <events_file> (in .scap format) instead of tapping into live.\n"
|
||||
" -r <rules_file> Rules file (defaults to value set in configuration file, or /etc/falco_rules.conf).\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
@ -192,16 +194,20 @@ int falco_init(int argc, char **argv)
|
||||
sinsp_evt::param_fmt event_buffer_format;
|
||||
int long_index = 0;
|
||||
string lua_main_filename;
|
||||
string output_name = "stdout";
|
||||
string output_name = "syslog";
|
||||
string scap_filename;
|
||||
string conf_filename;
|
||||
string rules_filename;
|
||||
string lua_dir = FALCO_LUA_DIR;
|
||||
lua_State* ls = NULL;
|
||||
bool daemon = false;
|
||||
string pidfilename = "/var/run/falco.pid";
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{"daemon", no_argument, 0, 'd' },
|
||||
{"pidfile", required_argument, 0, 'd' },
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -214,7 +220,7 @@ int falco_init(int argc, char **argv)
|
||||
// Parse the args
|
||||
//
|
||||
while((op = getopt_long(argc, argv,
|
||||
"c:ho:e:r:",
|
||||
"c:ho:e:r:dp:",
|
||||
long_options, &long_index)) != -1)
|
||||
{
|
||||
switch(op)
|
||||
@ -239,6 +245,12 @@ int falco_init(int argc, char **argv)
|
||||
case 'r':
|
||||
rules_filename = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
daemon = true;
|
||||
break;
|
||||
case 'p':
|
||||
pidfilename = optarg;
|
||||
break;
|
||||
case '?':
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
@ -248,6 +260,18 @@ int falco_init(int argc, char **argv)
|
||||
|
||||
}
|
||||
|
||||
// Some combinations of arguments are not allowed.
|
||||
if (daemon && pidfilename == "") {
|
||||
falco_logger::log(LOG_ERR, "If -d is provided, a pid file must also be provided. Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (daemon && output_name == "stdout") {
|
||||
falco_logger::log(LOG_ERR, "If -d is provided, can not output to stdout. Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ifstream* conf_stream;
|
||||
if (conf_filename.size())
|
||||
@ -255,7 +279,7 @@ int falco_init(int argc, char **argv)
|
||||
conf_stream = new ifstream(conf_filename);
|
||||
if (!conf_stream->good())
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Could not find configuration file at " + conf_filename + ". Exiting \n");
|
||||
falco_logger::log(LOG_ERR, "Could not find configuration file at " + conf_filename + ". Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
@ -308,7 +332,7 @@ int falco_init(int argc, char **argv)
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Could not find Falco Lua libraries (tried " +
|
||||
string(FALCO_LUA_DIR FALCO_LUA_MAIN) + ", " +
|
||||
lua_main_filename + "). Exiting \n");
|
||||
lua_main_filename + "). Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
@ -365,11 +389,64 @@ int falco_init(int argc, char **argv)
|
||||
{
|
||||
if(system("modprobe " PROBE_NAME " > /dev/null 2> /dev/null"))
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Unable to load the driver. Exiting\n");
|
||||
falco_logger::log(LOG_ERR, "Unable to load the driver. Exiting.\n");
|
||||
}
|
||||
inspector->open();
|
||||
}
|
||||
}
|
||||
|
||||
// If daemonizing, do it here so any init errors will
|
||||
// be returned in the foreground process.
|
||||
if (daemon) {
|
||||
pid_t pid, sid;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
// error
|
||||
falco_logger::log(LOG_ERR, "Could not fork. Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
} else if (pid > 0) {
|
||||
// parent. Write child pid to pidfile and exit
|
||||
std::ofstream pidfile;
|
||||
pidfile.open(pidfilename);
|
||||
|
||||
if (!pidfile.good())
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Could not write pid to pid file " + pidfilename + ". Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
pidfile << pid;
|
||||
pidfile.close();
|
||||
goto exit;
|
||||
}
|
||||
// if here, child.
|
||||
|
||||
// Become own process group.
|
||||
sid = setsid();
|
||||
if (sid < 0) {
|
||||
falco_logger::log(LOG_ERR, "Could not set session id. Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Set umask so no files are world anything or group writable.
|
||||
umask(027);
|
||||
|
||||
// Change working directory to '/'
|
||||
if ((chdir("/")) < 0) {
|
||||
falco_logger::log(LOG_ERR, "Could not change working directory to '/'. Exiting.\n");
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Close stdin, stdout, stderr.
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
}
|
||||
|
||||
do_inspect(inspector,
|
||||
rules,
|
||||
ls);
|
||||
@ -378,7 +455,7 @@ int falco_init(int argc, char **argv)
|
||||
}
|
||||
catch(sinsp_exception& e)
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Runtime error: " + string(e.what()) + ". Exiting\n");
|
||||
falco_logger::log(LOG_ERR, "Runtime error: " + string(e.what()) + ". Exiting.\n");
|
||||
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ int falco_logger::syslog(lua_State *ls) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool falco_logger::log_stderr;
|
||||
bool falco_logger::log_syslog;
|
||||
bool falco_logger::log_stderr = true;
|
||||
bool falco_logger::log_syslog = true;
|
||||
|
||||
void falco_logger::log(int priority, const string msg) {
|
||||
if (falco_logger::log_syslog) {
|
||||
|
Loading…
Reference in New Issue
Block a user