Rename analyzer.log to analyzer.debug log; move to policy

The current analyzer.log is more useful for debugging than for
operational purposes. Hence this is disabled by default, moved to a
policy script, and the log is renamed to analyzer-debug.log.

Furthermore, logging of analyzer confirmations and disabling analyzers
are now enabled by default.
This commit is contained in:
Johanna Amann 2025-03-27 16:48:49 +00:00
parent 6183c5086b
commit c55e21da71
3 changed files with 41 additions and 37 deletions

View file

@ -1,3 +1,2 @@
@load ./main
@load ./dpd
@load ./logging

View file

@ -1,4 +1,5 @@
##! Disables analyzers if protocol violations occur.
##! Disables analyzers if protocol violations occur, and add service information
##! to connection log.
module DPD;
@ -27,6 +28,7 @@ redef record connection += {
service_violation: set[string] &default=set() &ordered;
};
## add confirmed protocol analyzers to conn.log service field
event analyzer_confirmation_info(atype: AllAnalyzers::Tag, info: AnalyzerConfirmationInfo) &priority=10
{
if ( ! is_protocol_analyzer(atype) && ! is_packet_analyzer(atype) )
@ -40,6 +42,7 @@ event analyzer_confirmation_info(atype: AllAnalyzers::Tag, info: AnalyzerConfirm
add c$service[analyzer];
}
## Remove failed analyzers from service field and add them to c$service_violation
event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) &priority=10
{
if ( ! is_protocol_analyzer(atype) && ! is_packet_analyzer(atype) )

View file

@ -1,218 +0,0 @@
##! Logging analyzer confirmations and violations into analyzer.log
@load base/frameworks/config
@load base/frameworks/logging
@load ./main
module Analyzer::Logging;
export {
## Add the analyzer logging stream identifier.
redef enum Log::ID += { LOG };
## A default logging policy hook for the stream.
global log_policy: Log::PolicyHook;
## The record type defining the columns to log in the analyzer logging stream.
type Info: record {
## Timestamp of confirmation or violation.
ts: time &log;
## What caused this log entry to be produced. This can
## currently be "violation" or "confirmation".
cause: string &log;
## The kind of analyzer involved. Currently "packet", "file"
## or "protocol".
analyzer_kind: string &log;
## The name of the analyzer as produced by :zeek:see:`Analyzer::name`
## for the analyzer's tag.
analyzer_name: string &log;
## Connection UID if available.
uid: string &log &optional;
## File UID if available.
fuid: string &log &optional;
## Connection identifier if available
id: conn_id &log &optional;
## Failure or violation reason, if available.
failure_reason: string &log &optional;
## Data causing failure or violation if available. Truncated
## to :zeek:see:`Analyzer::Logging::failure_data_max_size`.
failure_data: string &log &optional;
};
## Enable logging of analyzer violations and optionally confirmations
## when :zeek:see:`Analyzer::Logging::include_confirmations` is set.
option enable = T;
## Enable analyzer_confirmation. They are usually less interesting
## outside of development of analyzers or troubleshooting scenarios.
## Setting this option may also generated multiple log entries per
## connection, minimally one for each conn.log entry with a populated
## service field.
option include_confirmations = F;
## Enable tracking of analyzers getting disabled. This is mostly
## interesting for troubleshooting of analyzers in DPD scenarios.
## Setting this option may also generated multiple log entries per
## connection.
option include_disabling = F;
## If a violation contains information about the data causing it,
## include at most this many bytes of it in the log.
option failure_data_max_size = 40;
## Set of analyzers for which to not log confirmations or violations.
option ignore_analyzers: set[AllAnalyzers::Tag] = set();
}
event zeek_init() &priority=5
{
Log::create_stream(LOG, [$columns=Info, $path="analyzer", $policy=log_policy,
$event_groups=set("Analyzer::Logging")]);
local enable_handler = function(id: string, new_value: bool): bool {
if ( new_value )
Log::enable_stream(LOG);
else
Log::disable_stream(LOG);
return new_value;
};
Option::set_change_handler("Analyzer::Logging::enable", enable_handler);
local include_confirmations_handler = function(id: string, new_value: bool): bool {
if ( new_value )
enable_event_group("Analyzer::Logging::include_confirmations");
else
disable_event_group("Analyzer::Logging::include_confirmations");
return new_value;
};
Option::set_change_handler("Analyzer::Logging::include_confirmations",
include_confirmations_handler);
local include_disabling_handler = function(id: string, new_value: bool): bool {
if ( new_value )
enable_event_group("Analyzer::Logging::include_disabling");
else
disable_event_group("Analyzer::Logging::include_disabling");
return new_value;
};
Option::set_change_handler("Analyzer::Logging::include_disabling",
include_disabling_handler);
# Call the handlers directly with the current values to avoid config
# framework interactions like creating entries in config.log.
enable_handler("Analyzer::Logging::enable", Analyzer::Logging::enable);
include_confirmations_handler("Analyzer::Logging::include_confirmations",
Analyzer::Logging::include_confirmations);
include_disabling_handler("Analyzer::Logging::include_disabling",
Analyzer::Logging::include_disabling);
}
function analyzer_kind(atype: AllAnalyzers::Tag): string
{
if ( is_protocol_analyzer(atype) )
return "protocol";
else if ( is_packet_analyzer(atype) )
return "packet";
else if ( is_file_analyzer(atype) )
return "file";
Reporter::warning(fmt("Unknown kind of analyzer %s", atype));
return "unknown";
}
function populate_from_conn(rec: Info, c: connection)
{
rec$id = c$id;
rec$uid = c$uid;
}
function populate_from_file(rec: Info, f: fa_file)
{
rec$fuid = f$id;
# If the confirmation didn't have a connection, but the
# fa_file object has exactly one, use it.
if ( ! rec?$uid && f?$conns && |f$conns| == 1 )
{
for ( _, c in f$conns )
{
rec$id = c$id;
rec$uid = c$uid;
}
}
}
event analyzer_confirmation_info(atype: AllAnalyzers::Tag, info: AnalyzerConfirmationInfo) &group="Analyzer::Logging::include_confirmations"
{
if ( atype in ignore_analyzers )
return;
local rec = Info(
$ts=network_time(),
$cause="confirmation",
$analyzer_kind=analyzer_kind(atype),
$analyzer_name=Analyzer::name(atype),
);
if ( info?$c )
populate_from_conn(rec, info$c);
if ( info?$f )
populate_from_file(rec, info$f);
Log::write(LOG, rec);
}
event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) &priority=6
{
if ( atype in ignore_analyzers )
return;
local rec = Info(
$ts=network_time(),
$cause="violation",
$analyzer_kind=analyzer_kind(atype),
$analyzer_name=Analyzer::name(atype),
$failure_reason=info$reason,
);
if ( info?$c )
populate_from_conn(rec, info$c);
if ( info?$f )
populate_from_file(rec, info$f);
if ( info?$data )
{
if ( failure_data_max_size > 0 )
rec$failure_data = info$data[0:failure_data_max_size];
else
rec$failure_data = info$data;
}
Log::write(LOG, rec);
}
hook Analyzer::disabling_analyzer(c: connection, atype: AllAnalyzers::Tag, aid: count) &priority=-1000 &group="Analyzer::Logging::include_disabling"
{
if ( atype in ignore_analyzers )
return;
local rec = Info(
$ts=network_time(),
$cause="disabled",
$analyzer_kind=analyzer_kind(atype),
$analyzer_name=Analyzer::name(atype),
);
populate_from_conn(rec, c);
Log::write(LOG, rec);
}