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.
/proc
/proc/net
/proc/<pid>/fd socket inodes to /proc/net/tcp and /proc/net/tcp6notify craterun for continuous monitoringonce for a single snapshotvalidate-configdefault-configContinuous 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.
/proc.The crate is kept buildable on non-Linux hosts for development and tests. On non-Linux systems, process and network collectors return empty results.
cargo build
Run tests:
cargo test
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"}}
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.
Most telemetry works as an unprivileged user, but visibility depends on host policy:
/proc permissions./proc/<pid>/fd symlinks. Socket events are still emitted when owner context is unavailable.If a configured filesystem watch path cannot be opened, sentinel-rs logs that the filesystem monitor was disabled and continues with other telemetry.
/proc exposes at collection time. Very short-lived processes or restricted /proc entries may be unattributed./proc parsing is intentionally minimal and may be expanded in later phases./proc/net and /proc/<pid>/fd.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