@@ -19,31 +19,31 @@ The classic :ref:`framework-input` and :ref:`framework-configuration` can be
1919leveraged for runtime configuration of Zeek as well as triggering arbitrary
2020events or script execution via option handlers. These frameworks are mostly
2121file- or process-based and may feel a bit unusual in environments where creation
22- of files is uncommon. In today's world, interacting using HTTP-based APIs or
23- other remote interfaces is more common.
22+ of files is uncommon or even impossible due to separation of concerns. In many
23+ of today's environments, interacting using HTTP-based APIs or other remote
24+ interfaces is more common.
2425
2526.. note ::
2627
2728 As an aside, if you need more flexibility than the WebSocket API offers today,
2829 an alternative could be to use :ref: `javascript ` within Zeek. This opens the
2930 possibility to run a separate HTTP or a totally different Node.js based server
30- within a Zeek process.
31-
31+ within a Zeek process for quick experimentation and evaluation of other
32+ approaches.
3233
3334Background and Setup
3435====================
3536
36- Since Zeek 5.0, Zeek allows connections from external clients over WebSocket
37- connections. This allows these clients to interact with Zeek's publish-subscribe
38- layer and exchange Zeek events with other Zeek nodes.
37+ Since Zeek 5.0, Zeek allows connections from external clients over WebSocket.
38+ This allows these clients to interact with Zeek's publish-subscribe layer and
39+ exchange Zeek events with other Zeek nodes.
3940Initially, this implementation resided in the Broker subsystem.
4041With Zeek 8.0, most of the implementation has been moved into core Zeek
4142itself with the v1 serialization format remaining in Broker.
4243
4344WebSocket clients may subscribe to a fixed set of topics and will receive
4445Zeek events matching these topics that Zeek cluster nodes, but also other
45- WebSocket clients publish.
46- Clients
46+ WebSocket clients, publish.
4747
4848With Zeek 8.0, Zeekctl has received support to interact with Zeek cluster nodes
4949using the WebSocket protocol. If you're running a Zeekctl based cluster and
@@ -56,42 +56,51 @@ your ``zeekctl.cfg``:
5656 ...
5757 UseWebSocket = 1
5858
59- This will essentially add the following snippet to be run on the Zeek manager:
59+ This will essentially add the following snippet, enabling a WebSocket server
60+ on the Zeek manager:
6061
6162.. code-block :: zeek
6263 :caption: websocket.zeek
6364
6465 event zeek_init()
6566 {
66- Cluster::listen_websocket([
67- $listen_addr=127.0.0.1,
68- $listen_port=27759/tcp,
69- ]);
67+ if ( Cluster::local_node_type() == Cluster::MANAGER )
68+ {
69+ Cluster::listen_websocket([
70+ $listen_addr=127.0.0.1,
71+ $listen_port=27759/tcp,
72+ ]);
73+ }
7074 }
7175
7276
73- To verify if the WebSocket API is functional on your deployment, it is possible
74- to use `websocat <https://github.com/vi/websocat >`_ for a quick check.
77+ To verify that the WebSocket API is functional in your deployment use, for example,
78+ `websocat <https://github.com/vi/websocat >`_ as a quick check.
7579
7680.. code-block :: shell
7781
7882 $ echo ' []' | websocat ws://127.0.0.1:27759/v1/messages/json
7983 {" type" :" ack" ," endpoint" :" 3eece35d-9f94-568d-861c-6a16c433e090-websocket-2" ," version" :" 8.0.0-dev.684" }
8084
8185 Zeek's ``cluster.log `` file will also have an entry for the WebSocket client connection.
82- The empty array in the command is the array holding the client's subscriptions.
86+ The empty array in the command specifies the client's subscriptions, in this case none .
8387
8488Version 1
8589=========
8690
87- The currently implemented protocol is accessible at ``v1/messages/json ``. The
88- `data representation <https://docs.zeek.org/projects/broker/en/current/web-socket.html#data-representation >`_
91+ The currently implemented protocol is accessible at ``/ v1/messages/json ``.
92+ The `data representation <https://docs.zeek.org/projects/broker/en/current/web-socket.html#data-representation >`_
8993is documented in detail within the Broker project. Note that this format is a
9094direct translation of Broker's binary format into JSON, resulting in a fairly
91- tight coupling between WebSocket clients and the Zeek scripts. Most prominently
92- is the representation of record values as vectors instead of objects, making
93- the protocol sensitive against reordering or introduction of optional fields
94- into records.
95+ tight coupling between WebSocket clients and the corresponding Zeek scripts.
96+ Most prominently is the representation of record values as vectors instead
97+ of objects, making the protocol sensitive against reordering or introduction
98+ of optional fields to records.
99+
100+ .. note ::
101+
102+ We're looking into an iteration of the format. If you have feedback or
103+ would like to contribute, please reach out on the usual community channels.
95104
96105
97106Handshake and Acknowledgement
@@ -106,8 +115,8 @@ Zeek replies with an acknowledgement message that's a JSON object or an error.
106115Events
107116------
108117
109- After the acknowledgement, WebSocket clients receive all messages arriving on
110- the topics they subscribed to.
118+ After the acknowledgement, WebSocket clients receive all events arriving on
119+ topics they have subscribed to.
111120
112121.. code-block :: shell
113122
@@ -128,17 +137,34 @@ to Broker's JSON format and send them as `text data frames <https://datatracker.
128137Language Bindings
129138-----------------
130139
131- Python
132- ^^^^^^
140+ Note that it's possible to use any language that offers WebSocket bindings.
141+ The ones listed below mostly add a bit of convenience features around the
142+ initial Handshake message, error handling and serializing Zeek events and
143+ values into the Broker-specific serialization format.
144+
145+ For example, using the Node.js `builtin WebSocket functionality <https://nodejs.org/en/learn/getting-started/websocket >`_,
146+ the ``websocat `` example from above can be reproduced as follows:
147+
148+ .. code-block :: javascript
149+ : caption: client .js
150+
151+ // client.js
152+ const socket = new WebSocket (' ws://192.168.122.107:27759/v1/messages/json' );
153+
154+ socket .addEventListener (' open' , event => {
155+ socket .send (' ["zeek.test"]' );
156+ });
157+
158+ socket .addEventListener (' message' , event => {
159+ console .log (' Message from server: ' , event .data );
160+ });
161+
162+ .. code-block :: shell
163+
164+ $ node ./client.js
165+ Message from server: {" type" :" ack" ," endpoint" :" 2e951b0c-3ca4-504c-ae8a-5d3750fec588-websocket-10" ," version" :" 8.0.0-dev.684" }
166+ Message from server: {" type" :" data-message" ," topic" :" zeek.test" ," @data-type" :" vector" ," data" :[{" @data-type" :" count" ," data" :1},{" @data-type" :" count" ," data" :1},{" @data-type" :" vector" ," data" :[{" @data-type" :" string" ," data" :" hello" },{" @data-type" :" vector" ," data" :[{" @data-type" :" count" ," data" :374}]},{" @data-type" :" vector" ," data" :[]}]}]}
133167
134- There are no ready to use Python libraries, but the third-party
135- `websockets <https://github.com/python-websockets/websockets >`_ allows
136- to getting started quickly.
137- You may take inspiration from `zeek-client's implementation <https://github.com/zeek/zeek-client >`_
138- or the `small helper library <https://raw.githubusercontent.com/zeek/zeek/refs/heads/master/testing/btest/Files/ws/wstest.py >`_ used by various of Zeek's own tests for the
139- WebSocket API.
140- Zeekctl similarly ships `light implementation <https://github.com/zeek/zeekctl/blob/93459b37c3deab4bec9e886211672024fa3e4759/ZeekControl/events.py#L159 >`_
141- using the ``websockets `` library to implement its ``netstats `` and ``print `` commands.
142168
143169 Golang
144170^^^^^^
@@ -150,3 +176,15 @@ Rust
150176^^^^
151177
152178* `Rust types for interacting with Zeek over WebSocket <https://github.com/bbannier/zeek-websocket-rs >`_ (not an official Zeek project)
179+
180+ Python
181+ ^^^^^^
182+
183+ There are no ready to use Python libraries available, but the third-party
184+ `websockets <https://github.com/python-websockets/websockets >`_ package
185+ allows to get started quickly.
186+ You may take inspiration from `zeek-client's implementation <https://github.com/zeek/zeek-client >`_
187+ or the `small helper library <https://raw.githubusercontent.com/zeek/zeek/refs/heads/master/testing/btest/Files/ws/wstest.py >`_ used by various of Zeek's own tests for the
188+ WebSocket API.
189+ Zeekctl similarly ships a `light implementation <https://github.com/zeek/zeekctl/blob/93459b37c3deab4bec9e886211672024fa3e4759/ZeekControl/events.py#L159 >`_
190+ using the ``websockets `` library to implement its ``netstats `` and ``print `` commands.
0 commit comments