Open-source project
cisagov/Malcolm avatar
cisagov/Malcolm

Malcolm: Zeek, Suricata, OpenSearch and Arkime wired into one traffic analysis stack

Malcolm is a powerful, easily deployable network traffic analysis tool suite for full packet capture artifacts (PCAP files), Zeek logs and Suricata alerts.

2,532 stars449 forksPythonNOASSERTION

At a glance

What is it?
A container cluster from Idaho National Laboratory that takes PCAP files, Zeek logs and Suricata alerts and puts them behind two web interfaces, with an unusual amount of attention paid to industrial control protocols.
Who is it for?
Malcolm is at its best when the input is a pile of packet captures and the question is what industrial traffic is doing inside them. The commit history is thin in the ways that matter for a general network tool, with a single Python tree at the top level and most of the real engineering sitting in the container images, but the release notes are unusually specific about protocol coverage and about security fixes, which is exactly the pair of things a SOC operator needs.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A wiring diagram for tools that already exist

The first honest thing to say about Malcolm is that none of its parts are new. The README says so directly, then adds that Malcolm supplies a framework of interconnectivity that makes it greater than the sum of its parts, which is a fair description of what the repository actually is. The tree at the top level reads like an inventory of the stack: `zeek/`, `suricata/`, `opensearch/`, `opensearch-dashboards/` under the newer OpenSearch name, `arkime/`, `logstash/`, `filebeat/`, plus the supporting pieces `nginx/`, `keycloak/`, `netbox/`, `postgres-scripts/`, `strelka/`, `yara/`, `freq-server/`, and a `kubernetes/` directory for people who do not want the compose file. The project language is listed as Python, though most of the visible logic lives in shell scripts under `scripts/` and in the container images built from `Dockerfiles/`.

The two interfaces are the part analysts touch. OpenSearch Dashboards is described as a flexible data visualization plugin with dozens of prebuilt dashboards covering network protocols at a glance, and Arkime handles the other job, identifying the network sessions that make up a suspected incident. Both are established projects with their own documentation, so the value Malcolm adds is the plumbing between them, not new analysis logic. There is a survey link in the README asking users to describe their use cases, which is a small signal about the audience: people running this in a security operations center or on a laptop during an engagement.

Getting traffic in, through a browser or a forwarder

Malcolm accepts three kinds of artifact: full packet capture files, Zeek logs, and Suricata alerts. The README describes two paths for supplying them. The first is a simple browser-based interface for uploading files, the second is passive capture of live traffic forwarded by lightweight forwarders. Either way the README claims the data is automatically normalized, enriched and correlated for analysis, and that is the sentence to hold onto, because it is the difference between feeding raw captures to a pile of tools and getting pre-shaped data in OpenSearch.

The passive path is what separates Malcolm from a desktop packet analyzer. `pcap-capture/`, `pcap-monitor/`, and `pcap/` sit in the tree, and `zeek-logs/` and `suricata-logs/` have their own top-level directories, which suggests logs are treated as durable artifacts rather than transient stream output. For a lab or an engagement, that matters: an analyst can point a sensor at a span port, or hand over a folder of PCAPs from a friendlier network, and get the same dashboards either way. The README is light on the mechanics of the forwarders, though, and the deployment and forwarder configuration detail lives in the external documentation rather than in the repository.

What docker-compose.yml reveals about the deployment model

The README describes deployment as a cluster of software containers, each serving a dedicated function, managed with a few simple scripts. The checked-in compose file makes that concrete, and it is worth reading because it tells you what Malcolm expects from the host before you install anything:

yaml
services:
  opensearch:
    image: ghcr.io/idaholab/malcolm/opensearch:26.08.0
    profiles: ["malcolm"]
    logging:
      driver: local
    restart: "no"
    hostname: opensearch
    env_file:
    - ./config/process.env
    - ./config/ssl.env
    - ./config/auth-common.env
    - ./config/opensearch.env

Two details stand out. The images are version-pinned to the release, here `26.08.0`, published from `ghcr.io/idaholab`, so a Malcolm release is a coordinated bump of many components rather than a pull of latest tags. And configuration arrives through a stack of env files under `config/`, which is also where the upgrade migration logic lives: the v26.07.1 notes point at `config/env-var-actions.yml` for migrating settings. The same service block disables swapping with `memlock` ulimits and adds `IPC_LOCK` and `SYS_RESOURCE` capabilities, and mounts host directories for data, backups and the OpenSearch keystore, so Malcolm assumes a real Linux host with permission to tune memory. There is also a `docker-compose-dev.yml` for working on the stack itself.

Industrial control protocols are the differentiator

Most general network tools have a thin story about OT traffic. Malcolm has a roadmap-shaped one. The README names expanding control systems visibility as a design goal and says ongoing development will add parsers for common ICS protocols, and the releases show that being carried out. v26.07.0, published 2026-07-22 in the release list with v26.07.1 following, added IEC 60870-5-104 support built on CERT.LV's Zeek plugin, and the work went all the way down the stack: Logstash parsing, ECS normalization, Arkime fields, and a new OpenSearch Dashboards dashboard. That combination is the point. A protocol parser on its own does nothing useful; a parser that lands in ECS and shows up in both an Arkime session view and a dashboard is what makes an analyst's afternoon shorter.

