From 4bfbf8e7f8042ad59eddac2c1ced453d5758c542 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 20 Aug 2019 10:57:26 +0000 Subject: [PATCH 1/4] feat: flag to disable sources (syscall, k8s_audit) Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- userspace/falco/falco.cpp | 132 +++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 53 deletions(-) diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index 76a4fc91da9..310b41270fe 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -82,25 +82,27 @@ static void usage() " -h, --help Print this page\n" " -c Configuration file (default " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ")\n" " -A Monitor all events, including those with EF_DROP_FALCO flag.\n" - " -b, --print-base64 Print data buffers in base64. This is useful for encoding\n" - " binary data that needs to be used over media designed to\n" - " --cri Path to CRI socket for container metadata\n" - " Use the specified socket to fetch data from a CRI-compatible runtime\n" - " -d, --daemon Run as a daemon\n" + " -b, --print-base64 Print data buffers in base64.\n" + " This is useful for encoding binary data that needs to be used over media designed to.\n" + " --cri Path to CRI socket for container metadata.\n" + " Use the specified socket to fetch data from a CRI-compatible runtime.\n" + " -d, --daemon Run as a daemon.\n" + " --disable-source \n" + " Disable a specific event source.\n" + " Available event sources are: syscall, k8s_audit.\n" + " It can be passed multiple times.\n" + " ....\n" " -D Disable any rules with names having the substring . Can be specified multiple times.\n" " Can not be specified with -t.\n" " -e Read the events from (in .scap format for sinsp events, or jsonl for\n" " k8s audit events) instead of tapping into live.\n" - " -k , --k8s-api=\n" - " Enable Kubernetes support by connecting to the API server\n" - " specified as argument. E.g. \"http://admin:password@127.0.0.1:8080\".\n" - " The API server can also be specified via the environment variable\n" - " FALCO_K8S_API.\n" - " -K | :[:], --k8s-api-cert= | :[:]\n" - " Use the provided files names to authenticate user and (optionally) verify the K8S API\n" - " server identity.\n" - " Each entry must specify full (absolute, or relative to the current directory) path\n" - " to the respective file.\n" + " -k , --k8s-api \n" + " Enable Kubernetes support by connecting to the API server specified as argument.\n" + " E.g. \"http://admin:password@127.0.0.1:8080\".\n" + " The API server can also be specified via the environment variable FALCO_K8S_API.\n" + " -K | :[:], --k8s-api-cert | :[:]\n" + " Use the provided files names to authenticate user and (optionally) verify the K8S API server identity.\n" + " Each entry must specify full (absolute, or relative to the current directory) path to the respective file.\n" " Private key password is optional (needed only if key is password protected).\n" " CA certificate is optional. For all files, only PEM file format is supported. \n" " Specifying CA certificate only is obsoleted - when single entry is provided \n" @@ -111,17 +113,16 @@ static void usage() " -l Show the name and description of the rule with name and exit.\n" " --list [] List all defined fields. If is provided, only list those fields for\n" " the source . Current values for are \"syscall\", \"k8s_audit\"\n" - " -m , --mesos-api=\n" + " -m , --mesos-api \n" " Enable Mesos support by connecting to the API server\n" " specified as argument. E.g. \"http://admin:password@127.0.0.1:5050\".\n" " Marathon url is optional and defaults to Mesos address, port 8080.\n" - " The API servers can also be specified via the environment variable\n" - " FALCO_MESOS_API.\n" + " The API servers can also be specified via the environment variable FALCO_MESOS_API.\n" " -M Stop collecting after reached.\n" " -N When used with --list, only print field names.\n" " -o, --option = Set the value of option to . Overrides values in configuration file.\n" " can be a two-part .\n" - " -p , --print=\n" + " -p , --print \n" " Add additional information to each falco notification's output.\n" " With -pc or -pcontainer will use a container-friendly format.\n" " With -pk or -pkubernetes will use a kubernetes-friendly format.\n" @@ -130,32 +131,31 @@ static void usage() " of %%container.info in rule output fields\n" " See the examples section below for more info.\n" " -P, --pidfile When run as a daemon, write pid to specified file\n" - " -r Rules file/directory (defaults to value set in configuration file,\n" - " or /etc/falco_rules.yaml). Can be specified multiple times to read\n" - " from multiple files/directories.\n" + " -r Rules file/directory (defaults to value set in configuration file,\n" + " or /etc/falco_rules.yaml). Can be specified multiple times to read\n" + " from multiple files/directories.\n" " -s If specified, write statistics related to falco's reading/processing of events\n" " to this file. (Only useful in live mode).\n" " --stats_interval When using -s , write statistics every ms.\n" " (This uses signals, so don't recommend intervals below 200 ms)\n" " defaults to 5000 (5 seconds)\n" - " -S , --snaplen=\n" - " Capture the first bytes of each I/O buffer.\n" - " By default, the first 80 bytes are captured. Use this\n" - " option with caution, it can generate huge trace files.\n" - " --support Print support information including version, rules files used, etc.\n" - " and exit.\n" + " -S , --snaplen \n" + " Capture the first bytes of each I/O buffer.\n" + " By default, the first 80 bytes are captured. Use this\n" + " option with caution, it can generate huge trace files.\n" + " --support Print support information including version, rules files used, etc. and exit.\n" " -T Disable any rules with a tag=. Can be specified multiple times.\n" " Can not be specified with -t.\n" " -t Only run those rules with a tag=. Can be specified multiple times.\n" " Can not be specified with -T/-D.\n" - " -U,--unbuffered Turn off output buffering to configured outputs. This causes every\n" - " single line emitted by falco to be flushed, which generates higher CPU\n" - " usage but is useful when piping those outputs into another process\n" - " or into a script.\n" - " -V,--validate Read the contents of the specified rules(s) file and exit\n" + " -U,--unbuffered Turn off output buffering to configured outputs.\n" + " This causes every single line emitted by falco to be flushed,\n" + " which generates higher CPU usage but is useful when piping those outputs\n" + " into another process or into a script.\n" + " -V, --validate Read the contents of the specified rules(s) file and exit.\n" " Can be specified multiple times to validate multiple files.\n" " -v Verbose output.\n" - " --version Print version number.\n" + " --version Print version number.\n" "\n" ); } @@ -428,6 +428,7 @@ int falco_init(int argc, char **argv) string list_flds_source = ""; bool print_support = false; string cri_socket_path; + set disable_sources; // Used for writing trace files int duration_seconds = 0; @@ -447,25 +448,26 @@ int falco_init(int argc, char **argv) static struct option long_options[] = { - {"help", no_argument, 0, 'h' }, - {"print-base64", no_argument, 0, 'b'}, - {"daemon", no_argument, 0, 'd' }, - {"k8s-api", required_argument, 0, 'k'}, - {"k8s-api-cert", required_argument, 0, 'K' }, - {"list", optional_argument, 0}, - {"mesos-api", required_argument, 0, 'm'}, - {"option", required_argument, 0, 'o'}, - {"print", required_argument, 0, 'p' }, - {"pidfile", required_argument, 0, 'P' }, - {"snaplen", required_argument, 0, 'S' }, - {"stats_interval", required_argument, 0}, - {"support", no_argument, 0}, - {"unbuffered", no_argument, 0, 'U' }, - {"version", no_argument, 0, 0 }, - {"validate", required_argument, 0, 'V' }, - {"writefile", required_argument, 0, 'w' }, - {"ignored-events", no_argument, 0, 'i'}, {"cri", required_argument, 0}, + {"daemon", no_argument, 0, 'd'}, + {"disable-source", required_argument, 0}, + {"help", no_argument, 0, 'h'}, + {"ignored-events", no_argument, 0, 'i'}, + {"k8s-api-cert", required_argument, 0, 'K'}, + {"k8s-api", required_argument, 0, 'k'}, + {"list", optional_argument, 0}, + {"mesos-api", required_argument, 0, 'm'}, + {"option", required_argument, 0, 'o'}, + {"pidfile", required_argument, 0, 'P'}, + {"print-base64", no_argument, 0, 'b'}, + {"print", required_argument, 0, 'p'}, + {"snaplen", required_argument, 0, 'S'}, + {"stats_interval", required_argument, 0}, + {"support", no_argument, 0}, + {"unbuffered", no_argument, 0, 'U'}, + {"validate", required_argument, 0, 'V'}, + {"version", no_argument, 0, 0}, + {"writefile", required_argument, 0, 'w'}, {0, 0, 0, 0} }; @@ -609,7 +611,10 @@ int falco_init(int argc, char **argv) } else if (string(long_options[long_index].name) == "cri") { - cri_socket_path = optarg; + if(optarg != NULL) + { + cri_socket_path = optarg; + } } else if (string(long_options[long_index].name) == "list") { @@ -627,6 +632,13 @@ int falco_init(int argc, char **argv) { print_support = true; } + else if (string(long_options[long_index].name) == "disable-source") + { + if(optarg != NULL) + { + disable_sources.insert(optarg); + } + } break; default: @@ -669,6 +681,20 @@ int falco_init(int argc, char **argv) return EXIT_SUCCESS; } + if(disable_sources.size() > 0) + { + auto it = disable_sources.begin(); + while(it != disable_sources.end()) + { + if(*it != "syscall" && *it != "k8s_audit") + { + it = disable_sources.erase(it); + continue; + } + ++it; + } + } + outputs = new falco_outputs(engine); outputs->set_inspector(inspector); From 93882f35665978277d34ff90634ee8eb55e1e226 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 21 Aug 2019 09:47:54 +0000 Subject: [PATCH 2/4] feat(userspace): can not disable both the event sources Co-authored-by: Lorenzo Fontana Signed-off-by: Leonardo Di Donato --- userspace/falco/falco.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index 310b41270fe..1252e6b0944 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -26,6 +26,7 @@ limitations under the License. #include #include #include +#include #include #include #include @@ -47,6 +48,8 @@ limitations under the License. #include "statsfilewriter.h" #include "webserver.h" +typedef function open_t; + bool g_terminate = false; bool g_reopen_outputs = false; bool g_restart = false; @@ -91,7 +94,7 @@ static void usage() " Disable a specific event source.\n" " Available event sources are: syscall, k8s_audit.\n" " It can be passed multiple times.\n" - " ....\n" + " Can not disable both the event sources.\n" " -D Disable any rules with names having the substring . Can be specified multiple times.\n" " Can not be specified with -t.\n" " -e Read the events from (in .scap format for sinsp events, or jsonl for\n" @@ -128,17 +131,15 @@ static void usage() " With -pk or -pkubernetes will use a kubernetes-friendly format.\n" " With -pm or -pmesos will use a mesos-friendly format.\n" " Additionally, specifying -pc/-pk/-pm will change the interpretation\n" - " of %%container.info in rule output fields\n" - " See the examples section below for more info.\n" + " of %%container.info in rule output fields.\n" " -P, --pidfile When run as a daemon, write pid to specified file\n" - " -r Rules file/directory (defaults to value set in configuration file,\n" - " or /etc/falco_rules.yaml). Can be specified multiple times to read\n" - " from multiple files/directories.\n" + " -r Rules file/directory (defaults to value set in configuration file, or /etc/falco_rules.yaml).\n" + " Can be specified multiple times to read from multiple files/directories.\n" " -s If specified, write statistics related to falco's reading/processing of events\n" " to this file. (Only useful in live mode).\n" " --stats_interval When using -s , write statistics every ms.\n" - " (This uses signals, so don't recommend intervals below 200 ms)\n" - " defaults to 5000 (5 seconds)\n" + " This uses signals, so don't recommend intervals below 200 ms.\n" + " Defaults to 5000 (5 seconds).\n" " -S , --snaplen \n" " Capture the first bytes of each I/O buffer.\n" " By default, the first 80 bytes are captured. Use this\n" @@ -429,6 +430,8 @@ int falco_init(int argc, char **argv) bool print_support = false; string cri_socket_path; set disable_sources; + bool disable_syscall = false; + bool disable_k8s_audit = false; // Used for writing trace files int duration_seconds = 0; @@ -693,6 +696,11 @@ int falco_init(int argc, char **argv) } ++it; } + disable_syscall = disable_sources.count("syscall") > 0; + disable_k8s_audit = disable_sources.count("k8s_audit") > 0; + if (disable_syscall && disable_k8s_audit) { + throw std::invalid_argument("The event source \"syscall\" and \"k8s_audit\" can not be disabled together"); + } } outputs = new falco_outputs(engine); @@ -998,7 +1006,7 @@ int falco_init(int argc, char **argv) g_daemonized = true; } - if (trace_filename.size()) + if(trace_filename.size()) { // Try to open the trace file as a sysdig // capture file first. @@ -1127,7 +1135,7 @@ int falco_init(int argc, char **argv) delete mesos_api; mesos_api = 0; - if(trace_filename.empty() && config.m_webserver_enabled) + if(trace_filename.empty() && config.m_webserver_enabled && !disable_k8s_audit) { std::string ssl_option = (config.m_webserver_ssl_enabled ? " (SSL)" : ""); falco_logger::log(LOG_INFO, "Starting internal webserver, listening on port " + to_string(config.m_webserver_listen_port) + ssl_option + "\n"); From 85c29f046864712f13d49dd446ce8b4325783100 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 21 Aug 2019 09:50:12 +0000 Subject: [PATCH 3/4] feat(userspace): open the event source/s depending on the flags Signed-off-by: Leonardo Di Donato Co-authored-by: Lorenzo Fonanta --- userspace/falco/falco.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index 1252e6b0944..0f136499205 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -1050,9 +1050,28 @@ int falco_init(int argc, char **argv) } else { + open_t open_cb = [](sinsp* inspector) { + inspector->open(); + }; + open_t open_nodriver_cb = [](sinsp* inspector) { + inspector->open_nodriver(); + }; + open_t open_f; + + // Default mode: both event sources enabled + if (!disable_syscall && !disable_k8s_audit) { + open_f = open_cb; + } + if (disable_syscall) { + open_f = open_nodriver_cb; + } + if (disable_k8s_audit) { + open_f = open_cb; + } + try { - inspector->open(200); + open_f(inspector); } catch(sinsp_exception &e) { @@ -1060,7 +1079,7 @@ int falco_init(int argc, char **argv) { falco_logger::log(LOG_ERR, "Unable to load the driver. Exiting.\n"); } - inspector->open(); + open_f(inspector); } } From 75bc460917fac39405c997e6b6cd078f26a8d78e Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Wed, 21 Aug 2019 13:46:19 +0000 Subject: [PATCH 4/4] docs: office hours zoom link Signed-off-by: Leonardo Di Donato Co-authored-by: Lorenzo Fontana --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index eff97df3c18..0f8a1f8255d 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,7 @@ Office hours Falco has weekly office hour style meetings where we plan our work on the project. You can get a Google calendar invite by joining the mailing list. It will automatically be sent. -Wednesdays at 8am Pacific on [Zoom]( - +Wednesdays at 8am Pacific on [Zoom](sysdig.zoom.us/j/213235330). License Terms ---