flow/output: make exception policy logging optional

Task #7623
pull/13837/head
Juliana Fajardini 2 months ago committed by Victor Julien
parent 6186996ba7
commit 681cfc95d5

@ -227,12 +227,22 @@ Flow Event
When an Exception Policy is triggered, this will be indicated in the flow log When an Exception Policy is triggered, this will be indicated in the flow log
event for the associated flow, also indicating which target triggered that, and event for the associated flow, also indicating which target triggered that, and
what policy was applied. If no exception policy is triggered, that field won't what policy was applied. **This is a configurable option, disabled by default.**
be present in the logs. If no exception policy is triggered, that field won't be present in the logs.
Note that this is true even if the policy is applied only to certain packets from Note that this is true even if the policy is applied only to certain packets from
a flow. a flow.
To enable logging of the triggered exception policies for a given flow, enable
the yaml option::
output:
- eve-log:
enabled: yes
types:
- flow:
exception-policy: true
.. Note:: As exception policies targetting ``flow memcap`` and ``defrag .. Note:: As exception policies targetting ``flow memcap`` and ``defrag
memcap`` act on a per-packet level, these are not shown in the flow logs. memcap`` act on a per-packet level, these are not shown in the flow logs.
Ticket #7884 (https://redmine.openinfosecfoundation.org/issues/7884) Ticket #7884 (https://redmine.openinfosecfoundation.org/issues/7884)

