CPU/GPU inference-only container for a PNETLab observation trial. It contains the trained B2 checkpoint and a small flow-to-window adapter; it does not train, read the CICIDS CSV files, calculate a trust score, or block traffic.
The checkpoint forecasts 14 aggregate features for the next 10-minute window
from six consecutive 10-minute windows (28 input features). On startup the
service chooses cuda:0 if CUDA is visible inside the container, otherwise it
uses CPU. The checkpoint was trained on offline traces; treat the output as a
lab observation, not an enforcement decision.
The first forecast needs six closed windows (about 60 minutes). A forecast error is returned only after the target window is closed. Feature construction also uses the preceding history, up to 300 windows, for peer and traffic baselines; early values are therefore based on shorter history.
From this directory:
docker build -t b2-lab-probe:2026-10-04 .
docker run --rm --name b2-lab-probe --gpus all -p 8080:8080 -e B2_DEVICE=auto b2-lab-probe:2026-10-04
If the host has no supported NVIDIA GPU/runtime, omit --gpus all; the service
will report and use CPU. GPU access requires an NVIDIA driver and NVIDIA
Container Toolkit on the Docker host. Do not expose this unauthenticated lab
API to an untrusted network.
Check the selected device and checkpoint:
curl http://localhost:8080/health
curl http://localhost:8080/features
NFStream runs outside this container and POSTs flow records to POST /flows.
Send either one flow object or a batch:
{"flows":[{
"src_ip":"10.0.0.10", "dst_ip":"198.51.100.20", "dst_port":443,
"protocol":"TCP", "application_name":"TLS",
"bidirectional_first_seen_ms":1791072000123,
"bidirectional_duration_ms":1200,
"bidirectional_packets":8, "bidirectional_bytes":2400,
"bidirectional_mean_ps":300, "bidirectional_mean_piat_ms":150,
"bidirectional_syn_packets":1, "bidirectional_rst_packets":0,
"bidirectional_fin_packets":1, "bidirectional_ack_packets":6,
"src2dst_packets":5, "dst2src_packets":3,
"src2dst_bytes":1700, "dst2src_bytes":700,
"dst2src_rst_packets":0
}]}
label is deliberately not required: live flows are normally unlabeled. The
field device_id is optional; when absent, src_ip is used as the device key.
The directional packet/byte fields are required because the trained features
include directional ratios. Timestamps must retain millisecond precision and
use NFStream's bidirectional_first_seen_ms field.
After the sender's lateness buffer guarantees that no older flow records will arrive, POST a monotonically increasing watermark:
{"watermark_ms":1791072600000}
to POST /watermark. The response's events array contains forecast events
and, once the corresponding target window closes, forecast_error events. The
error is reported as an absolute standardized residual per feature and its
mean; it is diagnostic only, not a calibrated attack threshold. Flows older
than the committed watermark are rejected so the window history cannot silently
become inconsistent. POST /reset clears in-memory lab state.
The sender should batch records (for example, 100 flows per request) to
http://<container-host>:8080/flows, then periodically call /watermark with
current_time_ms - lateness_buffer_ms. Choose the lateness buffer to exceed
NFStream's flow expiration/emit delay. Parse and save every returned event as
JSONL so predictions can be compared with the subsequent observations. The
optional nfstream_push_example.py provides a dependency-free B2HttpSink;
import it in the process that already iterates over NFStreamer, call push(flow)
for each emitted record, flush() as needed, and pass only a committed watermark
to watermark(...).
The service is stateful and in-memory. Restarting the container resets window history; this is intentional for a lightweight lab probe.
Content type
Image
Digest
sha256:555c22f02…
Size
3.8 GB
Last updated
25 days ago
docker pull poeency/b2-lab-probe:2026-10-04