mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-29 16:17:32 +00:00
commit
4eef8c9647
@ -84,6 +84,19 @@ ExternalProject_Add(b64
|
|||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
INSTALL_COMMAND "")
|
INSTALL_COMMAND "")
|
||||||
|
|
||||||
|
|
||||||
|
set(YAMLCPP_SRC "${PROJECT_BINARY_DIR}/yamlcpp-prefix/src/yamlcpp")
|
||||||
|
message(STATUS "Using bundled yaml-cpp in '${YAMLCPP_SRC}'")
|
||||||
|
set(YAMLCPP_LIB "${YAMLCPP_SRC}/libyaml-cpp.a")
|
||||||
|
set(YAMLCPP_INCLUDE_DIR "${YAMLCPP_SRC}/include")
|
||||||
|
# Once the next version of yaml-cpp is released (first version not requiring
|
||||||
|
# boost), we can switch to that and no longer pull from github.
|
||||||
|
ExternalProject_Add(yamlcpp
|
||||||
|
GIT_REPOSITORY "https://github.com/jbeder/yaml-cpp.git"
|
||||||
|
GIT_TAG "7d2873ce9f2202ea21b6a8c5ecbc9fe38032c229"
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
INSTALL_COMMAND "")
|
||||||
|
|
||||||
set(OPENSSL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl")
|
set(OPENSSL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl")
|
||||||
set(OPENSSL_INSTALL_DIR "${OPENSSL_BUNDLE_DIR}/target")
|
set(OPENSSL_INSTALL_DIR "${OPENSSL_BUNDLE_DIR}/target")
|
||||||
set(OPENSSL_LIBRARY_SSL "${OPENSSL_INSTALL_DIR}/lib/libssl.a")
|
set(OPENSSL_LIBRARY_SSL "${OPENSSL_INSTALL_DIR}/lib/libssl.a")
|
||||||
|
16
digwatch.yaml
Normal file
16
digwatch.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
rules_file: /etc/digwatch.conf
|
||||||
|
|
||||||
|
# Priority level
|
||||||
|
# Any rule with priority lower than this level will be discarded
|
||||||
|
priority_level: warning
|
||||||
|
|
||||||
|
syslog_output:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
file_output:
|
||||||
|
enabled: true
|
||||||
|
filename: "bla.bla"
|
||||||
|
|
||||||
|
stdout_output:
|
||||||
|
enabled: false
|
||||||
|
|
@ -5,12 +5,16 @@ include_directories(${PROJECT_SOURCE_DIR}/../sysdig/userspace/libscap)
|
|||||||
include_directories(${PROJECT_SOURCE_DIR}/../sysdig/userspace/libsinsp)
|
include_directories(${PROJECT_SOURCE_DIR}/../sysdig/userspace/libsinsp)
|
||||||
include_directories("${PROJECT_BINARY_DIR}/userspace/digwatch")
|
include_directories("${PROJECT_BINARY_DIR}/userspace/digwatch")
|
||||||
include_directories("${CURL_INCLUDE_DIR}")
|
include_directories("${CURL_INCLUDE_DIR}")
|
||||||
|
include_directories("${YAMLCPP_INCLUDE_DIR}")
|
||||||
include_directories("${LPEG_SRC}")
|
include_directories("${LPEG_SRC}")
|
||||||
|
include_directories(${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include)
|
||||||
|
|
||||||
add_executable(digwatch formats.cpp fields.cpp rules.cpp syslog.cpp digwatch.cpp)
|
add_executable(digwatch configuration.cpp formats.cpp fields.cpp rules.cpp syslog.cpp digwatch.cpp)
|
||||||
|
|
||||||
target_link_libraries(digwatch sinsp)
|
target_link_libraries(digwatch sinsp)
|
||||||
target_link_libraries(digwatch "${LPEG_SRC}/lpeg.a")
|
target_link_libraries(digwatch
|
||||||
|
"${LPEG_SRC}/lpeg.a"
|
||||||
|
"${YAMLCPP_LIB}")
|
||||||
|
|
||||||
|
|
||||||
set(DIGWATCH_LUA_MAIN "rule_loader.lua")
|
set(DIGWATCH_LUA_MAIN "rule_loader.lua")
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#define DIGWATCH_VERSION "${DIGWATCH_VERSION}"
|
#define DIGWATCH_VERSION "${DIGWATCH_VERSION}"
|
||||||
|
|
||||||
#define DIGWATCH_LUA_DIR "/usr/share/digwatch/lua/"
|
#define DIGWATCH_LUA_DIR "/usr/share/digwatch/lua/"
|
||||||
|
#define DIGWATCH_SOURCE_DIR "${PROJECT_SOURCE_DIR}"
|
||||||
|
#define DIGWATCH_SOURCE_CONF_FILE "${PROJECT_SOURCE_DIR}/digwatch.yaml"
|
||||||
|
#define DIGWATCH_INSTALL_CONF_FILE "/etc/digwatch.yaml"
|
||||||
#define DIGWATCH_SOURCE_LUA_DIR "${PROJECT_SOURCE_DIR}/userspace/digwatch/lua/"
|
#define DIGWATCH_SOURCE_LUA_DIR "${PROJECT_SOURCE_DIR}/userspace/digwatch/lua/"
|
||||||
|
|
||||||
|
|
||||||
|
56
userspace/digwatch/configuration.cpp
Normal file
56
userspace/digwatch/configuration.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "configuration.h"
|
||||||
|
#include "config_digwatch.h"
|
||||||
|
#include "sinsp.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
// If we don't have a configuration file, we just use stdout output and all other defaults
|
||||||
|
void digwatch_configuration::init()
|
||||||
|
{
|
||||||
|
output_config stdout_output;
|
||||||
|
stdout_output.name = "stdout";
|
||||||
|
m_outputs.push_back(stdout_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void digwatch_configuration::init(string conf_filename)
|
||||||
|
{
|
||||||
|
string m_config_file = conf_filename;
|
||||||
|
m_config = new yaml_configuration(m_config_file);
|
||||||
|
|
||||||
|
m_rules_file = m_config->get_scalar<string>("rules_file", "/etc/digwatch.conf");
|
||||||
|
m_priority_level = m_config->get_scalar<string>("priority_level", "warning");
|
||||||
|
|
||||||
|
output_config file_output;
|
||||||
|
file_output.name = "file";
|
||||||
|
if (m_config->get_scalar<bool>("file_output", "enabled", false))
|
||||||
|
{
|
||||||
|
string filename;
|
||||||
|
filename = m_config->get_scalar<string>("file_output", "filename", "");
|
||||||
|
if (filename == string(""))
|
||||||
|
{
|
||||||
|
throw sinsp_exception("Error reading config file (" + m_config_file + "): file output enabled but no filename in configuration block");
|
||||||
|
}
|
||||||
|
file_output.options["filename"] = filename;
|
||||||
|
m_outputs.push_back(file_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
output_config stdout_output;
|
||||||
|
stdout_output.name = "stdout";
|
||||||
|
if (m_config->get_scalar<bool>("stdout_output", "enabled", false))
|
||||||
|
{
|
||||||
|
m_outputs.push_back(stdout_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
output_config syslog_output;
|
||||||
|
syslog_output.name = "syslog";
|
||||||
|
if (m_config->get_scalar<bool>("syslog_output", "enabled", false))
|
||||||
|
{
|
||||||
|
m_outputs.push_back(syslog_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_outputs.size() == 0)
|
||||||
|
{
|
||||||
|
throw sinsp_exception("Error reading config file (" + m_config_file + "): No outputs configured. Please configure at least one output file output enabled but no filename in configuration block");
|
||||||
|
}
|
||||||
|
}
|
103
userspace/digwatch/configuration.h
Normal file
103
userspace/digwatch/configuration.h
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
struct output_config
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::map<std::string, std::string> options;
|
||||||
|
};
|
||||||
|
|
||||||
|
class yaml_configuration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string m_path;
|
||||||
|
yaml_configuration(const std::string& path)
|
||||||
|
{
|
||||||
|
m_path = path;
|
||||||
|
YAML::Node config;
|
||||||
|
std::vector<output_config> outputs;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_root = YAML::LoadFile(path);
|
||||||
|
}
|
||||||
|
catch (const YAML::BadFile& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Error reading config file (" + path + "): " + ex.what() + "\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const YAML::ParserException& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot read config file (" + path + "): " + ex.what() + "\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a scalar value defined at the top level of the config
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
const T get_scalar(const std::string& key, const T& default_value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto node = m_root[key];
|
||||||
|
if (node.IsDefined())
|
||||||
|
{
|
||||||
|
return node.as<T>();
|
||||||
|
}
|
||||||
|
} catch (const YAML::BadConversion& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot read config file (" + m_path + "): wrong type at key " + key + "\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a scalar value defined inside a 2 level nested structure like:
|
||||||
|
* file_output:
|
||||||
|
* enabled: true
|
||||||
|
* filename: output_file.txt
|
||||||
|
*
|
||||||
|
* get_scalar<bool>("file_output", "enabled", false)
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
const T get_scalar(const std::string& key, const std::string& subkey, const T& default_value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto node = m_root[key][subkey];
|
||||||
|
if (node.IsDefined())
|
||||||
|
{
|
||||||
|
return node.as<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const YAML::BadConversion& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot read config file (" + m_path + "): wrong type at key " + key + "\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
YAML::Node m_root;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class digwatch_configuration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init(std::string conf_filename);
|
||||||
|
void init();
|
||||||
|
std::string m_rules_file;
|
||||||
|
std::string m_priority_level;
|
||||||
|
std::vector<output_config> m_outputs;
|
||||||
|
private:
|
||||||
|
yaml_configuration* m_config;
|
||||||
|
};
|
||||||
|
|
@ -18,12 +18,14 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include <sinsp.h>
|
#include <sinsp.h>
|
||||||
#include <config_digwatch.h>
|
#include "config_digwatch.h"
|
||||||
|
#include "configuration.h"
|
||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
#include "formats.h"
|
#include "formats.h"
|
||||||
#include "fields.h"
|
#include "fields.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
static bool g_terminate = false;
|
static bool g_terminate = false;
|
||||||
|
|
||||||
@ -155,6 +157,8 @@ void add_lua_path(lua_State *ls, string path)
|
|||||||
lua_pop(ls, 1);
|
lua_pop(ls, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ARGUMENT PARSING AND PROGRAM SETUP
|
// ARGUMENT PARSING AND PROGRAM SETUP
|
||||||
//
|
//
|
||||||
@ -169,6 +173,7 @@ int digwatch_init(int argc, char **argv)
|
|||||||
string lua_main_filename;
|
string lua_main_filename;
|
||||||
string output_name = "stdout";
|
string output_name = "stdout";
|
||||||
string infile;
|
string infile;
|
||||||
|
string conf_filename;
|
||||||
string lua_dir = DIGWATCH_LUA_DIR;
|
string lua_dir = DIGWATCH_LUA_DIR;
|
||||||
lua_State* ls = NULL;
|
lua_State* ls = NULL;
|
||||||
|
|
||||||
@ -188,7 +193,7 @@ int digwatch_init(int argc, char **argv)
|
|||||||
// Parse the args
|
// Parse the args
|
||||||
//
|
//
|
||||||
while((op = getopt_long(argc, argv,
|
while((op = getopt_long(argc, argv,
|
||||||
"ho:r:",
|
"c:ho:R:",
|
||||||
long_options, &long_index)) != -1)
|
long_options, &long_index)) != -1)
|
||||||
{
|
{
|
||||||
switch(op)
|
switch(op)
|
||||||
@ -196,6 +201,9 @@ int digwatch_init(int argc, char **argv)
|
|||||||
case 'h':
|
case 'h':
|
||||||
usage();
|
usage();
|
||||||
goto exit;
|
goto exit;
|
||||||
|
case 'c':
|
||||||
|
conf_filename = optarg;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
valid = std::find(valid_output_names.begin(), valid_output_names.end(), optarg) != valid_output_names.end();
|
valid = std::find(valid_output_names.begin(), valid_output_names.end(), optarg) != valid_output_names.end();
|
||||||
if (!valid)
|
if (!valid)
|
||||||
@ -246,6 +254,50 @@ int digwatch_init(int argc, char **argv)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ifstream* conf_stream;
|
||||||
|
if (conf_filename.size())
|
||||||
|
{
|
||||||
|
conf_stream = new ifstream(conf_filename);
|
||||||
|
if (!conf_stream->good())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not find configuration file at %s \n", conf_filename.c_str());
|
||||||
|
result = EXIT_FAILURE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conf_stream = new ifstream(DIGWATCH_SOURCE_CONF_FILE);
|
||||||
|
if (conf_stream->good())
|
||||||
|
{
|
||||||
|
conf_filename = DIGWATCH_SOURCE_CONF_FILE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conf_stream = new ifstream(DIGWATCH_INSTALL_CONF_FILE);
|
||||||
|
if (conf_stream->good())
|
||||||
|
{
|
||||||
|
conf_filename = DIGWATCH_INSTALL_CONF_FILE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conf_filename = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
digwatch_configuration config;
|
||||||
|
if (conf_filename.size())
|
||||||
|
{
|
||||||
|
cout << "Using configuration file " + conf_filename + "\n";
|
||||||
|
config.init(conf_filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cout << "No configuration file found, proceeding with defaults\n";
|
||||||
|
config.init();
|
||||||
|
}
|
||||||
|
|
||||||
if(signal(SIGINT, signal_callback) == SIG_ERR)
|
if(signal(SIGINT, signal_callback) == SIG_ERR)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "An error occurred while setting SIGINT signal handler.\n");
|
fprintf(stderr, "An error occurred while setting SIGINT signal handler.\n");
|
||||||
@ -275,7 +327,6 @@ int digwatch_init(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialize Lua interpreter
|
// Initialize Lua interpreter
|
||||||
ls = lua_open();
|
ls = lua_open();
|
||||||
luaL_openlibs(ls);
|
luaL_openlibs(ls);
|
||||||
@ -327,7 +378,7 @@ int digwatch_init(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
printf("Exception\n");
|
printf("Error, exiting.\n");
|
||||||
result = EXIT_FAILURE;
|
result = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user