Skip to content

Commit

Permalink
Remote cfg support for the WAF
Browse files Browse the repository at this point in the history
  • Loading branch information
cataphract committed Apr 26, 2024
1 parent fa18a81 commit 6087843
Show file tree
Hide file tree
Showing 12 changed files with 1,213 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ if(NGINX_DATADOG_ASM_ENABLED)
src/security/collection.cpp
src/security/context.cpp
src/security/ddwaf_obj.cpp
src/security/library.cpp)
src/security/library.cpp
src/security/waf_remote_cfg.cpp)
target_compile_definitions(ngx_http_datadog_module PRIVATE WITH_WAF)
endif()

Expand Down
7 changes: 6 additions & 1 deletion src/ngx_http_datadog_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "ngx_logger.h"
#ifdef WITH_WAF
#include "security/library.h"
#include "security/waf_remote_cfg.h"
#endif
#include "string_util.h"
#include "tracing_library.h"
Expand Down Expand Up @@ -571,7 +572,11 @@ static ngx_int_t datadog_init_worker(ngx_cycle_t *cycle) noexcept try {
std::shared_ptr<dd::Logger> logger = std::make_shared<NgxLogger>();
#ifdef WITH_WAF
try {
security::Library::initialize_security_library(*main_conf);
std::optional<security::ddwaf_owned_map> initial_waf_cfg =
security::Library::initialize_security_library(*main_conf);
if (initial_waf_cfg) {
security::register_default_config(std::move(*initial_waf_cfg), logger);
}
} catch (const std::exception &e) {
ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
"Initialising security library failed: %s", e.what());
Expand Down
17 changes: 17 additions & 0 deletions src/ngx_logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,21 @@ void NgxLogger::log_error(std::string_view message) {
std::lock_guard<std::mutex> lock(mutex_);
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "datadog: %V", &ngx_message);
}

void NgxLogger::log_debug(const LogFunc& write) {
std::ostringstream stream;
write(stream);
log_debug(stream.str());
}

void NgxLogger::log_debug(std::string_view message) {
#if NGX_DEBUG
const ngx_str_t ngx_message = to_ngx_str(message);

std::lock_guard<std::mutex> lock(mutex_);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "datadog: %V",
&ngx_message);
#endif
}

} // namespace datadog::nginx
4 changes: 4 additions & 0 deletions src/ngx_logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class NgxLogger : public dd::Logger {
void log_error(const dd::Error& error) override;

void log_error(std::string_view message) override;

void log_debug(const LogFunc& write) override;

void log_debug(std::string_view message) override;
};

} // namespace nginx
Expand Down
25 changes: 25 additions & 0 deletions src/security/library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,31 @@ void Library::set_handle(OwnedDdwafHandle &&handle) {
ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, "WAF configuration updated");
}

bool Library::update_ruleset(const ddwaf_map_obj &spec) {
std::shared_ptr<OwnedDdwafHandle> cur_h{get_handle_uncond()};

if (!cur_h) {
throw std::runtime_error{"no handle to update"};
}

libddwaf_ddwaf_owned_obj<ddwaf_map_obj> diag{{}};
auto new_h = OwnedDdwafHandle{ddwaf_update(cur_h->get(), &spec, &diag.get())};
if (!new_h.get()) {
throw std::runtime_error{"call to ddwaf_update failed:" +
ddwaf_diagnostics_to_str(diag.get())};
}

if (ngx_cycle->log->log_level & NGX_LOG_DEBUG_HTTP) {
std::string diag_str = ddwaf_diagnostics_to_str(diag.get());
ngx_str_t str = ngx_stringv(diag_str);
ngx_log_debug(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"ddwaf_update succeeded: %V", &str);
}

set_handle(std::move(new_h));
return true;
}

std::shared_ptr<OwnedDdwafHandle> Library::get_handle() {
if (active_.load(std::memory_order_relaxed)) {
return get_handle_uncond();
Expand Down
2 changes: 2 additions & 0 deletions src/security/library.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class Library {
static std::optional<ddwaf_owned_map> initialize_security_library(
const datadog_main_conf_t &conf);

static bool update_ruleset(const ddwaf_map_obj &spec);

// returns the handle if active, otherwise an empty shared_ptr
static std::shared_ptr<OwnedDdwafHandle> get_handle();

Expand Down
Loading

0 comments on commit 6087843

Please sign in to comment.