mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Add pcap_file option to supervised nodes.
This allows to start Supervised nodes with a pcap_file argument rather than interface. This is based on changes from @J-Gras.
This commit is contained in:
parent
859ecc7b8b
commit
1882307cf3
7 changed files with 169 additions and 0 deletions
|
@ -27,6 +27,9 @@ export {
|
||||||
## The interface name from which the node will read/analyze packets.
|
## The interface name from which the node will read/analyze packets.
|
||||||
## Typically used by worker nodes.
|
## Typically used by worker nodes.
|
||||||
interface: string &optional;
|
interface: string &optional;
|
||||||
|
## The PCAP file name from which the node will read/analyze packets.
|
||||||
|
## Typically used by worker nodes.
|
||||||
|
pcap_file: string &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
## Configuration options that influence behavior of a supervised Zeek node.
|
## Configuration options that influence behavior of a supervised Zeek node.
|
||||||
|
@ -36,6 +39,8 @@ export {
|
||||||
name: string;
|
name: string;
|
||||||
## The interface name from which the node will read/analyze packets.
|
## The interface name from which the node will read/analyze packets.
|
||||||
interface: string &optional;
|
interface: string &optional;
|
||||||
|
## The PCAP file name from which the node will read/analyze packets.
|
||||||
|
pcap_file: string &optional;
|
||||||
## The working directory that the node should use.
|
## The working directory that the node should use.
|
||||||
directory: string &optional;
|
directory: string &optional;
|
||||||
## The filename/path to which the node's stdout will be redirected.
|
## The filename/path to which the node's stdout will be redirected.
|
||||||
|
|
|
@ -1233,6 +1233,11 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node)
|
||||||
if ( iface_val )
|
if ( iface_val )
|
||||||
rval.interface = iface_val->AsString()->CheckString();
|
rval.interface = iface_val->AsString()->CheckString();
|
||||||
|
|
||||||
|
const auto& pcap_file_val = node->GetField("pcap_file");
|
||||||
|
|
||||||
|
if ( pcap_file_val )
|
||||||
|
rval.pcap_file = pcap_file_val->AsString()->CheckString();
|
||||||
|
|
||||||
const auto& directory_val = node->GetField("directory");
|
const auto& directory_val = node->GetField("directory");
|
||||||
|
|
||||||
if ( directory_val )
|
if ( directory_val )
|
||||||
|
@ -1326,6 +1331,11 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node)
|
||||||
if ( iface )
|
if ( iface )
|
||||||
ep.interface = iface->AsStringVal()->ToStdString();
|
ep.interface = iface->AsStringVal()->ToStdString();
|
||||||
|
|
||||||
|
const auto& pcap_file = rv->GetField("pcap_file");
|
||||||
|
|
||||||
|
if ( pcap_file )
|
||||||
|
ep.pcap_file = pcap_file->AsStringVal()->ToStdString();
|
||||||
|
|
||||||
rval.cluster.emplace(name, std::move(ep));
|
rval.cluster.emplace(name, std::move(ep));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1342,6 +1352,9 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromJSON(std::string_view json)
|
||||||
if ( auto it = j.FindMember("interface"); it != j.MemberEnd() )
|
if ( auto it = j.FindMember("interface"); it != j.MemberEnd() )
|
||||||
rval.interface = it->value.GetString();
|
rval.interface = it->value.GetString();
|
||||||
|
|
||||||
|
if ( auto it = j.FindMember("pcap_file"); it != j.MemberEnd() )
|
||||||
|
rval.pcap_file = it->value.GetString();
|
||||||
|
|
||||||
if ( auto it = j.FindMember("directory"); it != j.MemberEnd() )
|
if ( auto it = j.FindMember("directory"); it != j.MemberEnd() )
|
||||||
rval.directory = it->value.GetString();
|
rval.directory = it->value.GetString();
|
||||||
|
|
||||||
|
@ -1402,6 +1415,9 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromJSON(std::string_view json)
|
||||||
if ( auto it = val.FindMember("interface"); it != val.MemberEnd() )
|
if ( auto it = val.FindMember("interface"); it != val.MemberEnd() )
|
||||||
ep.interface = it->value.GetString();
|
ep.interface = it->value.GetString();
|
||||||
|
|
||||||
|
if ( auto it = val.FindMember("pcap_file"); it != val.MemberEnd() )
|
||||||
|
ep.pcap_file = it->value.GetString();
|
||||||
|
|
||||||
rval.cluster.emplace(key, std::move(ep));
|
rval.cluster.emplace(key, std::move(ep));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1423,6 +1439,9 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const
|
||||||
if ( interface )
|
if ( interface )
|
||||||
rval->AssignField("interface", *interface);
|
rval->AssignField("interface", *interface);
|
||||||
|
|
||||||
|
if ( pcap_file )
|
||||||
|
rval->AssignField("pcap_file", *pcap_file);
|
||||||
|
|
||||||
if ( directory )
|
if ( directory )
|
||||||
rval->AssignField("directory", *directory);
|
rval->AssignField("directory", *directory);
|
||||||
|
|
||||||
|
@ -1499,6 +1518,9 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const
|
||||||
if ( ep.interface )
|
if ( ep.interface )
|
||||||
val->AssignField("interface", *ep.interface);
|
val->AssignField("interface", *ep.interface);
|
||||||
|
|
||||||
|
if ( ep.pcap_file )
|
||||||
|
val->AssignField("pcap_file", *ep.pcap_file);
|
||||||
|
|
||||||
cluster_val->Assign(std::move(key), std::move(val));
|
cluster_val->Assign(std::move(key), std::move(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1666,6 +1688,9 @@ void SupervisedNode::Init(Options* options) const
|
||||||
if ( config.interface )
|
if ( config.interface )
|
||||||
options->interface = *config.interface;
|
options->interface = *config.interface;
|
||||||
|
|
||||||
|
if ( config.pcap_file )
|
||||||
|
options->pcap_file = *config.pcap_file;
|
||||||
|
|
||||||
auto& stl = options->scripts_to_load;
|
auto& stl = options->scripts_to_load;
|
||||||
|
|
||||||
stl.insert(stl.begin(), config.addl_base_scripts.begin(), config.addl_base_scripts.end());
|
stl.insert(stl.begin(), config.addl_base_scripts.begin(), config.addl_base_scripts.end());
|
||||||
|
@ -1732,6 +1757,9 @@ std::string Supervisor::Create(const Supervisor::NodeConfig& node)
|
||||||
if ( nodes.find(node.name) != nodes.end() )
|
if ( nodes.find(node.name) != nodes.end() )
|
||||||
return util::fmt("node with name '%s' already exists", node.name.data());
|
return util::fmt("node with name '%s' already exists", node.name.data());
|
||||||
|
|
||||||
|
if ( node.interface.has_value() && node.pcap_file.has_value() )
|
||||||
|
return util::fmt("node with name '%s' has interface and pcap_file set", node.name.data());
|
||||||
|
|
||||||
if ( node.directory )
|
if ( node.directory )
|
||||||
{
|
{
|
||||||
auto res = util::detail::ensure_intermediate_dirs(node.directory->data());
|
auto res = util::detail::ensure_intermediate_dirs(node.directory->data());
|
||||||
|
|
|
@ -138,6 +138,11 @@ public:
|
||||||
* Typically used by worker nodes.
|
* Typically used by worker nodes.
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> interface;
|
std::optional<std::string> interface;
|
||||||
|
/**
|
||||||
|
* The PCAP file name from which the node read/analyze packets.
|
||||||
|
* Typically used by worker nodes.
|
||||||
|
*/
|
||||||
|
std::optional<std::string> pcap_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -199,6 +204,10 @@ public:
|
||||||
* The interface name from which the node should read/analyze packets.
|
* The interface name from which the node should read/analyze packets.
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> interface;
|
std::optional<std::string> interface;
|
||||||
|
/**
|
||||||
|
* The PCAP file name from which the node should read/analyze packets.
|
||||||
|
*/
|
||||||
|
std::optional<std::string> pcap_file;
|
||||||
/**
|
/**
|
||||||
* The working directory that should be used by the node.
|
* The working directory that should be used by the node.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
1300475167.096535 CHhAvVGS1DHFjwGM9 141.142.220.202 224.0.0.251 D dns
|
||||||
|
1300475167.097012 ClEkJM2Vm5giqnMf4h fe80::217:f2ff:fed7:cf65 ff02::fb D dns
|
||||||
|
1300475167.099816 C4J4Th3PJpwUYZZ6gc 141.142.220.50 224.0.0.251 D dns
|
||||||
|
1300475168.853899 CmES5u32sYpV7JYN 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.854378 CP5puj4I8PtEU4qzYg 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.854837 C37jN32gN3y3AZzyf6 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.857956 C0LAHyvtKSQHyJxIl 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.858306 CFLRIC3zaTU1loLGxh 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.858713 C9rXSW3KSpTYvPrlI1 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.891644 C9mvWx3ezztgzcexV7 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.892037 CNnMIj2QSd84NKf7U3 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.892414 C7fIlMZDuRiqjpYbb 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.893988 CpmdRlaUoJLN3uIRa 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.894422 C1Xkzz2MaGtLrc1Tla 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.894787 CqlVyW1YwZ15RhTBc4 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.901749 CBA8792iHmnhPLksKa 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475168.902195 CGLPPc35OzDQij1XX8 141.142.220.118 141.142.2.2 Dd dns
|
||||||
|
1300475169.899438 Cipfzj1BEnhejw8cGf 141.142.220.44 224.0.0.251 D dns
|
||||||
|
1300475170.862384 CV5WJ42jPYbNW9JNWf 141.142.220.226 141.142.220.255 D dns
|
||||||
|
1300475171.675372 CPhDKt12KQPUVbQz06 fe80::3074:17d5:2052:c324 ff02::1:3 D dns
|
||||||
|
1300475171.677081 CAnFrb2Cvxr5T7quOc 141.142.220.226 224.0.0.252 D dns
|
||||||
|
1300475173.116749 C8rquZ3DjgNW06JGLl fe80::3074:17d5:2052:c324 ff02::1:3 D dns
|
||||||
|
1300475173.117362 CzrZOtXqhwwndQva3 141.142.220.226 224.0.0.252 D dns
|
||||||
|
1300475173.153679 CaGCc13FffXe6RkQl9 141.142.220.238 141.142.220.255 D dns
|
||||||
|
1300475168.652003 CtPZjS20MLrsMUOJi2 141.142.220.118 208.80.152.2 DdA -
|
||||||
|
1300475168.902635 CiyBAq1bBLNaTiTAc 141.142.220.118 208.80.152.2 ShADad http
|
||||||
|
1300475168.855305 C3eiCBGOLw3VtHfOj 141.142.220.118 208.80.152.3 ShADad http
|
||||||
|
1300475168.855330 CwjjYJ2WqgTbAqiHl6 141.142.220.118 208.80.152.3 ShADad http
|
||||||
|
1300475168.859163 Ck51lg1bScffFj34Ri 141.142.220.118 208.80.152.3 ShADad http
|
||||||
|
1300475168.892913 CykQaM33ztNt0csB9a 141.142.220.118 208.80.152.3 ShADad http
|
||||||
|
1300475168.892936 CtxTCR2Yer0FR1tIBg 141.142.220.118 208.80.152.3 ShADad http
|
||||||
|
1300475168.895267 CLNN1k2QMum1aexUK7 141.142.220.118 208.80.152.3 ShADad http
|
||||||
|
1300475168.724007 CUM0KZ3MLUfNB0cl11 141.142.220.118 208.80.152.118 ShADad http
|
||||||
|
1300475169.780331 CFSwNi4CNGxcuffo49 141.142.220.235 173.192.163.128 ^h -
|
|
@ -0,0 +1,3 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
is_supervisor, T
|
||||||
|
PASS (got error), node with name 'grault' has interface and pcap_file set
|
70
testing/btest/supervisor/config-cluster-pcap.zeek
Normal file
70
testing/btest/supervisor/config-cluster-pcap.zeek
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# @TEST-DOC: Test support for pcap_file on Supervisor::ClusterEndpoint and Supervisor::NodeConfig
|
||||||
|
#
|
||||||
|
# @TEST-PORT: MANAGER_PORT
|
||||||
|
# @TEST-PORT: WORKER_PORT
|
||||||
|
# @TEST-EXEC: btest-bg-run zeek zeek -j %INPUT
|
||||||
|
# @TEST-EXEC: btest-bg-wait 45
|
||||||
|
# @TEST-EXEC: mv zeek/worker/conn.log zeek/worker/conn.log.orig
|
||||||
|
# @TEST-EXEC: zeek-cut ts uid id.orig_h id.resp_h history service < zeek/worker/conn.log.orig > zeek/worker/conn.log
|
||||||
|
# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff zeek/worker/conn.log
|
||||||
|
|
||||||
|
redef Log::default_rotation_interval = 0sec;
|
||||||
|
|
||||||
|
@if ( Supervisor::is_supervisor() )
|
||||||
|
|
||||||
|
redef SupervisorControl::enable_listen = T;
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
local cluster: table[string] of Supervisor::ClusterEndpoint;
|
||||||
|
cluster["manager"] = [$role=Supervisor::MANAGER, $host=127.0.0.1,
|
||||||
|
$p=to_port(getenv("MANAGER_PORT"))];
|
||||||
|
cluster["worker"] = [$role=Supervisor::WORKER, $host=127.0.0.1,
|
||||||
|
$p=to_port(getenv("WORKER_PORT")),
|
||||||
|
$pcap_file=(getenv("TRACES") + "/wikipedia.trace")];
|
||||||
|
|
||||||
|
for ( n, ep in cluster )
|
||||||
|
{
|
||||||
|
local sn = Supervisor::NodeConfig($name = n);
|
||||||
|
sn$cluster = cluster;
|
||||||
|
sn$directory = n;
|
||||||
|
sn$stdout_file = "stdout";
|
||||||
|
sn$stderr_file = "stderr";
|
||||||
|
|
||||||
|
if ( ep?$pcap_file )
|
||||||
|
sn$pcap_file = ep$pcap_file;
|
||||||
|
|
||||||
|
local res = Supervisor::create(sn);
|
||||||
|
|
||||||
|
if ( res != "" )
|
||||||
|
print fmt("failed to create node %s: %s", n, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global ready_for_shutdown = F;
|
||||||
|
|
||||||
|
# Immediately terminate the supervisor once we get a report about the worker
|
||||||
|
# starting for a second time.
|
||||||
|
event Supervisor::node_status(node: string, pid: count)
|
||||||
|
{
|
||||||
|
if ( node != "worker" )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ready_for_shutdown )
|
||||||
|
terminate();
|
||||||
|
|
||||||
|
ready_for_shutdown = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else
|
||||||
|
|
||||||
|
redef Log::enable_local_logging = T;
|
||||||
|
redef Log::enable_remote_logging = F;
|
||||||
|
|
||||||
|
# Even though we run with a pcap_file, we will not terminate
|
||||||
|
# once fully read, trigger terminate() directly.
|
||||||
|
event Pcap::file_done(path: string)
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
@endif
|
|
@ -0,0 +1,19 @@
|
||||||
|
# @TEST-DOC: Creating a node with inteface and pcap_file fails.
|
||||||
|
# @TEST-EXEC: zeek -j -b %INPUT >out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
# Providing interface and pcap_file is an error.
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
print "is_supervisor", Supervisor::is_supervisor();
|
||||||
|
local sn = Supervisor::NodeConfig(
|
||||||
|
$name="grault",
|
||||||
|
$interface="lo",
|
||||||
|
$pcap_file="/dev/null",
|
||||||
|
);
|
||||||
|
local res = Supervisor::create(sn);
|
||||||
|
|
||||||
|
print res != "" ? "PASS (got error)" : " FAIL (no error)", res;
|
||||||
|
terminate();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue