Feb 10 2025 dev (#255)

* sync code

* sync code

* code sync

* code sync

---------

Co-authored-by: Ned Wright <nedwright@proton.me>
Co-authored-by: Daniel Eisenberg <danielei@checkpoint.com>
This commit is contained in:
Daniel-Eisenberg
2025-02-12 10:56:44 +02:00
committed by GitHub
parent 81433bac25
commit 4ddcd2462a
75 changed files with 1540 additions and 258 deletions

View File

@@ -31,6 +31,7 @@
#include <stdarg.h>
#include <boost/range/iterator_range.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
#include "nginx_attachment_config.h"
@@ -260,6 +261,22 @@ public:
);
}
const char* ignored_headers_env = getenv("SAAS_IGNORED_UPSTREAM_HEADERS");
if (ignored_headers_env) {
string ignored_headers_str = ignored_headers_env;
ignored_headers_str = NGEN::Strings::trim(ignored_headers_str);
if (!ignored_headers_str.empty()) {
dbgInfo(D_HTTP_MANAGER)
<< "Ignoring SAAS_IGNORED_UPSTREAM_HEADERS environment variable: "
<< ignored_headers_str;
vector<string> ignored_headers_vec;
boost::split(ignored_headers_vec, ignored_headers_str, boost::is_any_of(";"));
for (const string &header : ignored_headers_vec) ignored_headers.insert(header);
}
}
dbgInfo(D_NGINX_ATTACHMENT) << "Successfully initialized NGINX Attachment";
}
@@ -1034,7 +1051,11 @@ private:
case ChunkType::REQUEST_START:
return handleStartTransaction(data, opaque);
case ChunkType::REQUEST_HEADER:
return handleMultiModifiableChunks(NginxParser::parseRequestHeaders(data), "request header", true);
return handleMultiModifiableChunks(
NginxParser::parseRequestHeaders(data, ignored_headers),
"request header",
true
);
case ChunkType::REQUEST_BODY:
return handleModifiableChunk(NginxParser::parseRequestBody(data), "request body", true);
case ChunkType::REQUEST_END: {
@@ -1814,6 +1835,7 @@ private:
HttpAttachmentConfig attachment_config;
I_MainLoop::RoutineID attachment_routine_id = 0;
bool traffic_indicator = false;
unordered_set<string> ignored_headers;
// Interfaces
I_Socket *i_socket = nullptr;

View File

@@ -240,6 +240,21 @@ HttpAttachmentConfig::setRetriesForVerdict()
"Max retries for verdict"
));
conf_data.setNumericalValue("hold_verdict_retries", getAttachmentConf<uint>(
3,
"agent.retriesForHoldVerdict.nginxModule",
"HTTP manager",
"Retries for hold verdict"
));
conf_data.setNumericalValue("hold_verdict_polling_time", getAttachmentConf<uint>(
1,
"agent.holdVerdictPollingInterval.nginxModule",
"HTTP manager",
"Hold verdict polling interval seconds"
));
conf_data.setNumericalValue("body_size_trigger", getAttachmentConf<uint>(
200000,
"agent.reqBodySizeTrigger.nginxModule",

View File

@@ -19,12 +19,15 @@
#include "config.h"
#include "virtual_modifiers.h"
#include "agent_core_utilities.h"
using namespace std;
using namespace boost::uuids;
USE_DEBUG_FLAG(D_HTTP_MANAGER);
extern bool is_keep_alive_ctx;
NginxAttachmentOpaque::NginxAttachmentOpaque(HttpTransactionData _transaction_data)
:
TableOpaqueSerialize<NginxAttachmentOpaque>(this),
@@ -119,3 +122,47 @@ NginxAttachmentOpaque::setSavedData(const string &name, const string &data, EnvK
saved_data[name] = data;
ctx.registerValue(name, data, log_ctx);
}
bool
NginxAttachmentOpaque::setKeepAliveCtx(const string &hdr_key, const string &hdr_val)
{
if (!is_keep_alive_ctx) return false;
static pair<string, string> keep_alive_hdr;
static bool keep_alive_hdr_initialized = false;
if (keep_alive_hdr_initialized) {
if (!keep_alive_hdr.first.empty() && hdr_key == keep_alive_hdr.first && hdr_val == keep_alive_hdr.second) {
dbgTrace(D_HTTP_MANAGER) << "Registering keep alive context";
ctx.registerValue("keep_alive_request_ctx", true);
return true;
}
return false;
}
const char* saas_keep_alive_hdr_name_env = getenv("SAAS_KEEP_ALIVE_HDR_NAME");
if (saas_keep_alive_hdr_name_env) {
keep_alive_hdr.first = NGEN::Strings::trim(saas_keep_alive_hdr_name_env);
dbgInfo(D_HTTP_MANAGER) << "Using SAAS_KEEP_ALIVE_HDR_NAME environment variable: " << keep_alive_hdr.first;
}
if (!keep_alive_hdr.first.empty()) {
const char* saas_keep_alive_hdr_value_env = getenv("SAAS_KEEP_ALIVE_HDR_VALUE");
if (saas_keep_alive_hdr_value_env) {
keep_alive_hdr.second = NGEN::Strings::trim(saas_keep_alive_hdr_value_env);
dbgInfo(D_HTTP_MANAGER)
<< "Using SAAS_KEEP_ALIVE_HDR_VALUE environment variable: "
<< keep_alive_hdr.second;
}
if (!keep_alive_hdr.second.empty() && (hdr_key == keep_alive_hdr.first && hdr_val == keep_alive_hdr.second)) {
dbgTrace(D_HTTP_MANAGER) << "Registering keep alive context";
ctx.registerValue("keep_alive_request_ctx", true);
keep_alive_hdr_initialized = true;
return true;
}
}
keep_alive_hdr_initialized = true;
return false;
}

View File

@@ -85,6 +85,7 @@ public:
EnvKeyAttr::LogSection log_ctx = EnvKeyAttr::LogSection::NONE
);
void setApplicationState(const ApplicationState &app_state) { application_state = app_state; }
bool setKeepAliveCtx(const std::string &hdr_key, const std::string &hdr_val);
private:
CompressionStream *response_compression_stream;

View File

@@ -29,6 +29,7 @@ USE_DEBUG_FLAG(D_NGINX_ATTACHMENT_PARSER);
Buffer NginxParser::tenant_header_key = Buffer();
static const Buffer proxy_ip_header_key("X-Forwarded-For", 15, Buffer::MemoryType::STATIC);
static const Buffer source_ip("sourceip", 8, Buffer::MemoryType::STATIC);
bool is_keep_alive_ctx = getenv("SAAS_KEEP_ALIVE_HDR_NAME") != nullptr;
map<Buffer, CompressionType> NginxParser::content_encodings = {
{Buffer("identity"), CompressionType::NO_COMPRESSION},
@@ -177,22 +178,54 @@ getActivetenantAndProfile(const string &str, const string &deli = ",")
}
Maybe<vector<HttpHeader>>
NginxParser::parseRequestHeaders(const Buffer &data)
NginxParser::parseRequestHeaders(const Buffer &data, const unordered_set<string> &ignored_headers)
{
auto parsed_headers = genHeaders(data);
if (!parsed_headers.ok()) return parsed_headers.passErr();
auto maybe_parsed_headers = genHeaders(data);
if (!maybe_parsed_headers.ok()) return maybe_parsed_headers.passErr();
auto i_transaction_table = Singleton::Consume<I_TableSpecific<SessionID>>::by<NginxAttachment>();
auto parsed_headers = maybe_parsed_headers.unpack();
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
for (const HttpHeader &header : *parsed_headers) {
if (is_keep_alive_ctx || !ignored_headers.empty()) {
bool is_last_header_removed = false;
parsed_headers.erase(
remove_if(
parsed_headers.begin(),
parsed_headers.end(),
[&opaque, &is_last_header_removed, &ignored_headers](const HttpHeader &header)
{
string hdr_key = static_cast<string>(header.getKey());
string hdr_val = static_cast<string>(header.getValue());
if (
opaque.setKeepAliveCtx(hdr_key, hdr_val)
|| ignored_headers.find(hdr_key) != ignored_headers.end()
) {
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Header was removed from headers list: " << hdr_key;
if (header.isLastHeader()) {
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Last header was removed from headers list";
is_last_header_removed = true;
}
return true;
}
return false;
}
),
parsed_headers.end()
);
if (is_last_header_removed) {
dbgTrace(D_NGINX_ATTACHMENT_PARSER) << "Adjusting last header flag";
if (!parsed_headers.empty()) parsed_headers.back().setIsLastHeader();
}
}
for (const HttpHeader &header : parsed_headers) {
auto source_identifiers = getConfigurationWithDefault<UsersAllIdentifiersConfig>(
UsersAllIdentifiersConfig(),
"rulebase",
"usersIdentifiers"
);
source_identifiers.parseRequestHeaders(header);
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
opaque.addToSavedData(
HttpTransactionData::req_headers,
static_cast<string>(header.getKey()) + ": " + static_cast<string>(header.getValue()) + "\r\n"

View File

@@ -28,7 +28,10 @@ public:
static Maybe<HttpTransactionData> parseStartTrasaction(const Buffer &data);
static Maybe<ResponseCode> parseResponseCode(const Buffer &data);
static Maybe<uint64_t> parseContentLength(const Buffer &data);
static Maybe<std::vector<HttpHeader>> parseRequestHeaders(const Buffer &data);
static Maybe<std::vector<HttpHeader>> parseRequestHeaders(
const Buffer &data,
const std::unordered_set<std::string> &ignored_headers
);
static Maybe<std::vector<HttpHeader>> parseResponseHeaders(const Buffer &data);
static Maybe<HttpBody> parseRequestBody(const Buffer &data);
static Maybe<HttpBody> parseResponseBody(const Buffer &raw_response_body, CompressionStream *compression_stream);