sentinel-rs

sentinel-rs is a small, read-only Linux host telemetry monitor written in Rust. It focuses on collecting useful local security signals and emitting structured JSON events without taking response actions.

It does not kill processes, block network connections, quarantine files, change permissions, or modify watched paths.

Features

Baseline monitoring

Continuous run monitoring can compare process and listening-socket metadata against a persistent JSON baseline. The baseline is initialized from the first host snapshot, so existing processes and listeners do not generate a burst of first-seen alerts. Later observations produce structured anomaly events for new identities and listener owner changes.

Persistent process identity uses executable path, UID, and name rather than PID. Persistent listener identity uses protocol, local address, local port, and owner metadata rather than socket inode alone. Runtime socket tracking remains independent of owner metadata so ownership changes can be detected reliably.

The baseline is only used by run. The once command remains a stateless telemetry snapshot and does not modify the baseline.

Behavioral monitoring stores compact process-network identities rather than every connection occurrence. Repeated observations of a learned connection do not produce repeated anomaly events. Behavioral monitoring remains detection-only and does not classify endpoints as malicious or take response actions.

Behavioral detection also works when persistent baseline storage is disabled; the current process-network observation state remains in memory for the monitoring session. Correlation normalizes deleted executable identities such as /tmp/payload (deleted) to the original path while retaining raw values in the source events.

Cross-domain correlation detects suspicious sequences of legitimate observations, such as a file being created, then executed, then opening a listener or making an outbound connection. It does not label activity as malware and does not take response actions. Correlation is enabled for continuous run monitoring and is bounded by the configured time window.

Requirements

The crate is kept buildable on non-Linux hosts for development and tests. On non-Linux systems, process and network collectors return empty results.

Setup

cargo build

Run tests:

cargo test

Usage

Print the default configuration:

cargo run -- default-config

Validate the included configuration:

cargo run -- --config config/sentinel.toml validate-config

Collect one snapshot:

cargo run -- --config config/sentinel.toml once

Run continuously until Ctrl-C:

cargo run -- --config config/sentinel.toml run

Each event is printed as a single JSON line:

{"timestamp":"2026-10-04T14:02:11.123Z","kind":"listening_socket","severity":"high","source":"network","message":"tcp listening on 0.0.0.0:4444 owned by pid 1842 (payload)","details":{"inode":53124,"local_address":"0.0.0.0","local_port":4444,"pid":1842,"process_cmdline":"/tmp/payload --listen 4444","process_exe":"/tmp/payload","process_name":"payload","process_uid":0,"protocol":"tcp"}}

Configuration

The default config lives at config/sentinel.toml.

[telemetry]
interval_seconds = 5

[process]
enabled = true
include_command_line = true

[network]
enabled = true
include_udp = true

[filesystem]
enabled = true
paths = ["/etc", "/usr/local/bin", "/tmp"]
recursive = false

[logging]
level = "info"
json = false

[baseline]
enabled = true
path = "state/baseline.json"
initialize_on_first_run = true
learn_new = true

[baseline.allowlist]
process_executables = ["/usr/bin/systemd", "/usr/sbin/sshd"]
listener_executables = ["/usr/sbin/sshd"]
listener_ports = [22]

[behavior]
enabled = true
learn_new = true
track_outbound = true
track_remote_endpoints = true
track_remote_ports = true

[behavior.allowlist]
remote_addresses = []
remote_ports = []
process_executables = []

[correlation]
enabled = true
window_seconds = 300

Allowlist matching is exact; regular expressions and glob patterns are not supported. Baseline corruption is reported as an error rather than silently overwritten. If baseline persistence fails during monitoring, telemetry continues and the failure is logged.

Permissions

Most telemetry works as an unprivileged user, but visibility depends on host policy:

If a configured filesystem watch path cannot be opened, sentinel-rs logs that the filesystem monitor was disabled and continues with other telemetry.

Limitations

Repository Layout

sentinel-rs/
├── config/
│   └── sentinel.toml
├── src/
│   ├── anomaly.rs
│   ├── baseline.rs
│   ├── behavior.rs
│   ├── correlation.rs
│   ├── config.rs
│   ├── detection.rs
│   ├── event.rs
│   ├── filesystem.rs
│   ├── lib.rs
│   ├── logger.rs
│   ├── main.rs
│   ├── network.rs
│   └── process.rs
├── tests/
│   └── event_detection.rs
├── Cargo.toml
└── README.md

Next Phase Ideas