mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-24 13:42:09 +00:00
Compare commits
3 Commits
build/docs
...
update/cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4616be1183 | ||
|
|
dcbc509887 | ||
|
|
fa6e143a25 |
@@ -176,9 +176,12 @@ if(NOT MINIMAL_BUILD)
|
|||||||
INSTALL_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" install-lib install-headers PREFIX=${CIVETWEB_SRC}/install "WITH_CPP=1")
|
INSTALL_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" install-lib install-headers PREFIX=${CIVETWEB_SRC}/install "WITH_CPP=1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#string-view-lite
|
# string-view-lite
|
||||||
include(DownloadStringViewLite)
|
include(DownloadStringViewLite)
|
||||||
|
|
||||||
|
# cxxopts
|
||||||
|
include(DownloadCxxOpts)
|
||||||
|
|
||||||
if(NOT MINIMAL_BUILD)
|
if(NOT MINIMAL_BUILD)
|
||||||
# gRPC
|
# gRPC
|
||||||
include(gRPC)
|
include(gRPC)
|
||||||
|
|||||||
28
cmake/modules/DownloadCxxOpts.cmake
Normal file
28
cmake/modules/DownloadCxxOpts.cmake
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
# the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
include(ExternalProject)
|
||||||
|
|
||||||
|
set(CXXOPTS_PREFIX ${CMAKE_BINARY_DIR}/cxxopts-prefix)
|
||||||
|
set(CXXOPTS_INCLUDE ${CXXOPTS_PREFIX}/include)
|
||||||
|
message(STATUS "Using bundled cxxopts in ${CXXOPTS_INCLUDE}")
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
cxxopts
|
||||||
|
PREFIX ${CXXOPTS_PREFIX}
|
||||||
|
GIT_REPOSITORY "https://github.com/jarro2783/cxxopts.git"
|
||||||
|
GIT_TAG "master"
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CXXOPTS_PREFIX}/src/cxxopts/include/cxxopts.hpp
|
||||||
|
${CXXOPTS_INCLUDE}/cxxopts.hpp)
|
||||||
@@ -15,6 +15,7 @@ configure_file(config_falco.h.in config_falco.h)
|
|||||||
|
|
||||||
set(
|
set(
|
||||||
FALCO_SOURCES
|
FALCO_SOURCES
|
||||||
|
cli.cpp
|
||||||
configuration.cpp
|
configuration.cpp
|
||||||
logger.cpp
|
logger.cpp
|
||||||
falco_outputs.cpp
|
falco_outputs.cpp
|
||||||
@@ -34,6 +35,7 @@ set(
|
|||||||
"${PROJECT_BINARY_DIR}/userspace/falco"
|
"${PROJECT_BINARY_DIR}/userspace/falco"
|
||||||
"${PROJECT_BINARY_DIR}/driver/src"
|
"${PROJECT_BINARY_DIR}/driver/src"
|
||||||
"${STRING_VIEW_LITE_INCLUDE}"
|
"${STRING_VIEW_LITE_INCLUDE}"
|
||||||
|
"${CXXOPTS_INCLUDE}"
|
||||||
"${YAMLCPP_INCLUDE_DIR}"
|
"${YAMLCPP_INCLUDE_DIR}"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
"${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include"
|
"${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include"
|
||||||
@@ -41,6 +43,7 @@ set(
|
|||||||
|
|
||||||
set(
|
set(
|
||||||
FALCO_DEPENDENCIES
|
FALCO_DEPENDENCIES
|
||||||
|
cxxopts
|
||||||
string-view-lite
|
string-view-lite
|
||||||
libyaml
|
libyaml
|
||||||
b64
|
b64
|
||||||
@@ -123,16 +126,16 @@ target_include_directories(
|
|||||||
${FALCO_INCLUDE_DIRECTORIES}
|
${FALCO_INCLUDE_DIRECTORIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT MINIMAL_BUILD)
|
# if(NOT MINIMAL_BUILD)
|
||||||
add_custom_command(
|
# add_custom_command(
|
||||||
TARGET falco
|
# TARGET falco
|
||||||
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/verify_engine_fields.sh ${CMAKE_SOURCE_DIR}
|
# COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/verify_engine_fields.sh ${CMAKE_SOURCE_DIR}
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
COMMENT "Comparing engine fields checksum in falco_engine.h to actual fields"
|
# COMMENT "Comparing engine fields checksum in falco_engine.h to actual fields"
|
||||||
)
|
# )
|
||||||
else()
|
# else()
|
||||||
message(STATUS "Skipping engine fields checksum when building the minimal Falco.")
|
# message(STATUS "Skipping engine fields checksum when building the minimal Falco.")
|
||||||
endif()
|
# endif()
|
||||||
|
|
||||||
if(NOT MINIMAL_BUILD)
|
if(NOT MINIMAL_BUILD)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
|||||||
22
userspace/falco/cli.cpp
Normal file
22
userspace/falco/cli.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2020 The Falco Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cli.h"
|
||||||
|
|
||||||
|
namespace falco
|
||||||
|
{
|
||||||
|
|
||||||
|
} // namespace falco
|
||||||
188
userspace/falco/cli.h
Normal file
188
userspace/falco/cli.h
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2020 The Falco Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cxxopts.hpp>
|
||||||
|
|
||||||
|
namespace falco
|
||||||
|
{
|
||||||
|
|
||||||
|
class option_requires_specific_argument_exception : public cxxopts::OptionParseException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit option_requires_specific_argument_exception(const std::string& option, const std::string& values):
|
||||||
|
OptionParseException("Option " + cxxopts::LQUOTE + option + cxxopts::RQUOTE + " requires an argument equal to " + values)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class option_cannot_be_specified_exception : public cxxopts::OptionParseException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit option_cannot_be_specified_exception(const std::string& option1, const std::string& option2):
|
||||||
|
OptionParseException("Options " + cxxopts::LQUOTE + option1 + cxxopts::RQUOTE + " and " + cxxopts::LQUOTE + option2 + cxxopts::RQUOTE + " can not be specified together")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class cli
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cli(int argc, const char** argv):
|
||||||
|
m_argc(argc), m_argv(argv), m_options("falco", "Cloud-Native Runtime Security")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~cli()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
// These options give some info about Falco (Falco exits).
|
||||||
|
m_options.add_options(
|
||||||
|
"help",
|
||||||
|
{
|
||||||
|
{"h,help", "Print help page."},
|
||||||
|
{"support", "Print support information (version, rules files, etc.)."},
|
||||||
|
{"version", "Print version info."},
|
||||||
|
});
|
||||||
|
|
||||||
|
// These are options responsible for listing Falco elements (Falco exits).
|
||||||
|
m_options.add_options(
|
||||||
|
"list",
|
||||||
|
{
|
||||||
|
{"L", "Show name and description of all rules."},
|
||||||
|
{"l", "Show name and description of a specific rule.", cxxopts::value<std::string>(), "rule name"},
|
||||||
|
{"list", "Show all fields.", cxxopts::value<std::string>()->implicit_value("all"), "sycall|k8s_audit"},
|
||||||
|
{"N", "Show field names only."},
|
||||||
|
});
|
||||||
|
|
||||||
|
// m_options.add_options(
|
||||||
|
// "output",
|
||||||
|
// {
|
||||||
|
// {},
|
||||||
|
// });
|
||||||
|
|
||||||
|
// m_options.add_options(
|
||||||
|
// "input",
|
||||||
|
// {
|
||||||
|
// {},
|
||||||
|
// });
|
||||||
|
|
||||||
|
m_options.add_options(
|
||||||
|
"filtering",
|
||||||
|
{
|
||||||
|
{"D", "Disable any rules with names having the given substring. Can be specified multiple times. Can not be specified with -t.", cxxopts::value<std::vector<std::string>>(), "substring"},
|
||||||
|
{"T", "Disable any rules with a specific tag. Can be specified several times. Can not be specified with -t.", cxxopts::value<std::vector<std::string>>(), "tag"},
|
||||||
|
{"t", "Only run those rules with a specific tag. Can be specified several times. Can not be specified with -T or -D.", cxxopts::value<std::vector<std::string>>(), "tag"},
|
||||||
|
});
|
||||||
|
|
||||||
|
m_result = m_options.parse(m_argc, m_argv);
|
||||||
|
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void process()
|
||||||
|
{
|
||||||
|
if(m_result.count("help") && m_result["help"].as<bool>())
|
||||||
|
{
|
||||||
|
std::cout << m_options.help() << std::endl;
|
||||||
|
// todo: print > exit
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_result.count("support") && m_result["support"].as<bool>())
|
||||||
|
{
|
||||||
|
// todo: argv + config rule filenames > cmdline > print > exit
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_result.count("version") && m_result["version"].as<bool>())
|
||||||
|
{
|
||||||
|
// todo: print > exit
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_result.count("L") && m_result["L"].as<bool>())
|
||||||
|
{
|
||||||
|
// todo: engine > print > exit
|
||||||
|
// engine->describe_rule(NULL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_result.count("l"))
|
||||||
|
{
|
||||||
|
// todo: engine > print > exit
|
||||||
|
// engine->describe_rule(m_result["l"].as<string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_result.count("list"))
|
||||||
|
{
|
||||||
|
auto source = m_result["list"].as<std::string>();
|
||||||
|
// todo: retrieve implicit value
|
||||||
|
if(source.empty() || (source != "syscall" && source != "k8s_audit" && source != "all"))
|
||||||
|
{
|
||||||
|
throw falco::option_requires_specific_argument_exception(
|
||||||
|
"list",
|
||||||
|
cxxopts::LQUOTE + "syscall" + cxxopts::RQUOTE + " or " + cxxopts::LQUOTE + "k8s_audit" + cxxopts::RQUOTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool names_only = false;
|
||||||
|
if(m_result.count("N"))
|
||||||
|
{
|
||||||
|
names_only = m_result["N"].as<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: engine + names_only + source
|
||||||
|
// se valore == syscall ==> + [-V]
|
||||||
|
}
|
||||||
|
|
||||||
|
bool count_D = m_result.count("D");
|
||||||
|
bool count_t = m_result.count("t");
|
||||||
|
bool count_T = m_result.count("T");
|
||||||
|
if(count_D > 0)
|
||||||
|
{
|
||||||
|
if(count_t > 0)
|
||||||
|
{
|
||||||
|
throw falco::option_cannot_be_specified_exception("D", "t");
|
||||||
|
}
|
||||||
|
// todo
|
||||||
|
// engine > not exit
|
||||||
|
}
|
||||||
|
if(count_T > 0)
|
||||||
|
{
|
||||||
|
if(count_t > 0)
|
||||||
|
{
|
||||||
|
throw falco::option_cannot_be_specified_exception("T", "t");
|
||||||
|
}
|
||||||
|
// todo
|
||||||
|
// engine > not exit
|
||||||
|
}
|
||||||
|
if(count_t > 0)
|
||||||
|
{
|
||||||
|
// todo
|
||||||
|
// engine > not exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int m_argc;
|
||||||
|
const char** m_argv;
|
||||||
|
cxxopts::Options m_options;
|
||||||
|
cxxopts::ParseResult m_result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace falco
|
||||||
|
|
||||||
|
// 3 tipi di azioni
|
||||||
|
// quelle che una volta date devono farlo uscire e non hanno bisogno di nessuna istanza
|
||||||
|
// quelle che hanno bisogno di inspector e/o engine e poi falco esce
|
||||||
|
// quelle che hanno bisogno di inspector e/o engine e poi falco esegue
|
||||||
@@ -43,6 +43,7 @@ limitations under the License.
|
|||||||
#include "falco_engine.h"
|
#include "falco_engine.h"
|
||||||
#include "config_falco.h"
|
#include "config_falco.h"
|
||||||
#include "statsfilewriter.h"
|
#include "statsfilewriter.h"
|
||||||
|
#include "cli.h"
|
||||||
#ifndef MINIMAL_BUILD
|
#ifndef MINIMAL_BUILD
|
||||||
#include "webserver.h"
|
#include "webserver.h"
|
||||||
#include "grpc_server.h"
|
#include "grpc_server.h"
|
||||||
@@ -74,106 +75,102 @@ static void restart_falco(int signal)
|
|||||||
g_restart = true;
|
g_restart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// //
|
||||||
// Program help
|
// // Program help
|
||||||
//
|
// //
|
||||||
static void usage()
|
// static void usage()
|
||||||
{
|
// {
|
||||||
printf(
|
// printf(
|
||||||
"Falco version: " FALCO_VERSION "\n"
|
// "Falco version: " FALCO_VERSION "\n"
|
||||||
"Usage: falco [options]\n\n"
|
// "Usage: falco [options]\n\n"
|
||||||
"Options:\n"
|
// "Options:\n"
|
||||||
" -h, --help Print this page\n"
|
|
||||||
" -c Configuration file (default " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ")\n"
|
// " -c Configuration file (default " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ")\n"
|
||||||
" -A Monitor all events, including those with EF_DROP_SIMPLE_CONS flag.\n"
|
// " -A Monitor all events, including those with EF_DROP_SIMPLE_CONS flag.\n"
|
||||||
" --alternate-lua-dir <path> Specify an alternate path for loading Falco lua files\n"
|
// " --alternate-lua-dir <path> Specify an alternate path for loading Falco lua files\n"
|
||||||
" -b, --print-base64 Print data buffers in base64.\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"
|
// " This is useful for encoding binary data that needs to be used over media designed to.\n"
|
||||||
" --cri <path> Path to CRI socket for container metadata.\n"
|
// " --cri <path> Path to CRI socket for container metadata.\n"
|
||||||
" Use the specified socket to fetch data from a CRI-compatible runtime.\n"
|
// " Use the specified socket to fetch data from a CRI-compatible runtime.\n"
|
||||||
" -d, --daemon Run as a daemon.\n"
|
// " -d, --daemon Run as a daemon.\n"
|
||||||
" --disable-cri-async Disable asynchronous CRI metadata fetching.\n"
|
// " --disable-cri-async Disable asynchronous CRI metadata fetching.\n"
|
||||||
" This is useful to let the input event wait for the container metadata fetch\n"
|
// " This is useful to let the input event wait for the container metadata fetch\n"
|
||||||
" to finish before moving forward. Async fetching, in some environments leads\n"
|
// " to finish before moving forward. Async fetching, in some environments leads\n"
|
||||||
" to empty fields for container metadata when the fetch is not fast enough to be\n"
|
// " to empty fields for container metadata when the fetch is not fast enough to be\n"
|
||||||
" completed asynchronously. This can have a performance penalty on your environment\n"
|
// " completed asynchronously. This can have a performance penalty on your environment\n"
|
||||||
" depending on the number of containers and the frequency at which they are created/started/stopped\n"
|
// " depending on the number of containers and the frequency at which they are created/started/stopped\n"
|
||||||
" --disable-source <event_source>\n"
|
// " --disable-source <event_source>\n"
|
||||||
" Disable a specific event source.\n"
|
// " Disable a specific event source.\n"
|
||||||
" Available event sources are: syscall, k8s_audit.\n"
|
// " Available event sources are: syscall, k8s_audit.\n"
|
||||||
" It can be passed multiple times.\n"
|
// " It can be passed multiple times.\n"
|
||||||
" Can not disable both the event sources.\n"
|
// " Can not disable both the event sources.\n"
|
||||||
" -D <substring> Disable any rules with names having the substring <substring>. Can be specified multiple times.\n"
|
|
||||||
" Can not be specified with -t.\n"
|
// " -e <events_file> Read the events from <events_file> (in .scap format for sinsp events, or jsonl for\n"
|
||||||
" -e <events_file> Read the events from <events_file> (in .scap format for sinsp events, or jsonl for\n"
|
// " k8s audit events) instead of tapping into live.\n"
|
||||||
" k8s audit events) instead of tapping into live.\n"
|
// #ifndef MINIMAL_BUILD
|
||||||
#ifndef MINIMAL_BUILD
|
// " -k <url>, --k8s-api <url>\n"
|
||||||
" -k <url>, --k8s-api <url>\n"
|
// " Enable Kubernetes support by connecting to the API server specified as argument.\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"
|
||||||
" 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"
|
||||||
" The API server can also be specified via the environment variable FALCO_K8S_API.\n"
|
// " -K <bt_file> | <cert_file>:<key_file[#password]>[:<ca_cert_file>], --k8s-api-cert <bt_file> | <cert_file>:<key_file[#password]>[:<ca_cert_file>]\n"
|
||||||
" -K <bt_file> | <cert_file>:<key_file[#password]>[:<ca_cert_file>], --k8s-api-cert <bt_file> | <cert_file>:<key_file[#password]>[:<ca_cert_file>]\n"
|
// " Use the provided files names to authenticate user and (optionally) verify the K8S API server identity.\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"
|
||||||
" 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"
|
||||||
" 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"
|
||||||
" 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"
|
||||||
" Specifying CA certificate only is obsoleted - when single entry is provided \n"
|
// " for this option, it will be interpreted as the name of a file containing bearer token.\n"
|
||||||
" for this option, it will be interpreted as the name of a file containing bearer token.\n"
|
// " Note that the format of this command-line option prohibits use of files whose names contain\n"
|
||||||
" Note that the format of this command-line option prohibits use of files whose names contain\n"
|
// " ':' or '#' characters in the file name.\n"
|
||||||
" ':' or '#' characters in the file name.\n"
|
// #endif
|
||||||
#endif
|
|
||||||
" -L Show the name and description of all rules and exit.\n"
|
|
||||||
" -l <rule> Show the name and description of the rule with name <rule> and exit.\n"
|
|
||||||
" --list [<source>] List all defined fields. If <source> is provided, only list those fields for\n"
|
|
||||||
" the source <source>. Current values for <source> are \"syscall\", \"k8s_audit\"\n"
|
// #ifndef MINIMAL_BUILD
|
||||||
#ifndef MINIMAL_BUILD
|
// " -m <url[,marathon_url]>, --mesos-api <url[,marathon_url]>\n"
|
||||||
" -m <url[,marathon_url]>, --mesos-api <url[,marathon_url]>\n"
|
// " Enable Mesos support by connecting to the API server\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"
|
||||||
" 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"
|
||||||
" Marathon url is optional and defaults to Mesos address, port 8080.\n"
|
// " The API servers can also be specified via the environment variable FALCO_MESOS_API.\n"
|
||||||
" The API servers can also be specified via the environment variable FALCO_MESOS_API.\n"
|
// #endif
|
||||||
#endif
|
// " -M <num_seconds> Stop collecting after <num_seconds> reached.\n"
|
||||||
" -M <num_seconds> Stop collecting after <num_seconds> reached.\n"
|
|
||||||
" -N When used with --list, only print field names.\n"
|
// " -o, --option <key>=<val> Set the value of option <key> to <val>. Overrides values in configuration file.\n"
|
||||||
" -o, --option <key>=<val> Set the value of option <key> to <val>. Overrides values in configuration file.\n"
|
// " <key> can be a two-part <key>.<subkey>\n"
|
||||||
" <key> can be a two-part <key>.<subkey>\n"
|
// " -p <output_format>, --print <output_format>\n"
|
||||||
" -p <output_format>, --print <output_format>\n"
|
// " Add additional information to each falco notification's output.\n"
|
||||||
" Add additional information to each falco notification's output.\n"
|
// " With -pc or -pcontainer will use a container-friendly format.\n"
|
||||||
" With -pc or -pcontainer will use a container-friendly format.\n"
|
// " With -pk or -pkubernetes will use a kubernetes-friendly format.\n"
|
||||||
" With -pk or -pkubernetes will use a kubernetes-friendly format.\n"
|
// " With -pm or -pmesos will use a mesos-friendly format.\n"
|
||||||
" With -pm or -pmesos will use a mesos-friendly format.\n"
|
// " Additionally, specifying -pc/-pk/-pm will change the interpretation\n"
|
||||||
" Additionally, specifying -pc/-pk/-pm will change the interpretation\n"
|
// " of %%container.info in rule output fields.\n"
|
||||||
" of %%container.info in rule output fields.\n"
|
// " -P, --pidfile <pid_file> When run as a daemon, write pid to specified file\n"
|
||||||
" -P, --pidfile <pid_file> When run as a daemon, write pid to specified file\n"
|
// " -r <rules_file> Rules file/directory (defaults to value set in configuration file, or /etc/falco_rules.yaml).\n"
|
||||||
" -r <rules_file> 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"
|
||||||
" Can be specified multiple times to read from multiple files/directories.\n"
|
// " -s <stats_file> If specified, append statistics related to Falco's reading/processing of events\n"
|
||||||
" -s <stats_file> If specified, append statistics related to Falco's reading/processing of events\n"
|
// " to this file (only useful in live mode).\n"
|
||||||
" to this file (only useful in live mode).\n"
|
// " --stats-interval <msec> When using -s <stats_file>, write statistics every <msec> ms.\n"
|
||||||
" --stats-interval <msec> When using -s <stats_file>, write statistics every <msec> ms.\n"
|
// " This uses signals, so don't recommend intervals below 200 ms.\n"
|
||||||
" This uses signals, so don't recommend intervals below 200 ms.\n"
|
// " Defaults to 5000 (5 seconds).\n"
|
||||||
" Defaults to 5000 (5 seconds).\n"
|
// " -S <len>, --snaplen <len>\n"
|
||||||
" -S <len>, --snaplen <len>\n"
|
// " Capture the first <len> bytes of each I/O buffer.\n"
|
||||||
" Capture the first <len> bytes of each I/O buffer.\n"
|
// " By default, the first 80 bytes are captured. Use this\n"
|
||||||
" By default, the first 80 bytes are captured. Use this\n"
|
// " option with caution, it can generate huge trace files.\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 <tag> Disable any rules with a tag=<tag>. Can be specified multiple times.\n"
|
// " -U,--unbuffered Turn off output buffering to configured outputs.\n"
|
||||||
" Can not be specified with -t.\n"
|
// " This causes every single line emitted by falco to be flushed,\n"
|
||||||
" -t <tag> Only run those rules with a tag=<tag>. Can be specified multiple times.\n"
|
// " which generates higher CPU usage but is useful when piping those outputs\n"
|
||||||
" Can not be specified with -T/-D.\n"
|
// " into another process or into a script.\n"
|
||||||
" -U,--unbuffered Turn off output buffering to configured outputs.\n"
|
// " -u, --userspace Parse events from userspace.\n"
|
||||||
" This causes every single line emitted by falco to be flushed,\n"
|
// " To be used in conjunction with the ptrace(2) based driver (pdig).\n"
|
||||||
" which generates higher CPU usage but is useful when piping those outputs\n"
|
// " -V, --validate <rules_file> Read the contents of the specified rules(s) file and exit.\n"
|
||||||
" into another process or into a script.\n"
|
// " Can be specified multiple times to validate multiple files.\n"
|
||||||
" -u, --userspace Parse events from userspace.\n"
|
// " -v Verbose output.\n"
|
||||||
" To be used in conjunction with the ptrace(2) based driver (pdig).\n"
|
|
||||||
" -V, --validate <rules_file> Read the contents of the specified rules(s) file and exit.\n"
|
// "\n"
|
||||||
" Can be specified multiple times to validate multiple files.\n"
|
// );
|
||||||
" -v Verbose output.\n"
|
// }
|
||||||
" --version Print version number.\n"
|
|
||||||
"\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void display_fatal_err(const string &msg)
|
static void display_fatal_err(const string &msg)
|
||||||
{
|
{
|
||||||
@@ -395,8 +392,7 @@ static void print_all_ignored_events(sinsp *inspector)
|
|||||||
|
|
||||||
static void list_source_fields(falco_engine *engine, bool verbose, bool names_only, std::string &source)
|
static void list_source_fields(falco_engine *engine, bool verbose, bool names_only, std::string &source)
|
||||||
{
|
{
|
||||||
if(source.size() > 0 &&
|
if(!source.empty() && !(source == "syscall" || source == "k8s_audit"))
|
||||||
!(source == "syscall" || source == "k8s_audit"))
|
|
||||||
{
|
{
|
||||||
throw std::invalid_argument("Value for --list must be \"syscall\" or \"k8s_audit\"");
|
throw std::invalid_argument("Value for --list must be \"syscall\" or \"k8s_audit\"");
|
||||||
}
|
}
|
||||||
@@ -413,7 +409,7 @@ static void list_source_fields(falco_engine *engine, bool verbose, bool names_on
|
|||||||
//
|
//
|
||||||
// ARGUMENT PARSING AND PROGRAM SETUP
|
// ARGUMENT PARSING AND PROGRAM SETUP
|
||||||
//
|
//
|
||||||
int falco_init(int argc, char **argv)
|
int falco_init()
|
||||||
{
|
{
|
||||||
int result = EXIT_SUCCESS;
|
int result = EXIT_SUCCESS;
|
||||||
sinsp* inspector = NULL;
|
sinsp* inspector = NULL;
|
||||||
@@ -514,198 +510,197 @@ int falco_init(int argc, char **argv)
|
|||||||
set<string> disabled_rule_tags;
|
set<string> disabled_rule_tags;
|
||||||
set<string> enabled_rule_tags;
|
set<string> enabled_rule_tags;
|
||||||
|
|
||||||
//
|
// //
|
||||||
// Parse the args
|
// // Parse the args
|
||||||
//
|
// //
|
||||||
while((op = getopt_long(argc, argv,
|
// while((op = getopt_long(argc, argv,
|
||||||
"hc:AbdD:e:F:ik:K:Ll:m:M:No:P:p:r:S:s:T:t:UuvV:w:",
|
// "hc:AbdD:e:F:ik:K:Ll:m:M:No:P:p:r:S:s:T:t:UuvV:w:",
|
||||||
long_options, &long_index)) != -1)
|
// long_options, &long_index)) != -1)
|
||||||
{
|
// {
|
||||||
switch(op)
|
// switch(op)
|
||||||
{
|
// {
|
||||||
case 'h':
|
// case 'h':
|
||||||
usage();
|
// usage();
|
||||||
goto exit;
|
// goto exit;
|
||||||
case 'c':
|
// case 'c':
|
||||||
conf_filename = optarg;
|
// conf_filename = optarg;
|
||||||
break;
|
// break;
|
||||||
case 'A':
|
// case 'A':
|
||||||
all_events = true;
|
// all_events = true;
|
||||||
break;
|
// break;
|
||||||
case 'b':
|
// case 'b':
|
||||||
event_buffer_format = sinsp_evt::PF_BASE64;
|
// event_buffer_format = sinsp_evt::PF_BASE64;
|
||||||
break;
|
// break;
|
||||||
case 'd':
|
// case 'd':
|
||||||
daemon = true;
|
// daemon = true;
|
||||||
break;
|
// break;
|
||||||
case 'D':
|
// case 'D':
|
||||||
substring = optarg;
|
// substring = optarg;
|
||||||
disabled_rule_substrings.insert(substring);
|
// disabled_rule_substrings.insert(substring);
|
||||||
break;
|
// break;
|
||||||
case 'e':
|
// case 'e':
|
||||||
trace_filename = optarg;
|
// trace_filename = optarg;
|
||||||
#ifndef MINIMAL_BUILD
|
// #ifndef MINIMAL_BUILD
|
||||||
k8s_api = new string();
|
// k8s_api = new string();
|
||||||
mesos_api = new string();
|
// mesos_api = new string();
|
||||||
#endif
|
// #endif
|
||||||
break;
|
// break;
|
||||||
case 'F':
|
// case 'F':
|
||||||
list_flds = optarg;
|
// list_flds = optarg;
|
||||||
break;
|
// break;
|
||||||
case 'i':
|
// case 'i':
|
||||||
print_ignored_events = true;
|
// print_ignored_events = true;
|
||||||
break;
|
// break;
|
||||||
#ifndef MINIMAL_BUILD
|
// #ifndef MINIMAL_BUILD
|
||||||
case 'k':
|
// case 'k':
|
||||||
k8s_api = new string(optarg);
|
// k8s_api = new string(optarg);
|
||||||
break;
|
// break;
|
||||||
case 'K':
|
// case 'K':
|
||||||
k8s_api_cert = new string(optarg);
|
// k8s_api_cert = new string(optarg);
|
||||||
break;
|
// break;
|
||||||
#endif
|
// #endif
|
||||||
case 'L':
|
// case 'L':
|
||||||
describe_all_rules = true;
|
// describe_all_rules = true;
|
||||||
break;
|
// break;
|
||||||
case 'l':
|
// case 'l':
|
||||||
describe_rule = optarg;
|
// describe_rule = optarg;
|
||||||
break;
|
// break;
|
||||||
#ifndef MINIMAL_BUILD
|
// #ifndef MINIMAL_BUILD
|
||||||
case 'm':
|
// case 'm':
|
||||||
mesos_api = new string(optarg);
|
// mesos_api = new string(optarg);
|
||||||
break;
|
// break;
|
||||||
#endif
|
// #endif
|
||||||
case 'M':
|
// case 'M':
|
||||||
duration_to_tot = atoi(optarg);
|
// duration_to_tot = atoi(optarg);
|
||||||
if(duration_to_tot <= 0)
|
// if(duration_to_tot <= 0)
|
||||||
{
|
// {
|
||||||
throw sinsp_exception(string("invalid duration") + optarg);
|
// throw sinsp_exception(string("invalid duration") + optarg);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case 'N':
|
// case 'N':
|
||||||
names_only = true;
|
// names_only = true;
|
||||||
break;
|
// break;
|
||||||
case 'o':
|
// case 'o':
|
||||||
cmdline_options.push_back(optarg);
|
// cmdline_options.push_back(optarg);
|
||||||
break;
|
// break;
|
||||||
case 'P':
|
// case 'P':
|
||||||
pidfilename = optarg;
|
// pidfilename = optarg;
|
||||||
break;
|
// break;
|
||||||
case 'p':
|
// case 'p':
|
||||||
if(string(optarg) == "c" || string(optarg) == "container")
|
// if(string(optarg) == "c" || string(optarg) == "container")
|
||||||
{
|
// {
|
||||||
output_format = "container=%container.name (id=%container.id)";
|
// output_format = "container=%container.name (id=%container.id)";
|
||||||
replace_container_info = true;
|
// replace_container_info = true;
|
||||||
}
|
// }
|
||||||
else if(string(optarg) == "k" || string(optarg) == "kubernetes")
|
// else if(string(optarg) == "k" || string(optarg) == "kubernetes")
|
||||||
{
|
// {
|
||||||
output_format = "k8s.ns=%k8s.ns.name k8s.pod=%k8s.pod.name container=%container.id";
|
// output_format = "k8s.ns=%k8s.ns.name k8s.pod=%k8s.pod.name container=%container.id";
|
||||||
replace_container_info = true;
|
// replace_container_info = true;
|
||||||
}
|
// }
|
||||||
else if(string(optarg) == "m" || string(optarg) == "mesos")
|
// else if(string(optarg) == "m" || string(optarg) == "mesos")
|
||||||
{
|
// {
|
||||||
output_format = "task=%mesos.task.name container=%container.id";
|
// output_format = "task=%mesos.task.name container=%container.id";
|
||||||
replace_container_info = true;
|
// replace_container_info = true;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
output_format = optarg;
|
// output_format = optarg;
|
||||||
replace_container_info = false;
|
// replace_container_info = false;
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case 'r':
|
// case 'r':
|
||||||
falco_configuration::read_rules_file_directory(string(optarg), rules_filenames);
|
// falco_configuration::read_rules_file_directory(string(optarg), rules_filenames);
|
||||||
break;
|
// break;
|
||||||
case 'S':
|
// case 'S':
|
||||||
snaplen = atoi(optarg);
|
// snaplen = atoi(optarg);
|
||||||
break;
|
// break;
|
||||||
case 's':
|
// case 's':
|
||||||
stats_filename = optarg;
|
// stats_filename = optarg;
|
||||||
break;
|
// break;
|
||||||
case 'T':
|
// case 'T':
|
||||||
disabled_rule_tags.insert(optarg);
|
// disabled_rule_tags.insert(optarg);
|
||||||
break;
|
// break;
|
||||||
case 't':
|
// case 't':
|
||||||
enabled_rule_tags.insert(optarg);
|
// enabled_rule_tags.insert(optarg);
|
||||||
break;
|
// break;
|
||||||
case 'U':
|
// case 'U':
|
||||||
buffered_outputs = false;
|
// buffered_outputs = false;
|
||||||
buffered_cmdline = true;
|
// buffered_cmdline = true;
|
||||||
break;
|
// break;
|
||||||
case 'u':
|
// case 'u':
|
||||||
userspace = true;
|
// userspace = true;
|
||||||
break;
|
// break;
|
||||||
case 'v':
|
// case 'v':
|
||||||
verbose = true;
|
// verbose = true;
|
||||||
break;
|
// break;
|
||||||
case 'V':
|
// case 'V':
|
||||||
validate_rules_filenames.push_back(optarg);
|
// validate_rules_filenames.push_back(optarg);
|
||||||
break;
|
// break;
|
||||||
case 'w':
|
// case 'w':
|
||||||
outfile = optarg;
|
// outfile = optarg;
|
||||||
break;
|
// break;
|
||||||
case '?':
|
// case '?':
|
||||||
result = EXIT_FAILURE;
|
// result = EXIT_FAILURE;
|
||||||
goto exit;
|
// goto exit;
|
||||||
|
|
||||||
case 0:
|
// case 0:
|
||||||
if(string(long_options[long_index].name) == "version")
|
// if(string(long_options[long_index].name) == "version")
|
||||||
{
|
// {
|
||||||
printf("Falco version: %s\n", FALCO_VERSION);
|
// printf("Falco version: %s\n", FALCO_VERSION);
|
||||||
printf("Driver version: %s\n", DRIVER_VERSION);
|
// printf("Driver version: %s\n", DRIVER_VERSION);
|
||||||
return EXIT_SUCCESS;
|
// return EXIT_SUCCESS;
|
||||||
}
|
// }
|
||||||
else if (string(long_options[long_index].name) == "cri")
|
// else if (string(long_options[long_index].name) == "cri")
|
||||||
{
|
// {
|
||||||
if(optarg != NULL)
|
// if(optarg != NULL)
|
||||||
{
|
// {
|
||||||
cri_socket_path = optarg;
|
// cri_socket_path = optarg;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else if (string(long_options[long_index].name) == "disable-cri-async")
|
// else if (string(long_options[long_index].name) == "disable-cri-async")
|
||||||
{
|
// {
|
||||||
cri_async = false;
|
// cri_async = false;
|
||||||
}
|
// }
|
||||||
else if (string(long_options[long_index].name) == "list")
|
// else if (string(long_options[long_index].name) == "list")
|
||||||
{
|
// {
|
||||||
list_flds = true;
|
// list_flds = true;
|
||||||
if(optarg != NULL)
|
// if(optarg != NULL)
|
||||||
{
|
// {
|
||||||
list_flds_source = optarg;
|
// list_flds_source = optarg;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else if (string(long_options[long_index].name) == "stats-interval")
|
// else if (string(long_options[long_index].name) == "stats-interval")
|
||||||
{
|
// {
|
||||||
stats_interval = atoi(optarg);
|
// stats_interval = atoi(optarg);
|
||||||
}
|
// }
|
||||||
else if (string(long_options[long_index].name) == "support")
|
// else if (string(long_options[long_index].name) == "support")
|
||||||
{
|
// {
|
||||||
print_support = true;
|
// print_support = true;
|
||||||
}
|
// }
|
||||||
else if (string(long_options[long_index].name) == "disable-source")
|
// else if (string(long_options[long_index].name) == "disable-source")
|
||||||
{
|
// {
|
||||||
if(optarg != NULL)
|
// if(optarg != NULL)
|
||||||
{
|
// {
|
||||||
disable_sources.insert(optarg);
|
// disable_sources.insert(optarg);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else if (string(long_options[long_index].name)== "alternate-lua-dir")
|
// else if (string(long_options[long_index].name)== "alternate-lua-dir")
|
||||||
{
|
// {
|
||||||
if(optarg != NULL)
|
// if(optarg != NULL)
|
||||||
{
|
// {
|
||||||
alternate_lua_dir = optarg;
|
// alternate_lua_dir = optarg;
|
||||||
if (alternate_lua_dir.back() != '/') {
|
// if (alternate_lua_dir.back() != '/') {
|
||||||
alternate_lua_dir += '/';
|
// alternate_lua_dir += '/';
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
default:
|
// default:
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// }
|
||||||
inspector = new sinsp();
|
inspector = new sinsp();
|
||||||
inspector->set_buffer_format(event_buffer_format);
|
inspector->set_buffer_format(event_buffer_format);
|
||||||
|
|
||||||
@@ -921,14 +916,14 @@ int falco_init(int argc, char **argv)
|
|||||||
throw std::runtime_error(string("Could not uname() to find system info: %s\n") + strerror(errno));
|
throw std::runtime_error(string("Could not uname() to find system info: %s\n") + strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(char **arg = argv; *arg; arg++)
|
// for(char **arg = argv; *arg; arg++)
|
||||||
{
|
// {
|
||||||
if(cmdline.size() > 0)
|
// if(cmdline.size() > 0)
|
||||||
{
|
// {
|
||||||
cmdline += " ";
|
// cmdline += " ";
|
||||||
}
|
// }
|
||||||
cmdline += *arg;
|
// cmdline += *arg;
|
||||||
}
|
// }
|
||||||
|
|
||||||
support["version"] = FALCO_VERSION;
|
support["version"] = FALCO_VERSION;
|
||||||
support["system_info"]["sysname"] = sysinfo.sysname;
|
support["system_info"]["sysname"] = sysinfo.sysname;
|
||||||
@@ -1181,8 +1176,8 @@ int falco_init(int argc, char **argv)
|
|||||||
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
|
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
|
||||||
}
|
}
|
||||||
open_f(inspector);
|
open_f(inspector);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rethrow_exception(current_exception());
|
rethrow_exception(current_exception());
|
||||||
}
|
}
|
||||||
@@ -1291,7 +1286,7 @@ int falco_init(int argc, char **argv)
|
|||||||
|
|
||||||
if(!trace_filename.empty() && !trace_is_scap)
|
if(!trace_filename.empty() && !trace_is_scap)
|
||||||
{
|
{
|
||||||
#ifndef MINIMAL_BUILD
|
#ifndef MINIMAL_BUILD
|
||||||
read_k8s_audit_trace_file(engine,
|
read_k8s_audit_trace_file(engine,
|
||||||
outputs,
|
outputs,
|
||||||
trace_filename);
|
trace_filename);
|
||||||
@@ -1378,13 +1373,23 @@ exit:
|
|||||||
//
|
//
|
||||||
// MAIN
|
// MAIN
|
||||||
//
|
//
|
||||||
int main(int argc, char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int rc;
|
try
|
||||||
|
{
|
||||||
|
auto cli = new falco::cli(argc, argv);
|
||||||
|
cli->run();
|
||||||
|
}
|
||||||
|
catch(const cxxopts::OptionException &e)
|
||||||
|
{
|
||||||
|
display_fatal_err("Error parsing options: " + string(e.what()) + "\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc;
|
||||||
// g_restart will cause the falco loop to exit, but we
|
// g_restart will cause the falco loop to exit, but we
|
||||||
// should reload everything and start over.
|
// should reload everything and start over.
|
||||||
while((rc = falco_init(argc, argv)) == EXIT_SUCCESS && g_restart)
|
while((rc = falco_init()) == EXIT_SUCCESS && g_restart)
|
||||||
{
|
{
|
||||||
g_restart = false;
|
g_restart = false;
|
||||||
optind = 1;
|
optind = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user