From cfc89127e75c820ebcaa6c8b7547cb0e64411842 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 6 May 2016 14:04:44 -0700 Subject: [PATCH 1/4] Add init.d files to debian/redhat packages. Add init.d scripts to debian/redhat packages as well as postinstall/remove scripts to enable the falco service on install and disable it on uninstall. I still need to add support for daemonization to falco, and change the default output options to match the expected use of being daemonized. --- CMakeCPackOptions.cmake | 10 +++ CMakeLists.txt | 7 +- scripts/CMakeLists.txt | 5 ++ scripts/debian/falco | 156 ++++++++++++++++++++++++++++++++++++++ scripts/debian/postinst | 16 ++++ scripts/debian/postrm | 8 ++ scripts/debian/prerm | 13 ++++ scripts/rpm/falco | 105 +++++++++++++++++++++++++ scripts/rpm/postinstall | 1 + scripts/rpm/postuninstall | 3 + scripts/rpm/preuninstall | 4 + 11 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 scripts/CMakeLists.txt create mode 100755 scripts/debian/falco create mode 100755 scripts/debian/postinst create mode 100755 scripts/debian/postrm create mode 100755 scripts/debian/prerm create mode 100755 scripts/rpm/falco create mode 100755 scripts/rpm/postinstall create mode 100755 scripts/rpm/postuninstall create mode 100755 scripts/rpm/preuninstall diff --git a/CMakeCPackOptions.cmake b/CMakeCPackOptions.cmake index 91854961..5d50761d 100644 --- a/CMakeCPackOptions.cmake +++ b/CMakeCPackOptions.cmake @@ -1,3 +1,13 @@ +if(CPACK_GENERATOR MATCHES "DEB") + list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d/") + list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/debian/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/init.d") +endif() + +if(CPACK_GENERATOR MATCHES "RPM") + list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d/") + list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/rpm/falco _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/etc/rc.d/init.d") +endif() + if(CPACK_GENERATOR MATCHES "TGZ") set(CPACK_SET_DESTDIR "ON") set(CPACK_STRIP_FILES "OFF") diff --git a/CMakeLists.txt b/CMakeLists.txt index fb86493f..49d19e23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,6 +181,7 @@ add_subdirectory(${SYSDIG_DIR}/userspace/libscap ${PROJECT_BINARY_DIR}/userspace add_subdirectory(${SYSDIG_DIR}/userspace/libsinsp ${PROJECT_BINARY_DIR}/userspace/libsinsp) add_subdirectory(rules) +add_subdirectory(scripts) add_subdirectory(userspace/falco) @@ -192,18 +193,22 @@ set(CPACK_PACKAGE_VERSION "${FALCO_VERSION}") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_SOURCE_DIR}/CMakeCPackOptions.cmake") set(CPACK_STRIP_FILES "ON") +set(CPACK_PACKAGE_RELOCATABLE "OFF") set(CPACK_GENERATOR DEB RPM TGZ) set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Sysdig ") set(CPACK_DEBIAN_PACKAGE_SECTION "utils") - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://www.sysdig.org") set(CPACK_DEBIAN_PACKAGE_DEPENDS "sysdig") +set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/scripts/debian/postinst;${PROJECT_SOURCE_DIR}/scripts/debian/prerm;${PROJECT_SOURCE_DIR}/scripts/debian/postrm") set(CPACK_RPM_PACKAGE_LICENSE "GPLv2") set(CPACK_RPM_PACKAGE_URL "http://www.sysdig.org") 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) include(CPack) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt new file mode 100644 index 00000000..f9084aee --- /dev/null +++ b/scripts/CMakeLists.txt @@ -0,0 +1,5 @@ +file(COPY ${PROJECT_SOURCE_DIR}/scripts/debian/falco + DESTINATION ${PROJECT_BINARY_DIR}/scripts/debian) + +file(COPY ${PROJECT_SOURCE_DIR}/scripts/rpm/falco + DESTINATION ${PROJECT_BINARY_DIR}/scripts/rpm) diff --git a/scripts/debian/falco b/scripts/debian/falco new file mode 100755 index 00000000..9604f2d3 --- /dev/null +++ b/scripts/debian/falco @@ -0,0 +1,156 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: falco +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Falco syscall activity monitoring agent +# Description: Falco is a system activity monitoring agent +# driven by system calls with support for containers. +### END INIT INFO + +# Author: Sysdig + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="Falco" +NAME=falco +DAEMON=/usr/bin/$NAME +PIDFILE=/var/run/$NAME.pid +DAEMON_ARGS="--daemon --falcopid=$PIDFILE" +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.2-14) to ensure that this file is present +# and status_of_proc is working. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ + $DAEMON_ARGS \ + || return 2 + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + #reload|force-reload) + # + # If do_reload() is not implemented then leave this commented out + # and leave 'force-reload' as an alias for 'restart'. + # + #log_daemon_msg "Reloading $DESC" "$NAME" + #do_reload + #log_end_msg $? + #;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/scripts/debian/postinst b/scripts/debian/postinst new file mode 100755 index 00000000..b90add76 --- /dev/null +++ b/scripts/debian/postinst @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +NAME=falco + +if [ -x "/etc/init.d/$NAME" ]; then + update-rc.d $NAME defaults >/dev/null +fi + +if [ -x "/etc/init.d/$NAME" ]; then + if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then + invoke-rc.d $NAME start || exit $? + else + /etc/init.d/$NAME start || exit $? + fi +fi diff --git a/scripts/debian/postrm b/scripts/debian/postrm new file mode 100755 index 00000000..18797f67 --- /dev/null +++ b/scripts/debian/postrm @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +NAME=falco + +if [ "$1" = "purge" ] ; then + update-rc.d $NAME remove >/dev/null +fi diff --git a/scripts/debian/prerm b/scripts/debian/prerm new file mode 100755 index 00000000..5270e189 --- /dev/null +++ b/scripts/debian/prerm @@ -0,0 +1,13 @@ +#!/bin/sh +set -e + +NAME=falco + +if [ -x "/etc/init.d/$NAME" ]; then + if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then + invoke-rc.d $NAME stop || exit $? + else + /etc/init.d/$NAME stop || exit $? + fi +fi + diff --git a/scripts/rpm/falco b/scripts/rpm/falco new file mode 100755 index 00000000..c0c17e84 --- /dev/null +++ b/scripts/rpm/falco @@ -0,0 +1,105 @@ +#!/bin/sh +# +# falco syscall monitoring agent +# +# chkconfig: 2345 55 45 +# description: Falco syscall monitoring agent +# + +### BEGIN INIT INFO +# Provides: +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: +# Default-Stop: +# Short-Description: +# Description: +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +exec="/usr/bin/falco" +prog="falco" +# config="" + +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +lockfile=/var/lock/subsys/$prog +pidfile="/var/run/falco.pid" + +start() { + [ -x $exec ] || exit 5 + # [ -f $config ] || exit 6 + echo -n $"Starting $prog: " + daemon $exec --daemon --falcopid=$pidfile + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p $pidfile + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +reload() { + restart +} + +force_reload() { + restart +} + +rh_status() { + status -p $pidfile $prog +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? diff --git a/scripts/rpm/postinstall b/scripts/rpm/postinstall new file mode 100755 index 00000000..56e0be45 --- /dev/null +++ b/scripts/rpm/postinstall @@ -0,0 +1 @@ +/sbin/chkconfig --add falco diff --git a/scripts/rpm/postuninstall b/scripts/rpm/postuninstall new file mode 100755 index 00000000..69502ec9 --- /dev/null +++ b/scripts/rpm/postuninstall @@ -0,0 +1,3 @@ +if [ "$1" -ge "1" ]; then + /sbin/service falco condrestart > /dev/null 2>&1 +fi diff --git a/scripts/rpm/preuninstall b/scripts/rpm/preuninstall new file mode 100755 index 00000000..10d3b98f --- /dev/null +++ b/scripts/rpm/preuninstall @@ -0,0 +1,4 @@ +if [ $1 = 0 ]; then + /sbin/service falco stop > /dev/null 2>&1 + /sbin/chkconfig --del falco +fi From a787dc84d50b709c34ee16bd0658ed72ccaf55ef Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 6 May 2016 17:25:54 -0700 Subject: [PATCH 2/4] 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. --- CMakeLists.txt | 3 +- falco.yaml | 6 +- scripts/debian/falco | 2 +- scripts/rpm/falco | 2 +- userspace/falco/configuration.cpp | 2 +- userspace/falco/falco.cpp | 99 +++++++++++++++++++++++++++---- userspace/falco/logger.cpp | 4 +- 7 files changed, 98 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49d19e23..22c3e5ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/falco.yaml b/falco.yaml index d82ed41e..b3b30b26 100644 --- a/falco.yaml +++ b/falco.yaml @@ -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 diff --git a/scripts/debian/falco b/scripts/debian/falco index 9604f2d3..0c55a02f 100755 --- a/scripts/debian/falco +++ b/scripts/debian/falco @@ -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 diff --git a/scripts/rpm/falco b/scripts/rpm/falco index c0c17e84..524e167c 100755 --- a/scripts/rpm/falco +++ b/scripts/rpm/falco @@ -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 diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index b1c5a6cb..74e5775e 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -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("rules_file", "/etc/falco_rules.conf"); + m_rules_filename = m_config->get_scalar("rules_file", "/etc/falco_rules.yaml"); m_json_output = m_config->get_scalar("json_output", false); output_config file_output; diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index 8b3cb59e..9dce811c 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -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 Read the events from (in .scap format) instead of tapping into live.\n" - " -r 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 When run as a daemon, write pid to specified file\n" + " -e Read the events from (in .scap format) instead of tapping into live.\n" + " -r 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; } diff --git a/userspace/falco/logger.cpp b/userspace/falco/logger.cpp index 9f104265..7c4bdc5b 100644 --- a/userspace/falco/logger.cpp +++ b/userspace/falco/logger.cpp @@ -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) { From 58d730c62ab8664b04a8e049f3cd61fb46af664e Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 9 May 2016 17:17:39 -0700 Subject: [PATCH 3/4] Don't start by default on debian. This makes the behavior consistent on debian and redhat. --- scripts/debian/postinst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/scripts/debian/postinst b/scripts/debian/postinst index b90add76..0084f213 100755 --- a/scripts/debian/postinst +++ b/scripts/debian/postinst @@ -7,10 +7,3 @@ if [ -x "/etc/init.d/$NAME" ]; then update-rc.d $NAME defaults >/dev/null fi -if [ -x "/etc/init.d/$NAME" ]; then - if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then - invoke-rc.d $NAME start || exit $? - else - /etc/init.d/$NAME start || exit $? - fi -fi From 6203c6be74a361627a82dc45fe720b536131c10e Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 9 May 2016 17:18:20 -0700 Subject: [PATCH 4/4] Change output options in file as well. Also change output options in falco config to reflect default behavior of being started via a service. --- falco.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/falco.yaml b/falco.yaml index b3b30b26..719e4598 100644 --- a/falco.yaml +++ b/falco.yaml @@ -1,14 +1,14 @@ rules_file: /etc/falco_rules.yaml json_output: false -log_stderr: true +log_stderr: false log_syslog: true syslog_output: enabled: true file_output: - enabled: true + enabled: false filename: ./events.txt stdout_output: