Merge remote-tracking branch 'origin/topic/awelzel/control-switch-to-cluster'

* origin/topic/awelzel/control-switch-to-cluster:
  NEWS: ZeekControl, ZeroMQ and WebSocket
  Update zeekctl module for ClusterBackend and UseWebSocket
  control: Use Cluster::publish() for replying
This commit is contained in:
Arne Welzel 2025-07-23 19:31:13 +02:00
commit ee5ffdf42c
5 changed files with 54 additions and 15 deletions

17
CHANGES
View file

@ -1,3 +1,20 @@
8.0.0-dev.713 | 2025-07-23 19:31:13 +0200
* NEWS: ZeekControl, ZeroMQ and WebSocket (Arne Welzel, Corelight)
* Update zeekctl module for ClusterBackend and UseWebSocket (Arne Welzel, Corelight)
* control: Use Cluster::publish() for replying (Arne Welzel, Corelight)
Switching to ZeroMQ as cluster backend and dabbling with zeekctl
and WebSocket, replies didn't arrive due to the usage of
Broker::publish() rather than Cluster::publish(). Additionally,
add the node name to the topic on which we reply so that the
receiver can figure out which node sent the reply. It could've
been a separate event parameter, but the topic appears just fine.
* Fix clang-tidy findings in embedded C++ from bif files (Tim Wojtulewicz, Corelight)
8.0.0-dev.707 | 2025-07-23 08:21:17 -0700
* CI: Add weekly task for running builds with newest compilers (Tim Wojtulewicz, Corelight)

19
NEWS
View file

@ -130,6 +130,25 @@ New Functionality
implementation in the ``src/packet_analysis/protocol/ip/conn_key/vlan_fivetuple``
directory for an example.
- Added support to ZeekControl for seamlessly switching to ZeroMQ as cluster
backend by adding the following settings to zeekctl.cfg:
ClusterBackend = ZeroMQ
UseWebSocket = 1
With the ZeroMQ cluster backend, Zeekctl requires to use Zeek's WebSocket API
to communicate with individual nodes for the ``print`` and ``netstats`` commands.
Setting the ``UseWebSocket`` option enables a WebSocket server on the manager
node, listening on 127.0.0.1:27759 by default (this is configurable with using
the newly introduced ``WebSocketHost`` and ``WebSocketPort`` options).
The ``UseWebSocket`` option can also be used when ``ClusterBackend`` is set
to ``Broker``, but isn't strictly required.
For ZeroMQ (or other future cluster backends), setting ``UseWebSocket`` is a
requirement as Zeekctl does not speak the native ZeroMQ protocol to communicate
with cluster nodes for executing commands. This functionality requires the
``websockets`` Python package with version 11.0 or higher.
- Cluster telemetry improvements. Zeek now exposes a configurable number of
metrics regarding outgoing and incoming cluster events. By default, the number
of events sent and received by a Zeek cluster node and any attached WebSocket

View file

@ -1 +1 @@
8.0.0-dev.707
8.0.0-dev.713

@ -1 +1 @@
Subproject commit 61d7712b828a593bf7b84f67f3123442d5ab6f12
Subproject commit 9be35bd6e1d7c61855594b08aa99d5fff49476f5

View file

@ -14,17 +14,20 @@ module Control;
event zeek_init() &priority=-10
{
Broker::subscribe(Control::topic_prefix + "/" + Broker::node_id());
if ( Cluster::backend == Cluster::CLUSTER_BACKEND_BROKER )
{
Broker::subscribe(Control::topic_prefix + "/" + Broker::node_id());
if ( Control::controllee_listen )
Broker::listen();
if ( Control::controllee_listen )
Broker::listen();
}
}
event Control::id_value_request(id: string)
{
local val = lookup_ID(id);
local reply_topic = Control::topic_prefix + "/id_value_response";
Broker::publish(reply_topic, Control::id_value_response, id, fmt("%s", val));
local reply_topic = Control::topic_prefix + "/id_value_response/" + Cluster::node;
Cluster::publish(reply_topic, Control::id_value_response, id, fmt("%s", val));
}
event Control::peer_status_request()
@ -44,8 +47,8 @@ event Control::peer_status_request()
bpeer$status);
}
local topic = Control::topic_prefix + "/peer_status_response";
Broker::publish(topic, Control::peer_status_response, status);
local topic = Control::topic_prefix + "/peer_status_response/" + Cluster::node;
Cluster::publish(topic, Control::peer_status_response, status);
}
event Control::net_stats_request()
@ -53,8 +56,8 @@ event Control::net_stats_request()
local ns = get_net_stats();
local reply = fmt("%.6f recvd=%d dropped=%d link=%d\n", network_time(),
ns$pkts_recvd, ns$pkts_dropped, ns$pkts_link);
local topic = Control::topic_prefix + "/net_stats_response";
Broker::publish(topic, Control::net_stats_response, reply);
local topic = Control::topic_prefix + "/net_stats_response/" + Cluster::node;
Cluster::publish(topic, Control::net_stats_response, reply);
}
event Control::configuration_update_request()
@ -66,15 +69,15 @@ event Control::configuration_update_request()
# the configuration is going to be updated. This event could be handled
# by other scripts if they need to do some ancillary processing if
# redef-able consts are modified at runtime.
local topic = Control::topic_prefix + "/configuration_update_response";
Broker::publish(topic, Control::configuration_update_response);
local topic = Control::topic_prefix + "/configuration_update_response/" + Cluster::node;
Cluster::publish(topic, Control::configuration_update_response);
}
event Control::shutdown_request()
{
# Send the acknowledgement event.
local topic = Control::topic_prefix + "/shutdown_response";
Broker::publish(topic, Control::shutdown_response);
local topic = Control::topic_prefix + "/shutdown_response/" + Cluster::node;
Cluster::publish(topic, Control::shutdown_response);
# Schedule the shutdown to let the current event queue flush itself first.
schedule 1sec { terminate_event() };
}