From 6e2de3ce930bb3f1e873448f07f82c449a22e897 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Mon, 16 Sep 2019 05:31:33 +0000 Subject: [PATCH] new(userspace/falco): read all the gRPC server configs Signed-off-by: Leonardo Di Donato --- userspace/falco/configuration.cpp | 84 ++++++++++++++++++------------- userspace/falco/configuration.h | 57 +++++++++++---------- 2 files changed, 80 insertions(+), 61 deletions(-) diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index 842ae9c9..f809dbd3 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -29,20 +29,20 @@ limitations under the License. using namespace std; -falco_configuration::falco_configuration() - : m_buffered_outputs(false), - m_time_format_iso_8601(false), - m_webserver_enabled(false), - m_webserver_listen_port(8765), - m_webserver_k8s_audit_endpoint("/k8s_audit"), - m_webserver_ssl_enabled(false), - m_config(NULL) +falco_configuration::falco_configuration(): + m_buffered_outputs(false), + m_time_format_iso_8601(false), + m_webserver_enabled(false), + m_webserver_listen_port(8765), + m_webserver_k8s_audit_endpoint("/k8s_audit"), + m_webserver_ssl_enabled(false), + m_config(NULL) { } falco_configuration::~falco_configuration() { - if (m_config) + if(m_config) { delete m_config; } @@ -84,11 +84,11 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio falco_outputs::output_config file_output; file_output.name = "file"; - if (m_config->get_scalar("file_output", "enabled", false)) + if(m_config->get_scalar("file_output", "enabled", false)) { string filename, keep_alive; filename = m_config->get_scalar("file_output", "filename", ""); - if (filename == string("")) + if(filename == string("")) { throw invalid_argument("Error reading config file (" + m_config_file + "): file output enabled but no filename in configuration block"); } @@ -102,25 +102,25 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio falco_outputs::output_config stdout_output; stdout_output.name = "stdout"; - if (m_config->get_scalar("stdout_output", "enabled", false)) + if(m_config->get_scalar("stdout_output", "enabled", false)) { m_outputs.push_back(stdout_output); } falco_outputs::output_config syslog_output; syslog_output.name = "syslog"; - if (m_config->get_scalar("syslog_output", "enabled", false)) + if(m_config->get_scalar("syslog_output", "enabled", false)) { m_outputs.push_back(syslog_output); } falco_outputs::output_config program_output; program_output.name = "program"; - if (m_config->get_scalar("program_output", "enabled", false)) + if(m_config->get_scalar("program_output", "enabled", false)) { string program, keep_alive; program = m_config->get_scalar("program_output", "program", ""); - if (program == string("")) + if(program == string("")) { throw sinsp_exception("Error reading config file (" + m_config_file + "): program output enabled but no program in configuration block"); } @@ -134,12 +134,12 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio falco_outputs::output_config http_output; http_output.name = "http"; - if (m_config->get_scalar("http_output", "enabled", false)) + if(m_config->get_scalar("http_output", "enabled", false)) { string url; url = m_config->get_scalar("http_output", "url", ""); - if (url == string("")) + if(url == string("")) { throw sinsp_exception("Error reading config file (" + m_config_file + "): http output enabled but no url in configuration block"); } @@ -148,15 +148,24 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio m_outputs.push_back(http_output); } + m_grpc_enabled = m_config->get_scalar("grpc", "enabled", false); + m_grpc_bind_address = m_config->get_scalar("grpc", "bind_address", "0.0.0.0:5060"); + m_grpc_threadiness = m_config->get_scalar("grpc", "threadiness", 8); + // todo(fntlnz,leodido) > chose correct paths + m_grpc_private_key = m_config->get_scalar("grpc", "private_key", ""); + m_grpc_cert_chain = m_config->get_scalar("grpc", "cert_chain", ""); + m_grpc_root_certs = m_config->get_scalar("grpc", "root_certs", ""); + falco_outputs::output_config grpc_output; grpc_output.name = "grpc"; - if(m_config->get_scalar("grpc_output", "enabled", false)) + // gRPC output is enabled only if gRPC server is enabled too + if(m_config->get_scalar("grpc_output", "enabled", false) && m_grpc_enabled) { - // todo > grpc_output is enabled but we should constraint it to the grpc server being enabled too + // todo > m_outputs.push_back(grpc_output); } - if (m_outputs.size() == 0) + if(m_outputs.size() == 0) { throw invalid_argument("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"); } @@ -171,7 +180,7 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio string priority = m_config->get_scalar("priority", "debug"); vector::iterator it; - auto comp = [priority] (string &s) { + auto comp = [priority](string &s) { return (strcasecmp(s.c_str(), priority.c_str()) == 0); }; @@ -179,7 +188,7 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio { throw invalid_argument("Unknown priority \"" + priority + "\"--must be one of emergency, alert, critical, error, warning, notice, informational, debug"); } - m_min_priority = (falco_common::priority_type) (it - falco_common::priority_names.begin()); + m_min_priority = (falco_common::priority_type)(it - falco_common::priority_names.begin()); m_buffered_outputs = m_config->get_scalar("buffered_outputs", false); m_time_format_iso_8601 = m_config->get_scalar("time_format_iso_8601", false); @@ -191,7 +200,7 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio m_webserver_listen_port = m_config->get_scalar("webserver", "listen_port", 8765); m_webserver_k8s_audit_endpoint = m_config->get_scalar("webserver", "k8s_audit_endpoint", "/k8s_audit"); m_webserver_ssl_enabled = m_config->get_scalar("webserver", "ssl_enabled", false); - m_webserver_ssl_certificate = m_config->get_scalar("webserver", "ssl_certificate","/etc/falco/falco.pem"); + m_webserver_ssl_certificate = m_config->get_scalar("webserver", "ssl_certificate", "/etc/falco/falco.pem"); std::list syscall_event_drop_acts; m_config->get_sequence(syscall_event_drop_acts, "syscall_event_drops", "actions"); @@ -202,15 +211,15 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio { m_syscall_evt_drop_actions.insert(syscall_evt_drop_mgr::ACT_IGNORE); } - else if (act == "log") + else if(act == "log") { m_syscall_evt_drop_actions.insert(syscall_evt_drop_mgr::ACT_LOG); } - else if (act == "alert") + else if(act == "alert") { m_syscall_evt_drop_actions.insert(syscall_evt_drop_mgr::ACT_ALERT); } - else if (act == "exit") + else if(act == "exit") { m_syscall_evt_drop_actions.insert(syscall_evt_drop_mgr::ACT_EXIT); } @@ -258,7 +267,7 @@ void falco_configuration::read_rules_file_directory(const string &path, listd_name; @@ -281,7 +290,7 @@ void falco_configuration::read_rules_file_directory(const string &path, list &parts) +static bool split(const string &str, char delim, pair &parts) { size_t pos; - if ((pos = str.find_first_of(delim)) == string::npos) { + if((pos = str.find_first_of(delim)) == string::npos) + { return false; } parts.first = str.substr(0, pos); @@ -318,16 +328,20 @@ void falco_configuration::init_cmdline_options(list &cmdline_options) void falco_configuration::set_cmdline_option(const string &opt) { - pair keyval; - pair subkey; + pair keyval; + pair subkey; - if (! split(opt, '=', keyval)) { + if(!split(opt, '=', keyval)) + { throw invalid_argument("Error parsing config option \"" + opt + "\". Must be of the form key=val or key.subkey=val"); } - if (split(keyval.first, '.', subkey)) { + if(split(keyval.first, '.', subkey)) + { m_config->set_scalar(subkey.first, subkey.second, keyval.second); - } else { + } + else + { m_config->set_scalar(keyval.first, keyval.second); } } diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index 585aea1d..51cd3b65 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -45,12 +45,12 @@ public: { m_root = YAML::LoadFile(path); } - catch (const YAML::BadFile& ex) + catch(const YAML::BadFile& ex) { std::cerr << "Error reading config file (" + path + "): " + ex.what() + "\n"; throw; } - catch (const YAML::ParserException& ex) + catch(const YAML::ParserException& ex) { std::cerr << "Cannot read config file (" + path + "): " + ex.what() + "\n"; throw; @@ -66,11 +66,12 @@ public: try { auto node = m_root[key]; - if (node.IsDefined()) + if(node.IsDefined()) { return node.as(); } - } catch (const YAML::BadConversion& ex) + } + catch(const YAML::BadConversion& ex) { std::cerr << "Cannot read config file (" + m_path + "): wrong type at key " + key + "\n"; throw; @@ -83,10 +84,10 @@ public: * Set the top-level node identified by key to value */ template - void set_scalar(const std::string &key, const T& value) + void set_scalar(const std::string& key, const T& value) { auto node = m_root; - if (node.IsDefined()) + if(node.IsDefined()) { node[key] = value; } @@ -106,12 +107,12 @@ public: try { auto node = m_root[key][subkey]; - if (node.IsDefined()) + if(node.IsDefined()) { return node.as(); } } - catch (const YAML::BadConversion& ex) + catch(const YAML::BadConversion& ex) { std::cerr << "Cannot read config file (" + m_path + "): wrong type at key " + key + "\n"; throw; @@ -127,15 +128,15 @@ public: void set_scalar(const std::string& key, const std::string& subkey, const T& value) { auto node = m_root; - if (node.IsDefined()) + if(node.IsDefined()) { node[key][subkey] = value; } } // called with the last variadic arg (where the sequence is expected to be found) - template - void get_sequence_from_node(T& ret, const YAML::Node &node) + template + void get_sequence_from_node(T& ret, const YAML::Node& node) { if(node.IsDefined()) { @@ -154,25 +155,25 @@ public: } // called with the last variadic arg (where the sequence is expected to be found) - template + template void get_sequence(T& ret, const std::string& name) { return get_sequence_from_node(ret, m_root[name]); } // called with the last variadic arg (where the sequence is expected to be found) - template - void get_sequence(T& ret, const std::string& key, const std::string &subkey) + template + void get_sequence(T& ret, const std::string& key, const std::string& subkey) { try { auto node = m_root[key]; - if (node.IsDefined()) + if(node.IsDefined()) { return get_sequence_from_node(ret, node[subkey]); } } - catch (const YAML::BadConversion& ex) + catch(const YAML::BadConversion& ex) { std::cerr << "Cannot read config file (" + m_path + "): wrong type at key " + key + "\n"; throw; @@ -183,17 +184,16 @@ private: YAML::Node m_root; }; - class falco_configuration { - public: +public: falco_configuration(); virtual ~falco_configuration(); - void init(std::string conf_filename, std::list &cmdline_options); - void init(std::list &cmdline_options); + void init(std::string conf_filename, std::list& cmdline_options); + void init(std::list& cmdline_options); - static void read_rules_file_directory(const string &path, list &rules_filenames); + static void read_rules_file_directory(const string& path, list& rules_filenames); std::list m_rules_filenames; bool m_json_output; @@ -207,6 +207,13 @@ class falco_configuration bool m_buffered_outputs; bool m_time_format_iso_8601; + bool m_grpc_enabled; + int m_grpc_threadiness; + std::string m_grpc_bind_address; + std::string m_grpc_private_key; + std::string m_grpc_cert_chain; + std::string m_grpc_root_certs; + bool m_webserver_enabled; uint32_t m_webserver_listen_port; std::string m_webserver_k8s_audit_endpoint; @@ -219,9 +226,8 @@ class falco_configuration // Only used for testing bool m_syscall_evt_simulate_drops; - - private: - void init_cmdline_options(std::list &cmdline_options); +private: + void init_cmdline_options(std::list& cmdline_options); /** * Given a = specifier, set the appropriate option @@ -229,8 +235,7 @@ class falco_configuration * characters for nesting. Currently only 1- or 2- level keys * are supported and only scalar values are supported. */ - void set_cmdline_option(const std::string &spec); + void set_cmdline_option(const std::string& spec); yaml_configuration* m_config; }; -