@ -52,6 +52,103 @@
#include "flow-storage.h" #include "flow-storage.h"
#include "util-exception-policy.h" #include "util-exception-policy.h"
typedef struct LogFlowCtx_ {
bool log_exception_policies;
OutputJsonCtx *eve_ctx;
} LogFlowCtx;
typedef struct LogFlowLogThread_ {
LogFlowCtx *flowlog_ctx;
OutputJsonThreadCtx *output_ctx;
} LogFlowLogThread;
static void OutputFlowLogDeInitCtxSub(OutputCtx *output_ctx)
{
LogFlowCtx *flow_ctx = output_ctx->data;
SCFree(flow_ctx);
SCFree(output_ctx);
}
static void JsonFlowLogParseConfig(ConfNode *conf, LogFlowCtx *flow_ctx)
{
/* by default, don't log exception policies */
flow_ctx->log_exception_policies = false;
if (conf != NULL) {
if (ConfNodeChildValueIsTrue(conf, "exception-policy")) {
flow_ctx->log_exception_policies = true;
}
}
SCLogDebug("Exception policy logging for flow %s",
flow_ctx->log_exception_policies ? "enabled" : "disabled");
}
static OutputInitResult OutputFlowLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
{
OutputInitResult result = { NULL, false };
OutputJsonCtx *ojc = parent_ctx->data;
LogFlowCtx *flow_ctx = SCCalloc(1, sizeof(LogFlowCtx));
if (unlikely(flow_ctx == NULL)) {
return result;
}
OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
if (unlikely(output_ctx == NULL)) {
SCFree(flow_ctx);
return result;
}
flow_ctx->eve_ctx = ojc;
output_ctx->data = flow_ctx;
output_ctx->DeInit = OutputFlowLogDeInitCtxSub;
JsonFlowLogParseConfig(conf, flow_ctx);
result.ctx = output_ctx;
result.ok = true;
return result;
}
static TmEcode JsonFlowLogThreadInit(ThreadVars *tv, const void *initdata, void **data)
{
LogFlowLogThread *thread = SCCalloc(1, sizeof(LogFlowLogThread));
if (unlikely(thread == NULL)) {
return TM_ECODE_FAILED;
}
if (initdata == NULL) {
SCLogDebug("Error getting context for EveLogFlow. \"initdata\" argument NULL");
goto error_exit;
}
thread->flowlog_ctx = ((OutputCtx *)initdata)->data;
thread->output_ctx = CreateEveThreadCtx(tv, thread->flowlog_ctx->eve_ctx);
if (!thread->output_ctx) {
goto error_exit;
}
*data = (void *)thread;
return TM_ECODE_OK;
error_exit:
SCFree(thread);
return TM_ECODE_FAILED;
}
static TmEcode JsonFlowLogThreadDeInit(ThreadVars *tv, void *data)
{
LogFlowLogThread *thread = (LogFlowLogThread *)data;
if (thread == NULL) {
return TM_ECODE_FAILED;
}
FreeEveThreadCtx(thread->output_ctx);
SCFree(thread);
return TM_ECODE_OK;
}
static JsonBuilder *CreateEveHeaderFromFlow(const Flow *f) static JsonBuilder *CreateEveHeaderFromFlow(const Flow *f)
{ {
char timebuf[64]; char timebuf[64];
@ -275,7 +372,7 @@ static void EveExceptionPolicyLog(JsonBuilder *js, uint16_t flag)
} }
/* Eve format logging */ /* Eve format logging */
static void EveFlowLogJSON(OutputJsonThreadCtx *aft, JsonBuilder *jb, Flow *f) static void EveFlowLogJSON(LogFlowLogThread *ft, JsonBuilder *jb, Flow *f)
{ {
EveAddAppProto(f, jb); EveAddAppProto(f, jb);
jb_open_object(jb, "flow"); jb_open_object(jb, "flow");
@ -337,7 +434,7 @@ static void EveFlowLogJSON(OutputJsonThreadCtx *aft, JsonBuilder *jb, Flow *f)
} else if (f->flags & FLOW_ACTION_PASS) { } else if (f->flags & FLOW_ACTION_PASS) {
JB_SET_STRING(jb, "action", "pass"); JB_SET_STRING(jb, "action", "pass");
} }
if (f->applied_exception_policy != 0) { if (f->applied_exception_policy != 0 && ft->flowlog_ctx->log_exception_policies) {
jb_open_array(jb, "exception_policy"); jb_open_array(jb, "exception_policy");
EveExceptionPolicyLog(jb, f->applied_exception_policy); EveExceptionPolicyLog(jb, f->applied_exception_policy);
jb_close(jb); /* close array */ jb_close(jb); /* close array */
@ -346,7 +443,7 @@ static void EveFlowLogJSON(OutputJsonThreadCtx *aft, JsonBuilder *jb, Flow *f)
/* Close flow. */ /* Close flow. */
jb_close(jb); jb_close(jb);
EveAddCommonOptions(&aft->ctx->cfg, NULL, f, jb, LOG_DIR_FLOW); EveAddCommonOptions(&ft->output_ctx->ctx->cfg, NULL, f, jb, LOG_DIR_FLOW);
/* TCP */ /* TCP */
if (f->proto == IPPROTO_TCP) { if (f->proto == IPPROTO_TCP) {
@ -397,10 +494,7 @@ static void EveFlowLogJSON(OutputJsonThreadCtx *aft, JsonBuilder *jb, Flow *f)
static int JsonFlowLogger(ThreadVars *tv, void *thread_data, Flow *f) static int JsonFlowLogger(ThreadVars *tv, void *thread_data, Flow *f)
{ {
SCEnter(); SCEnter();
OutputJsonThreadCtx *thread = thread_data; LogFlowLogThread *thread = thread_data;
/* reset */
MemBufferReset(thread->buffer);
JsonBuilder *jb = CreateEveHeaderFromFlow(f); JsonBuilder *jb = CreateEveHeaderFromFlow(f);
if (unlikely(jb == NULL)) { if (unlikely(jb == NULL)) {
@ -409,7 +503,7 @@ static int JsonFlowLogger(ThreadVars *tv, void *thread_data, Flow *f)
EveFlowLogJSON(thread, jb, f); EveFlowLogJSON(thread, jb, f);
OutputJsonBuilderBuffer(jb, thread); OutputJsonBuilderBuffer(jb, thread->output_ctx);
jb_free(jb); jb_free(jb);
SCReturnInt(TM_ECODE_OK); SCReturnInt(TM_ECODE_OK);
@ -419,5 +513,6 @@ void JsonFlowLogRegister (void)
{ {
/* register as child of eve-log */ /* register as child of eve-log */
OutputRegisterFlowSubModule(LOGGER_JSON_FLOW, "eve-log", "JsonFlowLog", "eve-log.flow", OutputRegisterFlowSubModule(LOGGER_JSON_FLOW, "eve-log", "JsonFlowLog", "eve-log.flow",
OutputJsonLogInitSub, JsonFlowLogger, JsonLogThreadInit, JsonLogThreadDeinit, NULL); OutputFlowLogInitSub, JsonFlowLogger, JsonFlowLogThreadInit, JsonFlowLogThreadDeInit,
NULL);
} }

@ -323,7 +323,9 @@ outputs:
threads: no # per thread stats threads: no # per thread stats
deltas: no # include delta values deltas: no # include delta values
# bi-directional flows # bi-directional flows
- flow - flow:
# Log exception policies triggered by this flow. Disabled by default.
# exception-policy: false
# uni-directional flows # uni-directional flows
#- netflow #- netflow

Loading…
Cancel
Save