mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-30 00:22:12 +00:00
Compare commits
3 Commits
update/log
...
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")
|
||||
endif()
|
||||
|
||||
#string-view-lite
|
||||
# string-view-lite
|
||||
include(DownloadStringViewLite)
|
||||
|
||||
# cxxopts
|
||||
include(DownloadCxxOpts)
|
||||
|
||||
if(NOT MINIMAL_BUILD)
|
||||
# gRPC
|
||||
include(gRPC)
|
||||
|
||||
@@ -11,8 +11,9 @@ Content in this document can be used to publically share about Falco.
|
||||
|
||||
### Logo
|
||||
|
||||
You can find the Falco logo in PNG and SVG in different colors in
|
||||
the [CNCF's artwork repository](https://github.com/cncf/artwork/blob/master/examples/incubating.md#falco-logos).
|
||||
There are 3 logos available for use in this directory. Use the primary logo unless required otherwise due to background issues, or printing.
|
||||
|
||||
The Falco logo is Apache 2 licensed and free to use in media and publication for the CNCF Falco project.
|
||||
|
||||
### Colors
|
||||
|
||||
|
||||
BIN
brand/primary-logo.png
Normal file
BIN
brand/primary-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
1
brand/teal-logo.svg
Normal file
1
brand/teal-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 708.41 374.92"><defs><style>.cls-1{fill:#00b4c8;}</style></defs><title>Falco horizontal logo_teal2</title><g id="fqqZXT"><path class="cls-1" d="M204.69,154.4Q151.5,208,98,261.25a48.42,48.42,0,0,1-5.27,4.87c-2.55,1.89-5.34,2-7.65-.45s-1.51-5,.41-7.06c4.6-4.94,9.35-9.74,14.13-14.5q52.56-52.31,105.14-104.59c3.35-3.34,18.05,7.52,21.58,11.1"/><path class="cls-1" d="M215.06,171.36c-.15,2.14-1.54,3.55-2.93,4.94l-87.82,87.79c-2.75,2.74-6,5.42-9.46,1.68-3.15-3.39-.5-6.44,2.06-9q43.44-43.44,86.89-86.87c2.21-2.22,4.58-4.23,8-3A4.61,4.61,0,0,1,215.06,171.36Z"/><path class="cls-1" d="M70.93,71c2.42-.09,4.09,1.31,5.64,2.87q41.82,41.79,83.61,83.59c2.6,2.61,5,5.74,1.69,9s-6.41,1-9-1.66Q111,123,69.25,81.2c-2.09-2.1-3.72-4.39-2.45-7.53A4.34,4.34,0,0,1,70.93,71Z"/><path class="cls-1" d="M203.42,268c-5,1-8.9-1.34-12.45-5-6.35-6.61-12.87-13-19.41-19.46-3.85-3.8-4-7.41-.14-11.28,11.14-11.07,22.21-22.21,33.35-33.29,2.45-2.44,5.43-4.49,8.55-1.55,3.48,3.29,1.19,6.41-1.39,9-8.74,8.84-17.44,17.73-26.4,26.35-3.4,3.27-3.93,5.72-.19,9.06,4.22,3.78,8.13,7.91,12,12,2.54,2.68,5.35,4.25,9.18,4.11s8.28-.12,8.16,5.09c-.12,5-4.74,4.8-8.4,5.14A21,21,0,0,1,203.42,268Z"/><path class="cls-1" d="M148.7,178.36c-.75,3.49-2.68,5.6-6.43,4.36a13,13,0,0,1-4.74-3.31q-30.11-30-60.1-60a23.14,23.14,0,0,1-2.56-3c-1.72-2.42-1.88-5,.3-7.11s4.84-1.76,7,.26c3.65,3.42,7.17,7,10.71,10.53q25.65,25.64,51.28,51.3C146.12,173.37,148.49,175.13,148.7,178.36Z"/><path class="cls-1" d="M133.74,192.93a4.9,4.9,0,0,1-2.53,4.29,5.37,5.37,0,0,1-6.63-.95c-3.35-3.1-6.57-6.34-9.8-9.57q-14.34-14.3-28.61-28.63a34.27,34.27,0,0,1-4.17-5,4.57,4.57,0,0,1,.36-6,5,5,0,0,1,6-1.12,11.65,11.65,0,0,1,3.7,2.58q19.44,19.33,38.79,38.76C132.4,188.85,133.77,190.54,133.74,192.93Z"/></g><path class="cls-1" d="M413.15,190.86a25.57,25.57,0,0,0-10.35-6.63,46.78,46.78,0,0,0-16-2.37A83.35,83.35,0,0,0,372,183.12a75.16,75.16,0,0,0-10.58,2.53l2.37,15.48a53.47,53.47,0,0,1,9-2.21A72.44,72.44,0,0,1,385,198a22.61,22.61,0,0,1,8.13,1.26,13,13,0,0,1,5.22,3.56,13.23,13.23,0,0,1,2.76,5.29,24.6,24.6,0,0,1,.79,6.32v3.16a61.65,61.65,0,0,0-7.42-1.34,57.43,57.43,0,0,0-6.64-.4,61.45,61.45,0,0,0-13,1.35,32.26,32.26,0,0,0-11,4.42,22.7,22.7,0,0,0-7.51,8,24.09,24.09,0,0,0-2.76,12A28.39,28.39,0,0,0,356,254.05a21.6,21.6,0,0,0,6.79,8.22,28.56,28.56,0,0,0,10.51,4.58,60.24,60.24,0,0,0,13.58,1.42A137.25,137.25,0,0,0,407,266.93c5.94-.9,10.4-1.66,13.35-2.29V214.56a50.84,50.84,0,0,0-1.66-13.35A24.93,24.93,0,0,0,413.15,190.86Zm-11.3,61.3a71.4,71.4,0,0,1-13.43.94q-7.26,0-11.53-2.6t-4.26-9.4a10,10,0,0,1,1.57-5.77,10.67,10.67,0,0,1,4.19-3.55,20.18,20.18,0,0,1,5.85-1.74,43.43,43.43,0,0,1,6.39-.47,42.23,42.23,0,0,1,6.64.47,37,37,0,0,1,4.58,1Z"/><path class="cls-1" d="M461.38,248.44a9.27,9.27,0,0,1-2-4,26.17,26.17,0,0,1-.55-5.85V143.94l-19.12,3.16v95.1a40.74,40.74,0,0,0,1.35,11,17.57,17.57,0,0,0,4.66,8.06,21.71,21.71,0,0,0,8.92,5,52,52,0,0,0,14.14,1.89l2.69-15.8a29.78,29.78,0,0,1-6.24-1.34A8.76,8.76,0,0,1,461.38,248.44Z"/><path class="cls-1" d="M532.2,251.05a49.24,49.24,0,0,1-9.64.95q-13.11,0-18.64-7.19t-5.53-19.51q0-12.8,5.85-19.83t17.06-7a40.4,40.4,0,0,1,8.92.95,43.38,43.38,0,0,1,7.51,2.37l4.1-15.64a57.88,57.88,0,0,0-22.11-4.26,42.15,42.15,0,0,0-17.06,3.31,37.35,37.35,0,0,0-12.88,9.17,40.64,40.64,0,0,0-8.14,13.82,50.82,50.82,0,0,0-2.84,17.14,56.83,56.83,0,0,0,2.53,17.3A37.22,37.22,0,0,0,489,256.34a34.82,34.82,0,0,0,13,9,47.83,47.83,0,0,0,18.4,3.24,68.05,68.05,0,0,0,13.19-1.27,39.84,39.84,0,0,0,9.56-2.84l-2.69-15.8A45,45,0,0,1,532.2,251.05Z"/><path class="cls-1" d="M625.77,207.37a40.7,40.7,0,0,0-8.14-13.67,35.23,35.23,0,0,0-12.56-8.76,40.93,40.93,0,0,0-16-3.08,40.34,40.34,0,0,0-16,3.08,36.32,36.32,0,0,0-12.56,8.76,39.88,39.88,0,0,0-8.21,13.67,51.31,51.31,0,0,0-2.93,17.77A52,52,0,0,0,552.31,243a40.47,40.47,0,0,0,8.13,13.75,36.57,36.57,0,0,0,12.48,8.85A40.14,40.14,0,0,0,589,268.74a40.69,40.69,0,0,0,16.19-3.15,36.32,36.32,0,0,0,12.56-8.85A39.7,39.7,0,0,0,625.85,243a53.47,53.47,0,0,0,2.84-17.85A51.55,51.55,0,0,0,625.77,207.37Zm-22,37.52q-5.29,7.28-14.77,7.27t-14.77-7.27q-5.29-7.26-5.3-19.75,0-12.31,5.3-19.51T589,198.44q9.48,0,14.77,7.19t5.29,19.51Q609.1,237.62,603.81,244.89Z"/><path class="cls-1" d="M347.24,218h-47.8v50.57H279.65V150h75.89v15.88h-56.1v36.23h47.8Z"/></svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
BIN
brand/white-logo.png
Normal file
BIN
brand/white-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
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)
|
||||
17
falco.yaml
17
falco.yaml
@@ -87,23 +87,6 @@ syscall_event_drops:
|
||||
rate: .03333
|
||||
max_burst: 10
|
||||
|
||||
# Falco continuously monitors outputs performance. When an output channel does not allow
|
||||
# to deliver an alert within a given deadline, an error is reported indicating
|
||||
# which output is blocking notifications.
|
||||
# The timeout error will be reported to the log according to the above log_* settings.
|
||||
# Note that the notification will not be discarded from the output queue; thus,
|
||||
# output channels may indefinitely remain blocked.
|
||||
# An output timeout error indeed indicate a misconfiguration issue or I/O problems
|
||||
# that cannot be recovered by Falco and should be fixed by the user.
|
||||
#
|
||||
# The "output_timeout" value specifies the duration in milliseconds to wait before
|
||||
# considering the deadline exceed.
|
||||
#
|
||||
# With a 2000ms default, the notification consumer can block the Falco output
|
||||
# for up to 2 seconds without reaching the timeout.
|
||||
|
||||
output_timeout: 2000
|
||||
|
||||
# A throttling mechanism implemented as a token bucket limits the
|
||||
# rate of falco notifications. This throttling is controlled by the following configuration
|
||||
# options:
|
||||
|
||||
@@ -3070,22 +3070,6 @@
|
||||
priority: WARNING
|
||||
tags: [process]
|
||||
|
||||
- list: run_as_root_image_list
|
||||
items: []
|
||||
|
||||
- macro: user_known_run_as_root_container
|
||||
condition: (container.image.repository in (run_as_root_image_list))
|
||||
|
||||
# The rule is disabled by default and should be enabled when non-root container policy has been applied.
|
||||
# Note the rule will not work as expected when usernamespace is applied, e.g. userns-remap is enabled.
|
||||
- rule: Container Run as Root User
|
||||
desc: Detected container running as root user
|
||||
condition: spawned_process and container and proc.vpid=1 and user.uid=0 and not user_known_run_as_root_container
|
||||
enabled: false
|
||||
output: Container launched with root user privilege (uid=%user.uid container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
||||
priority: INFO
|
||||
tags: [container, process]
|
||||
|
||||
# Application rules have moved to application_rules.yaml. Please look
|
||||
# there if you want to enable them by adding to
|
||||
# falco_rules.local.yaml.
|
||||
|
||||
@@ -15,6 +15,7 @@ configure_file(config_falco.h.in config_falco.h)
|
||||
|
||||
set(
|
||||
FALCO_SOURCES
|
||||
cli.cpp
|
||||
configuration.cpp
|
||||
logger.cpp
|
||||
falco_outputs.cpp
|
||||
@@ -34,6 +35,7 @@ set(
|
||||
"${PROJECT_BINARY_DIR}/userspace/falco"
|
||||
"${PROJECT_BINARY_DIR}/driver/src"
|
||||
"${STRING_VIEW_LITE_INCLUDE}"
|
||||
"${CXXOPTS_INCLUDE}"
|
||||
"${YAMLCPP_INCLUDE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include"
|
||||
@@ -41,6 +43,7 @@ set(
|
||||
|
||||
set(
|
||||
FALCO_DEPENDENCIES
|
||||
cxxopts
|
||||
string-view-lite
|
||||
libyaml
|
||||
b64
|
||||
@@ -123,16 +126,16 @@ target_include_directories(
|
||||
${FALCO_INCLUDE_DIRECTORIES}
|
||||
)
|
||||
|
||||
if(NOT MINIMAL_BUILD)
|
||||
add_custom_command(
|
||||
TARGET falco
|
||||
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/verify_engine_fields.sh ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Comparing engine fields checksum in falco_engine.h to actual fields"
|
||||
)
|
||||
else()
|
||||
message(STATUS "Skipping engine fields checksum when building the minimal Falco.")
|
||||
endif()
|
||||
# if(NOT MINIMAL_BUILD)
|
||||
# add_custom_command(
|
||||
# TARGET falco
|
||||
# COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/verify_engine_fields.sh ${CMAKE_SOURCE_DIR}
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
# COMMENT "Comparing engine fields checksum in falco_engine.h to actual fields"
|
||||
# )
|
||||
# else()
|
||||
# message(STATUS "Skipping engine fields checksum when building the minimal Falco.")
|
||||
# endif()
|
||||
|
||||
if(NOT MINIMAL_BUILD)
|
||||
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
|
||||
@@ -176,8 +176,6 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
|
||||
|
||||
falco_logger::set_level(m_log_level);
|
||||
|
||||
m_output_timeout = m_config->get_scalar<uint32_t>("output_timeout", 2000);
|
||||
|
||||
m_notifications_rate = m_config->get_scalar<uint32_t>("outputs", "rate", 1);
|
||||
m_notifications_max_burst = m_config->get_scalar<uint32_t>("outputs", "max_burst", 1000);
|
||||
|
||||
|
||||
@@ -204,7 +204,6 @@ public:
|
||||
|
||||
bool m_buffered_outputs;
|
||||
bool m_time_format_iso_8601;
|
||||
uint32_t m_output_timeout;
|
||||
|
||||
bool m_grpc_enabled;
|
||||
uint32_t m_grpc_threadiness;
|
||||
|
||||
@@ -43,6 +43,7 @@ limitations under the License.
|
||||
#include "falco_engine.h"
|
||||
#include "config_falco.h"
|
||||
#include "statsfilewriter.h"
|
||||
#include "cli.h"
|
||||
#ifndef MINIMAL_BUILD
|
||||
#include "webserver.h"
|
||||
#include "grpc_server.h"
|
||||
@@ -74,106 +75,102 @@ static void restart_falco(int signal)
|
||||
g_restart = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Program help
|
||||
//
|
||||
static void usage()
|
||||
{
|
||||
printf(
|
||||
"Falco version: " FALCO_VERSION "\n"
|
||||
"Usage: falco [options]\n\n"
|
||||
"Options:\n"
|
||||
" -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_SIMPLE_CONS flag.\n"
|
||||
" --alternate-lua-dir <path> Specify an alternate path for loading Falco lua files\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> 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-cri-async Disable asynchronous CRI metadata fetching.\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 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"
|
||||
" depending on the number of containers and the frequency at which they are created/started/stopped\n"
|
||||
" --disable-source <event_source>\n"
|
||||
" Disable a specific event source.\n"
|
||||
" Available event sources are: syscall, k8s_audit.\n"
|
||||
" It can be passed multiple times.\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"
|
||||
" k8s audit events) instead of tapping into live.\n"
|
||||
#ifndef MINIMAL_BUILD
|
||||
" -k <url>, --k8s-api <url>\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 <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"
|
||||
" 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"
|
||||
" 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"
|
||||
" ':' or '#' characters in the file name.\n"
|
||||
#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
|
||||
" -m <url[,marathon_url]>, --mesos-api <url[,marathon_url]>\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 FALCO_MESOS_API.\n"
|
||||
#endif
|
||||
" -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"
|
||||
" <key> can be a two-part <key>.<subkey>\n"
|
||||
" -p <output_format>, --print <output_format>\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"
|
||||
" 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"
|
||||
" -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"
|
||||
" 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"
|
||||
" to this file (only useful in live mode).\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"
|
||||
" Defaults to 5000 (5 seconds).\n"
|
||||
" -S <len>, --snaplen <len>\n"
|
||||
" Capture the first <len> 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 <tag> Disable any rules with a tag=<tag>. Can be specified multiple times.\n"
|
||||
" Can not be specified with -t.\n"
|
||||
" -t <tag> Only run those rules with a tag=<tag>. Can be specified multiple times.\n"
|
||||
" Can not be specified with -T/-D.\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"
|
||||
" -u, --userspace Parse events from userspace.\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"
|
||||
" Can be specified multiple times to validate multiple files.\n"
|
||||
" -v Verbose output.\n"
|
||||
" --version Print version number.\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
// //
|
||||
// // Program help
|
||||
// //
|
||||
// static void usage()
|
||||
// {
|
||||
// printf(
|
||||
// "Falco version: " FALCO_VERSION "\n"
|
||||
// "Usage: falco [options]\n\n"
|
||||
// "Options:\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"
|
||||
// " --alternate-lua-dir <path> Specify an alternate path for loading Falco lua files\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> 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-cri-async Disable asynchronous CRI metadata fetching.\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 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"
|
||||
// " depending on the number of containers and the frequency at which they are created/started/stopped\n"
|
||||
// " --disable-source <event_source>\n"
|
||||
// " Disable a specific event source.\n"
|
||||
// " Available event sources are: syscall, k8s_audit.\n"
|
||||
// " It can be passed multiple times.\n"
|
||||
// " Can not disable both the event sources.\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"
|
||||
// #ifndef MINIMAL_BUILD
|
||||
// " -k <url>, --k8s-api <url>\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 <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"
|
||||
// " 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"
|
||||
// " 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"
|
||||
// " ':' or '#' characters in the file name.\n"
|
||||
// #endif
|
||||
|
||||
|
||||
|
||||
|
||||
// #ifndef MINIMAL_BUILD
|
||||
// " -m <url[,marathon_url]>, --mesos-api <url[,marathon_url]>\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 FALCO_MESOS_API.\n"
|
||||
// #endif
|
||||
// " -M <num_seconds> Stop collecting after <num_seconds> reached.\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"
|
||||
// " -p <output_format>, --print <output_format>\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"
|
||||
// " 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"
|
||||
// " -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"
|
||||
// " 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"
|
||||
// " to this file (only useful in live mode).\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"
|
||||
// " Defaults to 5000 (5 seconds).\n"
|
||||
// " -S <len>, --snaplen <len>\n"
|
||||
// " Capture the first <len> 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"
|
||||
|
||||
|
||||
// " -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"
|
||||
// " -u, --userspace Parse events from userspace.\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"
|
||||
// " Can be specified multiple times to validate multiple files.\n"
|
||||
// " -v Verbose output.\n"
|
||||
|
||||
// "\n"
|
||||
// );
|
||||
// }
|
||||
|
||||
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)
|
||||
{
|
||||
if(source.size() > 0 &&
|
||||
!(source == "syscall" || source == "k8s_audit"))
|
||||
if(!source.empty() && !(source == "syscall" || source == "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
|
||||
//
|
||||
int falco_init(int argc, char **argv)
|
||||
int falco_init()
|
||||
{
|
||||
int result = EXIT_SUCCESS;
|
||||
sinsp* inspector = NULL;
|
||||
@@ -514,198 +510,197 @@ int falco_init(int argc, char **argv)
|
||||
set<string> disabled_rule_tags;
|
||||
set<string> enabled_rule_tags;
|
||||
|
||||
//
|
||||
// Parse the args
|
||||
//
|
||||
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:",
|
||||
long_options, &long_index)) != -1)
|
||||
{
|
||||
switch(op)
|
||||
{
|
||||
case 'h':
|
||||
usage();
|
||||
goto exit;
|
||||
case 'c':
|
||||
conf_filename = optarg;
|
||||
break;
|
||||
case 'A':
|
||||
all_events = true;
|
||||
break;
|
||||
case 'b':
|
||||
event_buffer_format = sinsp_evt::PF_BASE64;
|
||||
break;
|
||||
case 'd':
|
||||
daemon = true;
|
||||
break;
|
||||
case 'D':
|
||||
substring = optarg;
|
||||
disabled_rule_substrings.insert(substring);
|
||||
break;
|
||||
case 'e':
|
||||
trace_filename = optarg;
|
||||
#ifndef MINIMAL_BUILD
|
||||
k8s_api = new string();
|
||||
mesos_api = new string();
|
||||
#endif
|
||||
break;
|
||||
case 'F':
|
||||
list_flds = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
print_ignored_events = true;
|
||||
break;
|
||||
#ifndef MINIMAL_BUILD
|
||||
case 'k':
|
||||
k8s_api = new string(optarg);
|
||||
break;
|
||||
case 'K':
|
||||
k8s_api_cert = new string(optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'L':
|
||||
describe_all_rules = true;
|
||||
break;
|
||||
case 'l':
|
||||
describe_rule = optarg;
|
||||
break;
|
||||
#ifndef MINIMAL_BUILD
|
||||
case 'm':
|
||||
mesos_api = new string(optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'M':
|
||||
duration_to_tot = atoi(optarg);
|
||||
if(duration_to_tot <= 0)
|
||||
{
|
||||
throw sinsp_exception(string("invalid duration") + optarg);
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
names_only = true;
|
||||
break;
|
||||
case 'o':
|
||||
cmdline_options.push_back(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
pidfilename = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
if(string(optarg) == "c" || string(optarg) == "container")
|
||||
{
|
||||
output_format = "container=%container.name (id=%container.id)";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(string(optarg) == "k" || string(optarg) == "kubernetes")
|
||||
{
|
||||
output_format = "k8s.ns=%k8s.ns.name k8s.pod=%k8s.pod.name container=%container.id";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(string(optarg) == "m" || string(optarg) == "mesos")
|
||||
{
|
||||
output_format = "task=%mesos.task.name container=%container.id";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output_format = optarg;
|
||||
replace_container_info = false;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
falco_configuration::read_rules_file_directory(string(optarg), rules_filenames);
|
||||
break;
|
||||
case 'S':
|
||||
snaplen = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
stats_filename = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
disabled_rule_tags.insert(optarg);
|
||||
break;
|
||||
case 't':
|
||||
enabled_rule_tags.insert(optarg);
|
||||
break;
|
||||
case 'U':
|
||||
buffered_outputs = false;
|
||||
buffered_cmdline = true;
|
||||
break;
|
||||
case 'u':
|
||||
userspace = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'V':
|
||||
validate_rules_filenames.push_back(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case '?':
|
||||
result = EXIT_FAILURE;
|
||||
goto exit;
|
||||
// //
|
||||
// // Parse the args
|
||||
// //
|
||||
// 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:",
|
||||
// long_options, &long_index)) != -1)
|
||||
// {
|
||||
// switch(op)
|
||||
// {
|
||||
// case 'h':
|
||||
// usage();
|
||||
// goto exit;
|
||||
// case 'c':
|
||||
// conf_filename = optarg;
|
||||
// break;
|
||||
// case 'A':
|
||||
// all_events = true;
|
||||
// break;
|
||||
// case 'b':
|
||||
// event_buffer_format = sinsp_evt::PF_BASE64;
|
||||
// break;
|
||||
// case 'd':
|
||||
// daemon = true;
|
||||
// break;
|
||||
// case 'D':
|
||||
// substring = optarg;
|
||||
// disabled_rule_substrings.insert(substring);
|
||||
// break;
|
||||
// case 'e':
|
||||
// trace_filename = optarg;
|
||||
// #ifndef MINIMAL_BUILD
|
||||
// k8s_api = new string();
|
||||
// mesos_api = new string();
|
||||
// #endif
|
||||
// break;
|
||||
// case 'F':
|
||||
// list_flds = optarg;
|
||||
// break;
|
||||
// case 'i':
|
||||
// print_ignored_events = true;
|
||||
// break;
|
||||
// #ifndef MINIMAL_BUILD
|
||||
// case 'k':
|
||||
// k8s_api = new string(optarg);
|
||||
// break;
|
||||
// case 'K':
|
||||
// k8s_api_cert = new string(optarg);
|
||||
// break;
|
||||
// #endif
|
||||
// case 'L':
|
||||
// describe_all_rules = true;
|
||||
// break;
|
||||
// case 'l':
|
||||
// describe_rule = optarg;
|
||||
// break;
|
||||
// #ifndef MINIMAL_BUILD
|
||||
// case 'm':
|
||||
// mesos_api = new string(optarg);
|
||||
// break;
|
||||
// #endif
|
||||
// case 'M':
|
||||
// duration_to_tot = atoi(optarg);
|
||||
// if(duration_to_tot <= 0)
|
||||
// {
|
||||
// throw sinsp_exception(string("invalid duration") + optarg);
|
||||
// }
|
||||
// break;
|
||||
// case 'N':
|
||||
// names_only = true;
|
||||
// break;
|
||||
// case 'o':
|
||||
// cmdline_options.push_back(optarg);
|
||||
// break;
|
||||
// case 'P':
|
||||
// pidfilename = optarg;
|
||||
// break;
|
||||
// case 'p':
|
||||
// if(string(optarg) == "c" || string(optarg) == "container")
|
||||
// {
|
||||
// output_format = "container=%container.name (id=%container.id)";
|
||||
// replace_container_info = true;
|
||||
// }
|
||||
// else if(string(optarg) == "k" || string(optarg) == "kubernetes")
|
||||
// {
|
||||
// output_format = "k8s.ns=%k8s.ns.name k8s.pod=%k8s.pod.name container=%container.id";
|
||||
// replace_container_info = true;
|
||||
// }
|
||||
// else if(string(optarg) == "m" || string(optarg) == "mesos")
|
||||
// {
|
||||
// output_format = "task=%mesos.task.name container=%container.id";
|
||||
// replace_container_info = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// output_format = optarg;
|
||||
// replace_container_info = false;
|
||||
// }
|
||||
// break;
|
||||
// case 'r':
|
||||
// falco_configuration::read_rules_file_directory(string(optarg), rules_filenames);
|
||||
// break;
|
||||
// case 'S':
|
||||
// snaplen = atoi(optarg);
|
||||
// break;
|
||||
// case 's':
|
||||
// stats_filename = optarg;
|
||||
// break;
|
||||
// case 'T':
|
||||
// disabled_rule_tags.insert(optarg);
|
||||
// break;
|
||||
// case 't':
|
||||
// enabled_rule_tags.insert(optarg);
|
||||
// break;
|
||||
// case 'U':
|
||||
// buffered_outputs = false;
|
||||
// buffered_cmdline = true;
|
||||
// break;
|
||||
// case 'u':
|
||||
// userspace = true;
|
||||
// break;
|
||||
// case 'v':
|
||||
// verbose = true;
|
||||
// break;
|
||||
// case 'V':
|
||||
// validate_rules_filenames.push_back(optarg);
|
||||
// break;
|
||||
// case 'w':
|
||||
// outfile = optarg;
|
||||
// break;
|
||||
// case '?':
|
||||
// result = EXIT_FAILURE;
|
||||
// goto exit;
|
||||
|
||||
case 0:
|
||||
if(string(long_options[long_index].name) == "version")
|
||||
{
|
||||
printf("Falco version: %s\n", FALCO_VERSION);
|
||||
printf("Driver version: %s\n", DRIVER_VERSION);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
else if (string(long_options[long_index].name) == "cri")
|
||||
{
|
||||
if(optarg != NULL)
|
||||
{
|
||||
cri_socket_path = optarg;
|
||||
}
|
||||
}
|
||||
else if (string(long_options[long_index].name) == "disable-cri-async")
|
||||
{
|
||||
cri_async = false;
|
||||
}
|
||||
else if (string(long_options[long_index].name) == "list")
|
||||
{
|
||||
list_flds = true;
|
||||
if(optarg != NULL)
|
||||
{
|
||||
list_flds_source = optarg;
|
||||
}
|
||||
}
|
||||
else if (string(long_options[long_index].name) == "stats-interval")
|
||||
{
|
||||
stats_interval = atoi(optarg);
|
||||
}
|
||||
else if (string(long_options[long_index].name) == "support")
|
||||
{
|
||||
print_support = true;
|
||||
}
|
||||
else if (string(long_options[long_index].name) == "disable-source")
|
||||
{
|
||||
if(optarg != NULL)
|
||||
{
|
||||
disable_sources.insert(optarg);
|
||||
}
|
||||
}
|
||||
else if (string(long_options[long_index].name)== "alternate-lua-dir")
|
||||
{
|
||||
if(optarg != NULL)
|
||||
{
|
||||
alternate_lua_dir = optarg;
|
||||
if (alternate_lua_dir.back() != '/') {
|
||||
alternate_lua_dir += '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
// case 0:
|
||||
// if(string(long_options[long_index].name) == "version")
|
||||
// {
|
||||
// printf("Falco version: %s\n", FALCO_VERSION);
|
||||
// printf("Driver version: %s\n", DRIVER_VERSION);
|
||||
// return EXIT_SUCCESS;
|
||||
// }
|
||||
// else if (string(long_options[long_index].name) == "cri")
|
||||
// {
|
||||
// if(optarg != NULL)
|
||||
// {
|
||||
// cri_socket_path = optarg;
|
||||
// }
|
||||
// }
|
||||
// else if (string(long_options[long_index].name) == "disable-cri-async")
|
||||
// {
|
||||
// cri_async = false;
|
||||
// }
|
||||
// else if (string(long_options[long_index].name) == "list")
|
||||
// {
|
||||
// list_flds = true;
|
||||
// if(optarg != NULL)
|
||||
// {
|
||||
// list_flds_source = optarg;
|
||||
// }
|
||||
// }
|
||||
// else if (string(long_options[long_index].name) == "stats-interval")
|
||||
// {
|
||||
// stats_interval = atoi(optarg);
|
||||
// }
|
||||
// else if (string(long_options[long_index].name) == "support")
|
||||
// {
|
||||
// print_support = true;
|
||||
// }
|
||||
// else if (string(long_options[long_index].name) == "disable-source")
|
||||
// {
|
||||
// if(optarg != NULL)
|
||||
// {
|
||||
// disable_sources.insert(optarg);
|
||||
// }
|
||||
// }
|
||||
// else if (string(long_options[long_index].name)== "alternate-lua-dir")
|
||||
// {
|
||||
// if(optarg != NULL)
|
||||
// {
|
||||
// alternate_lua_dir = optarg;
|
||||
// if (alternate_lua_dir.back() != '/') {
|
||||
// alternate_lua_dir += '/';
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
// }
|
||||
inspector = new sinsp();
|
||||
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));
|
||||
}
|
||||
|
||||
for(char **arg = argv; *arg; arg++)
|
||||
{
|
||||
if(cmdline.size() > 0)
|
||||
{
|
||||
cmdline += " ";
|
||||
}
|
||||
cmdline += *arg;
|
||||
}
|
||||
// for(char **arg = argv; *arg; arg++)
|
||||
// {
|
||||
// if(cmdline.size() > 0)
|
||||
// {
|
||||
// cmdline += " ";
|
||||
// }
|
||||
// cmdline += *arg;
|
||||
// }
|
||||
|
||||
support["version"] = FALCO_VERSION;
|
||||
support["system_info"]["sysname"] = sysinfo.sysname;
|
||||
@@ -972,7 +967,6 @@ int falco_init(int argc, char **argv)
|
||||
|
||||
outputs->init(config.m_json_output,
|
||||
config.m_json_include_output_property,
|
||||
config.m_output_timeout,
|
||||
config.m_notifications_rate, config.m_notifications_max_burst,
|
||||
config.m_buffered_outputs,
|
||||
config.m_time_format_iso_8601,
|
||||
@@ -1182,8 +1176,8 @@ int falco_init(int argc, char **argv)
|
||||
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
|
||||
}
|
||||
open_f(inspector);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
rethrow_exception(current_exception());
|
||||
}
|
||||
@@ -1292,7 +1286,7 @@ int falco_init(int argc, char **argv)
|
||||
|
||||
if(!trace_filename.empty() && !trace_is_scap)
|
||||
{
|
||||
#ifndef MINIMAL_BUILD
|
||||
#ifndef MINIMAL_BUILD
|
||||
read_k8s_audit_trace_file(engine,
|
||||
outputs,
|
||||
trace_filename);
|
||||
@@ -1379,13 +1373,23 @@ exit:
|
||||
//
|
||||
// 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
|
||||
// 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;
|
||||
optind = 1;
|
||||
|
||||
@@ -24,7 +24,6 @@ limitations under the License.
|
||||
|
||||
#include "formats.h"
|
||||
#include "logger.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
#include "outputs_file.h"
|
||||
#include "outputs_program.h"
|
||||
@@ -52,26 +51,18 @@ falco_outputs::~falco_outputs()
|
||||
{
|
||||
if(m_initialized)
|
||||
{
|
||||
this->stop_worker();
|
||||
for(auto o : m_outputs)
|
||||
for(auto it = m_outputs.cbegin(); it != m_outputs.cend(); ++it)
|
||||
{
|
||||
delete o;
|
||||
(*it)->cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void falco_outputs::init(bool json_output,
|
||||
bool json_include_output_property,
|
||||
uint32_t timeout,
|
||||
uint32_t rate, uint32_t max_burst, bool buffered,
|
||||
bool time_format_iso_8601, std::string hostname)
|
||||
bool json_include_output_property,
|
||||
uint32_t rate, uint32_t max_burst, bool buffered,
|
||||
bool time_format_iso_8601, string hostname)
|
||||
{
|
||||
// Cannot be initialized more than one time.
|
||||
if(m_initialized)
|
||||
{
|
||||
throw falco_exception("falco_outputs already initialized");
|
||||
}
|
||||
|
||||
m_json_output = json_output;
|
||||
|
||||
// Note that falco_formats is already initialized by the engine,
|
||||
@@ -80,29 +71,17 @@ void falco_outputs::init(bool json_output,
|
||||
falco_formats::s_json_output = json_output;
|
||||
falco_formats::s_json_include_output_property = json_include_output_property;
|
||||
|
||||
m_timeout = std::chrono::milliseconds(timeout);
|
||||
|
||||
m_notifications_tb.init(rate, max_burst);
|
||||
|
||||
m_buffered = buffered;
|
||||
m_time_format_iso_8601 = time_format_iso_8601;
|
||||
m_hostname = hostname;
|
||||
|
||||
m_worker_thread = std::thread(&falco_outputs::worker, this);
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
// This function has to be called after init() since some configuration settings
|
||||
// need to be passed to the output plugins. Then, although the worker has started,
|
||||
// the worker is still on hold, waiting for a message.
|
||||
// Thus it is still safe to call add_output() before any message has been enqueued.
|
||||
void falco_outputs::add_output(falco::outputs::config oc)
|
||||
{
|
||||
if(!m_initialized)
|
||||
{
|
||||
throw falco_exception("cannot add output: falco_outputs not initialized yet");
|
||||
}
|
||||
|
||||
falco::outputs::abstract_output *oo;
|
||||
|
||||
@@ -150,12 +129,6 @@ void falco_outputs::handle_event(gen_event *evt, string &rule, string &source,
|
||||
return;
|
||||
}
|
||||
|
||||
falco_outputs::ctrl_msg cmsg = {};
|
||||
cmsg.ts = evt->get_ts();
|
||||
cmsg.priority = priority;
|
||||
cmsg.source = source;
|
||||
cmsg.rule = rule;
|
||||
|
||||
string sformat;
|
||||
if(source == "syscall")
|
||||
{
|
||||
@@ -190,38 +163,35 @@ void falco_outputs::handle_event(gen_event *evt, string &rule, string &source,
|
||||
sformat += " " + format;
|
||||
}
|
||||
|
||||
cmsg.msg = falco_formats::format_event(evt, rule, source, falco_common::priority_names[priority], sformat);
|
||||
cmsg.fields = falco_formats::resolve_tokens(evt, source, sformat);
|
||||
string msg;
|
||||
msg = falco_formats::format_event(evt, rule, source, falco_common::priority_names[priority], sformat);
|
||||
|
||||
cmsg.type = ctrl_msg_type::CTRL_MSG_OUTPUT;
|
||||
m_queue.push(cmsg);
|
||||
for(auto it = m_outputs.cbegin(); it != m_outputs.cend(); ++it)
|
||||
{
|
||||
(*it)->output_event(evt, rule, source, priority, sformat, msg);
|
||||
}
|
||||
}
|
||||
|
||||
void falco_outputs::handle_msg(uint64_t ts,
|
||||
void falco_outputs::handle_msg(uint64_t now,
|
||||
falco_common::priority_type priority,
|
||||
std::string &msg,
|
||||
std::string &rule,
|
||||
std::map<std::string, std::string> &output_fields)
|
||||
{
|
||||
falco_outputs::ctrl_msg cmsg = {};
|
||||
cmsg.ts = ts;
|
||||
cmsg.priority = priority;
|
||||
cmsg.source = "internal";
|
||||
cmsg.rule = rule;
|
||||
cmsg.fields = output_fields;
|
||||
std::string full_msg;
|
||||
|
||||
if(m_json_output)
|
||||
{
|
||||
nlohmann::json jmsg;
|
||||
|
||||
// Convert the time-as-nanoseconds to a more json-friendly ISO8601.
|
||||
time_t evttime = ts / 1000000000;
|
||||
time_t evttime = now / 1000000000;
|
||||
char time_sec[20]; // sizeof "YYYY-MM-DDTHH:MM:SS"
|
||||
char time_ns[12]; // sizeof ".sssssssssZ"
|
||||
string iso8601evttime;
|
||||
|
||||
strftime(time_sec, sizeof(time_sec), "%FT%T", gmtime(&evttime));
|
||||
snprintf(time_ns, sizeof(time_ns), ".%09luZ", ts % 1000000000);
|
||||
snprintf(time_ns, sizeof(time_ns), ".%09luZ", now % 1000000000);
|
||||
iso8601evttime = time_sec;
|
||||
iso8601evttime += time_ns;
|
||||
|
||||
@@ -231,15 +201,15 @@ void falco_outputs::handle_msg(uint64_t ts,
|
||||
jmsg["time"] = iso8601evttime;
|
||||
jmsg["output_fields"] = output_fields;
|
||||
|
||||
cmsg.msg = jmsg.dump();
|
||||
full_msg = jmsg.dump();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string timestr;
|
||||
bool first = true;
|
||||
|
||||
sinsp_utils::ts_to_string(ts, ×tr, false, true);
|
||||
cmsg.msg = timestr + ": " + falco_common::priority_names[priority] + " " + msg + " (";
|
||||
sinsp_utils::ts_to_string(now, ×tr, false, true);
|
||||
full_msg = timestr + ": " + falco_common::priority_names[priority] + " " + msg + " (";
|
||||
for(auto &pair : output_fields)
|
||||
{
|
||||
if(first)
|
||||
@@ -248,95 +218,23 @@ void falco_outputs::handle_msg(uint64_t ts,
|
||||
}
|
||||
else
|
||||
{
|
||||
cmsg.msg += " ";
|
||||
full_msg += " ";
|
||||
}
|
||||
cmsg.msg += pair.first + "=" + pair.second;
|
||||
full_msg += pair.first + "=" + pair.second;
|
||||
}
|
||||
cmsg.msg += ")";
|
||||
full_msg += ")";
|
||||
}
|
||||
|
||||
cmsg.type = ctrl_msg_type::CTRL_MSG_OUTPUT;
|
||||
m_queue.push(cmsg);
|
||||
}
|
||||
|
||||
void falco_outputs::cleanup_outputs()
|
||||
{
|
||||
this->push(falco_outputs::ctrl_msg_type::CTRL_MSG_CLEANUP);
|
||||
for(auto it = m_outputs.cbegin(); it != m_outputs.cend(); ++it)
|
||||
{
|
||||
(*it)->output_msg(priority, full_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void falco_outputs::reopen_outputs()
|
||||
{
|
||||
this->push(falco_outputs::ctrl_msg_type::CTRL_MSG_REOPEN);
|
||||
}
|
||||
|
||||
void falco_outputs::stop_worker()
|
||||
{
|
||||
watchdog<void *> wd;
|
||||
wd.start([&](void *) -> void {
|
||||
falco_logger::log(LOG_NOTICE, "output channels still blocked, discarding all remaining notifications\n");
|
||||
m_queue.clear();
|
||||
this->push(falco_outputs::ctrl_msg_type::CTRL_MSG_STOP);
|
||||
});
|
||||
wd.set_timeout(m_timeout, nullptr);
|
||||
|
||||
this->push(falco_outputs::ctrl_msg_type::CTRL_MSG_STOP);
|
||||
if(m_worker_thread.joinable())
|
||||
for(auto it = m_outputs.cbegin(); it != m_outputs.cend(); ++it)
|
||||
{
|
||||
m_worker_thread.join();
|
||||
(*it)->reopen();
|
||||
}
|
||||
}
|
||||
|
||||
inline void falco_outputs::push(ctrl_msg_type cmt)
|
||||
{
|
||||
falco_outputs::ctrl_msg cmsg = {};
|
||||
cmsg.type = cmt;
|
||||
m_queue.push(cmsg);
|
||||
}
|
||||
|
||||
// todo(leogr,leodido): this function is not supposed to throw exceptions, and with "noexcept",
|
||||
// the program is terminated if that occurs. Although that's the wanted behavior,
|
||||
// we still need to improve the error reporting since some inner functions can throw exceptions.
|
||||
void falco_outputs::worker() noexcept
|
||||
{
|
||||
watchdog<std::string> wd;
|
||||
wd.start([&](std::string payload) -> void {
|
||||
falco_logger::log(LOG_CRIT, "\"" + payload + "\" output timeout, all output channels are blocked\n");
|
||||
});
|
||||
|
||||
auto timeout = m_timeout;
|
||||
|
||||
falco_outputs::ctrl_msg cmsg;
|
||||
do
|
||||
{
|
||||
// Block until a message becomes available.
|
||||
m_queue.pop(cmsg);
|
||||
|
||||
for(const auto o : m_outputs)
|
||||
{
|
||||
wd.set_timeout(timeout, o->get_name());
|
||||
try
|
||||
{
|
||||
switch(cmsg.type)
|
||||
{
|
||||
case ctrl_msg_type::CTRL_MSG_OUTPUT:
|
||||
o->output(&cmsg);
|
||||
break;
|
||||
case ctrl_msg_type::CTRL_MSG_CLEANUP:
|
||||
case ctrl_msg_type::CTRL_MSG_STOP:
|
||||
o->cleanup();
|
||||
break;
|
||||
case ctrl_msg_type::CTRL_MSG_REOPEN:
|
||||
o->reopen();
|
||||
break;
|
||||
default:
|
||||
falco_logger::log(LOG_DEBUG, "Outputs worker received an unknown message type\n");
|
||||
}
|
||||
}
|
||||
catch(const exception &e)
|
||||
{
|
||||
falco_logger::log(LOG_ERR, o->get_name() + ": " + string(e.what()) + "\n");
|
||||
}
|
||||
}
|
||||
wd.cancel_timeout();
|
||||
} while(cmsg.type != ctrl_msg_type::CTRL_MSG_STOP);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ limitations under the License.
|
||||
#include "token_bucket.h"
|
||||
#include "falco_engine.h"
|
||||
#include "outputs.h"
|
||||
#include "tbb/concurrent_queue.h"
|
||||
|
||||
//
|
||||
// This class acts as the primary interface between a program and the
|
||||
@@ -40,25 +39,25 @@ public:
|
||||
|
||||
void init(bool json_output,
|
||||
bool json_include_output_property,
|
||||
uint32_t timeout,
|
||||
uint32_t rate, uint32_t max_burst, bool buffered,
|
||||
bool time_format_iso_8601, std::string hostname);
|
||||
|
||||
void add_output(falco::outputs::config oc);
|
||||
|
||||
// Format then send the event to all configured outputs (`evt` is an event that has matched some rule).
|
||||
//
|
||||
// evt is an event that has matched some rule. Pass the event
|
||||
// to all configured outputs.
|
||||
//
|
||||
void handle_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format);
|
||||
|
||||
// Format then send a generic message to all outputs. Not necessarily associated with any event.
|
||||
// Send a generic message to all outputs. Not necessarily associated with any event.
|
||||
void handle_msg(uint64_t now,
|
||||
falco_common::priority_type priority,
|
||||
std::string &msg,
|
||||
std::string &rule,
|
||||
std::map<std::string, std::string> &output_fields);
|
||||
|
||||
void cleanup_outputs();
|
||||
|
||||
void reopen_outputs();
|
||||
|
||||
private:
|
||||
@@ -72,28 +71,5 @@ private:
|
||||
bool m_buffered;
|
||||
bool m_json_output;
|
||||
bool m_time_format_iso_8601;
|
||||
std::chrono::milliseconds m_timeout;
|
||||
std::string m_hostname;
|
||||
|
||||
enum ctrl_msg_type
|
||||
{
|
||||
CTRL_MSG_STOP = 0,
|
||||
CTRL_MSG_OUTPUT = 1,
|
||||
CTRL_MSG_CLEANUP = 2,
|
||||
CTRL_MSG_REOPEN = 3,
|
||||
};
|
||||
|
||||
struct ctrl_msg : falco::outputs::message
|
||||
{
|
||||
ctrl_msg_type type;
|
||||
};
|
||||
|
||||
typedef tbb::concurrent_bounded_queue<ctrl_msg> falco_outputs_cbq;
|
||||
|
||||
falco_outputs_cbq m_queue;
|
||||
|
||||
std::thread m_worker_thread;
|
||||
inline void push(ctrl_msg_type cmt);
|
||||
void worker() noexcept;
|
||||
void stop_worker();
|
||||
};
|
||||
|
||||
@@ -37,21 +37,6 @@ struct config
|
||||
std::map<std::string, std::string> options;
|
||||
};
|
||||
|
||||
//
|
||||
// The message to be outputted. It can either refer to:
|
||||
// - an event that has matched some rule,
|
||||
// - or a generic message (e.g., a drop alert).
|
||||
//
|
||||
struct message
|
||||
{
|
||||
uint64_t ts;
|
||||
falco_common::priority_type priority;
|
||||
std::string msg;
|
||||
std::string rule;
|
||||
std::string source;
|
||||
map<std::string, std::string> fields;
|
||||
};
|
||||
|
||||
//
|
||||
// This class acts as the primary interface for implementing
|
||||
// a Falco output class.
|
||||
@@ -60,8 +45,6 @@ struct message
|
||||
class abstract_output
|
||||
{
|
||||
public:
|
||||
virtual ~abstract_output() {}
|
||||
|
||||
void init(config oc, bool buffered, std::string hostname)
|
||||
{
|
||||
m_oc = oc;
|
||||
@@ -69,19 +52,15 @@ public:
|
||||
m_hostname = hostname;
|
||||
}
|
||||
|
||||
// Return the output's name as per its configuration.
|
||||
const std::string get_name() const
|
||||
{
|
||||
return m_oc.name;
|
||||
}
|
||||
// Output an event that has matched some rule.
|
||||
virtual void output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg) = 0;
|
||||
|
||||
// Output a message.
|
||||
virtual void output(const message *msg) = 0;
|
||||
// Output a generic message. Not necessarily associated with any event.
|
||||
virtual void output_msg(falco_common::priority_type priority, std::string &msg) = 0;
|
||||
|
||||
// Possibly close the output and open it again.
|
||||
virtual void reopen() {}
|
||||
|
||||
// Possibly flush the output.
|
||||
virtual void cleanup() {}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -31,10 +31,16 @@ void falco::outputs::output_file::open_file()
|
||||
}
|
||||
}
|
||||
|
||||
void falco::outputs::output_file::output(const message *msg)
|
||||
void falco::outputs::output_file::output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg)
|
||||
{
|
||||
output_msg(priority, msg);
|
||||
}
|
||||
|
||||
void falco::outputs::output_file::output_msg(falco_common::priority_type priority, std::string &msg)
|
||||
{
|
||||
open_file();
|
||||
m_outfile << msg->msg + "\n";
|
||||
m_outfile << msg + "\n";
|
||||
|
||||
if(m_oc.options["keep_alive"] != "true")
|
||||
{
|
||||
|
||||
@@ -27,7 +27,10 @@ namespace outputs
|
||||
|
||||
class output_file : public abstract_output
|
||||
{
|
||||
void output(const message *msg);
|
||||
void output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg);
|
||||
|
||||
void output_msg(falco_common::priority_type priority, std::string &msg);
|
||||
|
||||
void cleanup();
|
||||
|
||||
|
||||
@@ -21,41 +21,44 @@ limitations under the License.
|
||||
#include "formats.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
void falco::outputs::output_grpc::output(const message *msg)
|
||||
void falco::outputs::output_grpc::output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format,
|
||||
std::string &msg)
|
||||
{
|
||||
falco::outputs::response grpc_res;
|
||||
|
||||
// time
|
||||
auto timestamp = grpc_res.mutable_time();
|
||||
*timestamp = google::protobuf::util::TimeUtil::NanosecondsToTimestamp(msg->ts);
|
||||
*timestamp = google::protobuf::util::TimeUtil::NanosecondsToTimestamp(evt->get_ts());
|
||||
|
||||
// rule
|
||||
auto r = grpc_res.mutable_rule();
|
||||
*r = msg->rule;
|
||||
*r = rule;
|
||||
|
||||
// source
|
||||
falco::schema::source s = falco::schema::source::SYSCALL;
|
||||
if(!falco::schema::source_Parse(msg->source, &s))
|
||||
if(!falco::schema::source_Parse(source, &s))
|
||||
{
|
||||
throw falco_exception("Unknown source passed to output_grpc::output()");
|
||||
throw falco_exception("Unknown source passed to output_grpc::output_event()");
|
||||
}
|
||||
grpc_res.set_source(s);
|
||||
|
||||
// priority
|
||||
falco::schema::priority p = falco::schema::priority::EMERGENCY;
|
||||
if(!falco::schema::priority_Parse(falco_common::priority_names[msg->priority], &p))
|
||||
if(!falco::schema::priority_Parse(falco_common::priority_names[priority], &p))
|
||||
{
|
||||
throw falco_exception("Unknown priority passed to output_grpc::output()");
|
||||
throw falco_exception("Unknown priority passed to output_grpc::output_event()");
|
||||
}
|
||||
grpc_res.set_priority(p);
|
||||
|
||||
// output
|
||||
auto output = grpc_res.mutable_output();
|
||||
*output = msg->msg;
|
||||
*output = msg;
|
||||
|
||||
// output fields
|
||||
auto &fields = *grpc_res.mutable_output_fields();
|
||||
for(const auto &kv : msg->fields)
|
||||
auto resolvedTkns = falco_formats::resolve_tokens(evt, source, format);
|
||||
for(const auto &kv : resolvedTkns)
|
||||
{
|
||||
fields[kv.first] = kv.second;
|
||||
}
|
||||
@@ -65,4 +68,9 @@ void falco::outputs::output_grpc::output(const message *msg)
|
||||
*host = m_hostname;
|
||||
|
||||
falco::grpc::queue::get().push(grpc_res);
|
||||
}
|
||||
|
||||
void falco::outputs::output_grpc::output_msg(falco_common::priority_type priority, std::string &msg)
|
||||
{
|
||||
// todo(fntlnz, leodido, leogr) > gRPC does not support subscribing to dropped events yet
|
||||
}
|
||||
@@ -25,7 +25,10 @@ namespace outputs
|
||||
|
||||
class output_grpc : public abstract_output
|
||||
{
|
||||
void output(const message *msg);
|
||||
void output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg);
|
||||
|
||||
void output_msg(falco_common::priority_type priority, std::string &msg);
|
||||
};
|
||||
|
||||
} // namespace outputs
|
||||
|
||||
@@ -18,7 +18,13 @@ limitations under the License.
|
||||
#include "logger.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
void falco::outputs::output_http::output(const message *msg)
|
||||
void falco::outputs::output_http::output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg)
|
||||
{
|
||||
output_msg(priority, msg);
|
||||
}
|
||||
|
||||
void falco::outputs::output_http::output_msg(falco_common::priority_type priority, std::string &msg)
|
||||
{
|
||||
CURL *curl = NULL;
|
||||
CURLcode res = CURLE_FAILED_INIT;
|
||||
@@ -31,7 +37,7 @@ void falco::outputs::output_http::output(const message *msg)
|
||||
slist1 = curl_slist_append(slist1, "Content-Type: application/json");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, m_oc.options["url"].c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg->msg.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
@@ -25,7 +25,10 @@ namespace outputs
|
||||
|
||||
class output_http : public abstract_output
|
||||
{
|
||||
void output(const message *msg);
|
||||
void output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg);
|
||||
|
||||
void output_msg(falco_common::priority_type priority, std::string &msg);
|
||||
};
|
||||
|
||||
} // namespace outputs
|
||||
|
||||
@@ -31,11 +31,17 @@ void falco::outputs::output_program::open_pfile()
|
||||
}
|
||||
}
|
||||
|
||||
void falco::outputs::output_program::output(const message *msg)
|
||||
void falco::outputs::output_program::output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg)
|
||||
{
|
||||
output_msg(priority, msg);
|
||||
}
|
||||
|
||||
void falco::outputs::output_program::output_msg(falco_common::priority_type priority, std::string &msg)
|
||||
{
|
||||
open_pfile();
|
||||
|
||||
fprintf(m_pfile, "%s\n", msg->msg.c_str());
|
||||
fprintf(m_pfile, "%s\n", msg.c_str());
|
||||
|
||||
if(m_oc.options["keep_alive"] != "true")
|
||||
{
|
||||
|
||||
@@ -25,7 +25,10 @@ namespace outputs
|
||||
|
||||
class output_program : public abstract_output
|
||||
{
|
||||
void output(const message *msg);
|
||||
void output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg);
|
||||
|
||||
void output_msg(falco_common::priority_type priority, std::string &msg);
|
||||
|
||||
void cleanup();
|
||||
|
||||
|
||||
@@ -18,10 +18,16 @@ limitations under the License.
|
||||
#include <iostream>
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
void falco::outputs::output_stdout::output(const message *msg)
|
||||
void falco::outputs::output_stdout::output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg)
|
||||
{
|
||||
output_msg(priority, msg);
|
||||
}
|
||||
|
||||
void falco::outputs::output_stdout::output_msg(falco_common::priority_type priority, std::string &msg)
|
||||
{
|
||||
//
|
||||
// By default, the stdout stream is fully buffered or line buffered
|
||||
// By default, the stdout stream is fully buffered or line buffered
|
||||
// (if the stream can be determined to refer to an interactive device, e.g. in a TTY).
|
||||
// Just enable automatic flushing when unbuffered output is desired.
|
||||
// Note that it is set every time since other writings to the stdout can disable it.
|
||||
@@ -30,7 +36,7 @@ void falco::outputs::output_stdout::output(const message *msg)
|
||||
{
|
||||
std::cout << std::unitbuf;
|
||||
}
|
||||
std::cout << msg->msg + "\n";
|
||||
std::cout << msg + "\n";
|
||||
}
|
||||
|
||||
void falco::outputs::output_stdout::cleanup()
|
||||
|
||||
@@ -25,7 +25,10 @@ namespace outputs
|
||||
|
||||
class output_stdout : public abstract_output
|
||||
{
|
||||
void output(const message *msg);
|
||||
void output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg);
|
||||
|
||||
void output_msg(falco_common::priority_type priority, std::string &msg);
|
||||
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
@@ -18,8 +18,14 @@ limitations under the License.
|
||||
#include <syslog.h>
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
void falco::outputs::output_syslog::output(const message *msg)
|
||||
void falco::outputs::output_syslog::output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg)
|
||||
{
|
||||
output_msg(priority, msg);
|
||||
}
|
||||
|
||||
void falco::outputs::output_syslog::output_msg(falco_common::priority_type priority, std::string &msg)
|
||||
{
|
||||
// Syslog output should not have any trailing newline
|
||||
::syslog(msg->priority, "%s", msg->msg.c_str());
|
||||
::syslog(priority, "%s", msg.c_str());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@ namespace outputs
|
||||
|
||||
class output_syslog : public abstract_output
|
||||
{
|
||||
void output(const message *msg);
|
||||
void output_event(gen_event *evt, std::string &rule, std::string &source,
|
||||
falco_common::priority_type priority, std::string &format, std::string &msg);
|
||||
|
||||
void output_msg(falco_common::priority_type priority, std::string &msg);
|
||||
};
|
||||
|
||||
} // namespace outputs
|
||||
|
||||
@@ -57,7 +57,4 @@ enum source {
|
||||
k8s_audit = 1;
|
||||
K8s_audit = 1;
|
||||
K8S_audit = 1;
|
||||
INTERNAL = 2;
|
||||
internal = 2;
|
||||
Internal = 2;
|
||||
}
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
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 <chrono>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
|
||||
template<typename _T>
|
||||
class watchdog
|
||||
{
|
||||
public:
|
||||
watchdog():
|
||||
m_timeout(nullptr),
|
||||
m_is_running(false)
|
||||
{
|
||||
}
|
||||
|
||||
~watchdog()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void start(std::function<void(_T)> cb,
|
||||
std::chrono::milliseconds resolution = std::chrono::milliseconds(100))
|
||||
{
|
||||
stop();
|
||||
m_is_running.store(true, std::memory_order_release);
|
||||
m_thread = std::thread([this, cb, resolution]() {
|
||||
const auto no_deadline = time_point{};
|
||||
timeout_data curr;
|
||||
while(m_is_running.load(std::memory_order_acquire))
|
||||
{
|
||||
auto t = m_timeout.exchange(nullptr, std::memory_order_release);
|
||||
if(t)
|
||||
{
|
||||
curr = *t;
|
||||
delete t;
|
||||
}
|
||||
if(curr.deadline != no_deadline && curr.deadline < std::chrono::steady_clock::now())
|
||||
{
|
||||
cb(curr.payload);
|
||||
curr.deadline = no_deadline;
|
||||
}
|
||||
std::this_thread::sleep_for(resolution);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if(m_is_running.load(std::memory_order_acquire))
|
||||
{
|
||||
m_is_running.store(false, std::memory_order_release);
|
||||
if(m_thread.joinable())
|
||||
{
|
||||
m_thread.join();
|
||||
}
|
||||
delete m_timeout.exchange(nullptr, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
inline void set_timeout(std::chrono::milliseconds timeout, _T payload) noexcept
|
||||
{
|
||||
delete m_timeout.exchange(new timeout_data{std::chrono::steady_clock::now() + timeout, payload}, std::memory_order_release);
|
||||
}
|
||||
|
||||
inline void cancel_timeout() noexcept
|
||||
{
|
||||
delete m_timeout.exchange(new timeout_data, std::memory_order_release);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::chrono::time_point<std::chrono::steady_clock> time_point;
|
||||
struct timeout_data
|
||||
{
|
||||
time_point deadline;
|
||||
_T payload;
|
||||
};
|
||||
std::atomic<timeout_data *> m_timeout;
|
||||
std::atomic<bool> m_is_running;
|
||||
std::thread m_thread;
|
||||
};
|
||||
Reference in New Issue
Block a user