ZeekJS is an experimental Zeek plugin to support JavaScript as an alternative scripting language in Zeek.
zeek.on('zeek_init', function() {
console.log('Hello, Zeek!');
});
The plugin embeds Node.js and primarily deals with converting between JavaScript and Zeek data types and registering JavaScript functions as event or hook handlers within Zeek. It further installs Node's IO loop as an IO source in Zeek.
Compiling and running ZeekJS requires a Zeek installation and Node.js available as a shared library.
Currently ZeekJS strives to be compatible with latest stable, feature and nightly releases of Zeek.
Note
With Zeek version 6.0, the ZeekJS plugin is automatically included as a builtin plugin when Node.js is available on the build system. The Zeek documentation received a section about JavaScript, too.
If your operating system offers a way to install a modern Node.js version as a shared library and includes development headers as well, that makes things easy. For example, on Fedora 34 and 35 all that is needed is to install the nodejs-devel
and nodejs-lib
packages.
If you're not using Fedora, you'll probably need to compile Node.js yourself.
Start by fetching a source tarball, or cloning the Node.js repository and check out the tag of the release you want to build. Then, configure, compile and install it.
$ git clone https://github.com/nodejs/node.git
$ cd node
# Reset repo to a specific Node.js version
$ git reset --hard v20.11.1
# Configure Node.js with shared OpenSSL and set desired installation prefix
$ ./configure --prefix=/opt/node-20.11 --shared --shared-openssl
$ make
$ sudo make install
With Node.js in place, you should be prepared to compile ZeekJS.
You may want to look into docker/debian.Dockerfile
for some inspiration around installing Node.js on Debian or other distributions.
ZeekJS is a standard Zeek plugin. Existing documentation around building and installing Zeek plugins should apply to it as well. Ensure that zeek-config
is in your path, then use ./configure
and make
for building and installing.
If Node.js is installed in a non-standard location, use --with-nodejs=/path/to/nodejs
.
For example:
$ zeek-config --version
6.0.3
$ ./configure --with-nodejs=/opt/node-20.11
$ make
$ sudo make install
If everything worked out the plugin should be available available:
$ zeek -NN Zeek::JavaScript
Zeek::JavaScript - Experimental JavaScript support for Zeek (dynamic, version 0.11.0)
Implements LoadFile (priority 0)
Verify ZeekJS is functional by running a JavaScript file using Zeek:
$ cat << EOF > hello.js
zeek.on('zeek_init', function() {
console.log('Hello, Zeek!');
});
EOF
$ zeek ./hello.js
Hello, Zeek!
- No multi-index support for tables and sets. JavaScript objects have string properties only.
Generally, look out for [ ERROR ]
messages on stderr
. If something doesn't seem to work, it may just not be implemented.
This example shows how to start a HTTP server and expose network and event stats gathered by invoking the bifs get_net_stats()
and get_event_stats()
.
examples/http-stats.js
$ curl -sfS localhost:3000 | jq
{
"net": {
"pkts_recvd": "4861",
"pkts_dropped": "0",
"pkts_link": "4861",
"bytes_recvd": "6319316"
},
"event": {
"queued": "431",
"dispatched": "431"
},
"zeek_version": "4.1.1-debug"
}
This leverages Zeek 4.1's new Log::log_stream_policy
hook to bypass Zeek logging.
examples/log-bypass.js
This will write JSON log entries into dns.log
, http.log
and ssl.log
when running, for example:
$ zeek -r tests/Traces/dns-http-https.pcap ./log-bypass.js
$ cat dns.log
{"ts":1630238733.951343,"uid":"CS00HK1MFHn2F03Px2","id.orig_h":"172.20.10.3","id.orig_p":55767,"id.resp_h":"172.20.10.1","id.resp_p":53,"proto":"udp","trans_id":"43556","rtt":0.03791093826293945,"query":"corelight.com","qclass":"1","qclass_name":"C_INTERNET","qtype":"1","qtype_name":"A","rcode":"0","rcode_name":"NOERROR","AA":false,"TC":false,"RD":true,"RA":true,"Z":"0","answers":["199.60.103.106","199.60.103.6"],"TTLs":[77,77],"rejected":false}
The plugin adds a zeek
object into the global namespace. This object provides the following functions to interact with Zeek.
zeek
on
hook
event
invoke
as
select_fields
flatten
global_vars