From 4fcd44e73a2cd826b5a44918a02bdea9e086f218 Mon Sep 17 00:00:00 2001 From: Michael Ducy Date: Wed, 23 Jan 2019 22:21:37 -0600 Subject: [PATCH] Allow SSL for k8s audit endpoint (#471) * Allow SSL for k8s audit endpoint Allow enabling SSL for the Kubernetes audit log web server. This required adding two new configuration options: webserver.ssl_enabled and webserver.ssl_certificate. To enable SSL add the below to the webserver section of the falco.yaml config: webserver: enabled: true listen_port: 8765s k8s_audit_endpoint: /k8s_audit ssl_enabled: true ssl_certificate: /etc/falco/falco.pem Note that the port number has an s appended to indicate SSL for the port which is how civetweb expects SSL ports be denoted. We could change this to dynamically add the s if ssl_enabled: true. The ssl_certificate is a combination SSL Certificate and corresponding key contained in a single file. You can generate a key/cert as follows: $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem $ cat certificate.pem key.pem > falco.pem $ sudo cp falco.pem /etc/falco/falco.pem fix ssl option handling * Add notes on how to create ssl certificate Add notes on how to create the ssl certificate to the config comments. --- .gitignore | 1 + falco.yaml | 11 ++++++++++- userspace/falco/configuration.cpp | 5 ++++- userspace/falco/configuration.h | 2 ++ userspace/falco/falco.cpp | 3 ++- userspace/falco/webserver.cpp | 12 +++++++++++- 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 38092a6a..b28c617f 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ docker/event-generator/mysqld docker/event-generator/httpd docker/event-generator/sha1sum docker/event-generator/vipw +.vscode/* \ No newline at end of file diff --git a/falco.yaml b/falco.yaml index 986f6de2..c01a8f0d 100644 --- a/falco.yaml +++ b/falco.yaml @@ -104,11 +104,20 @@ stdout_output: # Falco contains an embedded webserver that can be used to accept K8s # Audit Events. These config options control the behavior of that # webserver. (By default, the webserver is disabled). -# enabled: false +# +# The ssl_certificate is a combination SSL Certificate and corresponding +# key contained in a single file. You can generate a key/cert as follows: +# +# $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem +# $ cat certificate.pem key.pem > falco.pem +# $ sudo cp falco.pem /etc/falco/falco.pem + webserver: enabled: true listen_port: 8765 k8s_audit_endpoint: /k8s_audit + ssl_enabled: false + ssl_certificate: /etc/falco/falco.pem # Possible additional things you might want to do with program output: # - send to a slack webhook: diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index 1894946c..a778caaf 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -34,6 +34,7 @@ falco_configuration::falco_configuration() m_webserver_enabled(false), m_webserver_listen_port(8765), m_webserver_k8s_audit_endpoint("/k8s_audit"), + m_webserver_ssl_enabled(false), m_config(NULL) { } @@ -162,7 +163,9 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio m_webserver_enabled = m_config->get_scalar("webserver", "enabled", false); m_webserver_listen_port = m_config->get_scalar("webserver", "listen_port", 8765); - m_webserver_k8s_audit_endpoint = m_config->get_scalar("websever", "k8s_audit_endpoint", "/k8s_audit"); + 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"); } void falco_configuration::read_rules_file_directory(const string &path, list &rules_filenames) diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index 05a0f430..0fb6700a 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -182,6 +182,8 @@ class falco_configuration bool m_webserver_enabled; uint32_t m_webserver_listen_port; std::string m_webserver_k8s_audit_endpoint; + bool m_webserver_ssl_enabled; + std::string m_webserver_ssl_certificate; private: void init_cmdline_options(std::list &cmdline_options); diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index ddeb85f7..178fee0d 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -1024,7 +1024,8 @@ int falco_init(int argc, char **argv) if(trace_filename.empty() && config.m_webserver_enabled) { - falco_logger::log(LOG_INFO, "Starting internal webserver, listening on port " + to_string(config.m_webserver_listen_port) + "\n"); + std::string ssl_option = (config.m_webserver_ssl_enabled ? " (SSL)" : ""); + falco_logger::log(LOG_INFO, "Starting internal webserver, listening on port " + to_string(config.m_webserver_listen_port) + ssl_option + "\n"); webserver.init(&config, engine, outputs); webserver.start(); } diff --git a/userspace/falco/webserver.cpp b/userspace/falco/webserver.cpp index 9eadaa52..2ffd6d61 100644 --- a/userspace/falco/webserver.cpp +++ b/userspace/falco/webserver.cpp @@ -189,10 +189,20 @@ void falco_webserver::start() } std::vector cpp_options = { - "listening_ports", to_string(m_config->m_webserver_listen_port), "num_threads", to_string(1) }; + if (m_config->m_webserver_ssl_enabled) + { + cpp_options.push_back("listening_ports"); + cpp_options.push_back(to_string(m_config->m_webserver_listen_port) + "s"); + cpp_options.push_back("ssl_certificate"); + cpp_options.push_back(m_config->m_webserver_ssl_certificate); + } else { + cpp_options.push_back("listening_ports"); + cpp_options.push_back(to_string(m_config->m_webserver_listen_port)); + } + try { m_server = make_unique(cpp_options); }