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 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) * 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`` implementation in the ``src/packet_analysis/protocol/ip/conn_key/vlan_fivetuple``
directory for an example. 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 - Cluster telemetry improvements. Zeek now exposes a configurable number of
metrics regarding outgoing and incoming cluster events. By default, the number 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 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 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 ) if ( Control::controllee_listen )
Broker::listen(); Broker::listen();
}
} }
event Control::id_value_request(id: string) event Control::id_value_request(id: string)
{ {
local val = lookup_ID(id); local val = lookup_ID(id);
local reply_topic = Control::topic_prefix + "/id_value_response"; local reply_topic = Control::topic_prefix + "/id_value_response/" + Cluster::node;
Broker::publish(reply_topic, Control::id_value_response, id, fmt("%s", val)); Cluster::publish(reply_topic, Control::id_value_response, id, fmt("%s", val));
} }
event Control::peer_status_request() event Control::peer_status_request()
@ -44,8 +47,8 @@ event Control::peer_status_request()
bpeer$status); bpeer$status);
} }
local topic = Control::topic_prefix + "/peer_status_response"; local topic = Control::topic_prefix + "/peer_status_response/" + Cluster::node;
Broker::publish(topic, Control::peer_status_response, status); Cluster::publish(topic, Control::peer_status_response, status);
} }
event Control::net_stats_request() event Control::net_stats_request()
@ -53,8 +56,8 @@ event Control::net_stats_request()
local ns = get_net_stats(); local ns = get_net_stats();
local reply = fmt("%.6f recvd=%d dropped=%d link=%d\n", network_time(), local reply = fmt("%.6f recvd=%d dropped=%d link=%d\n", network_time(),
ns$pkts_recvd, ns$pkts_dropped, ns$pkts_link); ns$pkts_recvd, ns$pkts_dropped, ns$pkts_link);
local topic = Control::topic_prefix + "/net_stats_response"; local topic = Control::topic_prefix + "/net_stats_response/" + Cluster::node;
Broker::publish(topic, Control::net_stats_response, reply); Cluster::publish(topic, Control::net_stats_response, reply);
} }
event Control::configuration_update_request() 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 # the configuration is going to be updated. This event could be handled
# by other scripts if they need to do some ancillary processing if # by other scripts if they need to do some ancillary processing if
# redef-able consts are modified at runtime. # redef-able consts are modified at runtime.
local topic = Control::topic_prefix + "/configuration_update_response"; local topic = Control::topic_prefix + "/configuration_update_response/" + Cluster::node;
Broker::publish(topic, Control::configuration_update_response); Cluster::publish(topic, Control::configuration_update_response);
} }
event Control::shutdown_request() event Control::shutdown_request()
{ {
# Send the acknowledgement event. # Send the acknowledgement event.
local topic = Control::topic_prefix + "/shutdown_response"; local topic = Control::topic_prefix + "/shutdown_response/" + Cluster::node;
Broker::publish(topic, Control::shutdown_response); Cluster::publish(topic, Control::shutdown_response);
# Schedule the shutdown to let the current event queue flush itself first. # Schedule the shutdown to let the current event queue flush itself first.
schedule 1sec { terminate_event() }; schedule 1sec { terminate_event() };
} }