The v26.08.0 release pushes the same idea into asset data by adding a NetBox `purdue_zone` custom field, so Purdue-level zone classifications propagate to devices, prefixes and virtual machines, and to devices autopopulated from their containing prefix. Pair that with the `netbox/` directory and the PostgreSQL scripts and you have an inventory system joined to traffic data, which is the piece that most stacks leave to the analyst. Asset interaction and zone placement are the questions an OT investigation actually asks, and very few open source stacks answer them out of the box.

A security fix history worth reading in full

Malcolm ships fast and its release notes name their security fixes, which makes the recent history unusually easy to audit. v26.06.1, dated 2026-06-16 in the release list, addressed a high severity remote code execution vulnerability tracked as GHSA-8cvp-m7pg-qrp7, described as unrestricted PHP file upload, and shipped security updates across Arkime, OpenResty, Valkey and PostgreSQL. It also carried a warning that PostgreSQL databases, meaning NetBox and Keycloak, were not compatible with previous releases, with advice to back up the NetBox database before upgrading.

Then v26.07.0 fixed three archive extraction and authentication vulnerabilities, and v26.08.0, dated 2026-08-25, fixed five: an nginx RBAC bypass via percent-encoded, case-varied or slash-doubled request paths; an archive bomb bypass affecting raw-stream and lzip-compressed uploads; a case-variant path bypass of the nginx auth gate that exposed the Arkime backend to forged identity headers; an Arkime authentication gap on sensor nodes where `digest` was used instead of enforcing `s2s`; and a CSRF flaw in the kiosk `/script_call` endpoint allowing unauthenticated data-destructive operations. Each of these sits exactly where you would expect the risk for a web UI that accepts untrusted uploads: the auth gate, the upload path, and the extraction of what gets uploaded. The v26.08.0 notes also make configurable Strelka scanner and disabled-Suricata-SID lists available, so operators can tune what the scanners do.

Upgrades are scripted, and the sequence is documented: run `./scripts/status` before upgrading an existing installation so settings migrate first. The last push to the default branch `main` was on 2026-09-23, so the release line and the repository are still moving together.

Where the README stops and the hosted docs take over

The README is about 3000 characters and does three things: list the design goals, link to the documentation at `docs/README.md`, and state the license and contact. The license is the Apache License, version 2.0, in `LICENSE.txt`, with the copyright held by Battelle Energy Alliance, LLC and contact at `[email protected]`. Note that the repository metadata reports the license as NOASSERTION, so if a tool you are feeding this into reads the API field rather than the file, it will not find the Apache grant. Homepage is `https://cisagov.github.io/Malcolm/`, the tree includes a `.justfile` and `.envrc.example` for local development, and there is a `malcolm-iso/` directory for building an ISO image, which tells you how seriously the offline-install use case is taken.

The limits are worth stating plainly. Malcolm is heavy: OpenSearch, Logstash, Filebeat, Arkime, Keycloak, NetBox, PostgreSQL and nginx are a lot of containers to run on a laptop, and the pinned image tags mean every upgrade is a coordinated event rather than a pull. Building the same pipeline by hand from upstream Zeek, Suricata and Arkime is entirely possible, and if your needs stop at generic enterprise traffic you will get further faster that way. The case for Malcolm is ICS/OT depth, the asset model, and the fact that someone else already solved the integration. With 2532 stars, 449 forks and 152 open issues, it is an active project rather than a museum piece. The README hands off quickly to docs/README.md, and that hosted documentation, not the repository, is where the deployment detail lives.

Editorial conclusion

Malcolm is at its best when the input is a pile of packet captures and the question is what industrial traffic is doing inside them. The commit history is thin in the ways that matter for a general network tool, with a single Python tree at the top level and most of the real engineering sitting in the container images, but the release notes are unusually specific about protocol coverage and about security fixes, which is exactly the pair of things a SOC operator needs. The README is short and points straight at docs/README.md; the pinned image tags in docker-compose.yml, currently ghcr.io/idaholab/malcolm/opensearch:26.08.0, tell you which build you are actually running before you deploy anything.

Frequently asked questions

What kinds of network data can Malcolm ingest?

Full packet capture files, Zeek logs and Suricata alerts. Artifacts can be uploaded through a browser-based interface or captured live and forwarded passively by lightweight forwarders, and the README states the data is normalized, enriched and correlated once it arrives.

Which interfaces does Malcolm give an analyst?

OpenSearch Dashboards, with dozens of prebuilt protocol dashboards, and Arkime, for finding and identifying the network sessions that make up a suspected incident. Both sit on top of an OpenSearch cluster that Malcolm deploys for you.

Does Malcolm handle industrial control system protocols?

Yes, and this is its distinguishing feature. Release v26.07.0 added IEC 60870-5-104 support through a CERT.LV Zeek plugin with Logstash parsing, ECS normalization, Arkime fields and a dashboard, while v26.08.0 added a NetBox purdue_zone field for ICS/OT zone classification.

How is Malcolm deployed and under what license?

As a cluster of Docker containers managed with a few scripts, with images pinned per release in docker-compose.yml, and it is licensed under the Apache License 2.0 in LICENSE.txt, copyright 2026 Battelle Energy Alliance, LLC.

Official sources

  1. cisagov/Malcolm on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cisagov-malcolm.svg)](https://hysenlabs.com/projects/cisagov-malcolm)