Plugin + companion daemon delivering two capabilities in a single release: Incremental backup acceleration (3× measured on Linux, 1.7× on Windows) by eliminating the FD tree-walk, and active ransomware detection with 9 configurable response actions (log, webhook, syslog/EventLog, SMB kill, ACL deny, fs snapshot, emergency backup, kill suspect processes).
Companion technical document to the PodHeitor Sentinel plugin page.
1. The two problems attacked
1.1 Incremental backup does a full tree-walk
The stock Bacula File Daemon runs lstat() on every FileSet file on every Incremental — even when only 1 file changed. On a server with 60,000 files:
Director → Job runs → FD lstat()'s every file → backup modified ones
(60,000 stat calls even when 1 file changed)
On a 600,000-file file server, the overhead dominates the Incremental window. That’s why many sites disable frequent Incrementals — they prefer Full + weekly Differential.
1.2 Ransomware detection is offline, post-mortem
Standard solutions (CrowdStrike, Sentinel One, MS Defender) detect ransomware on the compromised host but don’t notify the backup before the trojan finishes encryption. Typical result: nightly backup captures already-encrypted files; restore depends on a previous Full + window loss.
2. Architecture — Rust daemon + FD plugin client
┌────────────────────────────────┐ JSON IPC ┌──────────────────┐
│ PodHeitor Sentinel Daemon │◄───────────────────►│ Bacula FD │
│ (Rust, tokio, redb) │ Unix socket (Linux)│ Rust cdylib FD │
│ │ Named Pipe (Win32) │ │
│ ┌─────────────────────────┐ │ │ │
│ │ fs watcher │ │ │ │
│ │ • inotify Linux │ │ │ │
│ │ • ReadDirW Win32 │ │ │ │
│ └────────┬────────────────┘ │ │ │
│ ▼ │ │ │
│ ┌─────────────────────────┐ │ │ │
│ │ detection engine │ │ │ │
│ │ • burst_rename │ │ │ │
│ │ • suspicious_ext │ │ │ │
│ │ • high_entropy │ │ │ │
│ │ • altered_ratio │ │ │ │
│ │ • hysteresis scoring │ │ │ │
│ └────────┬────────────────┘ │ │ │
│ ▼ │ │ │
│ ┌─────────────────────────┐ │ │ │
│ │ policy engine (9 actions) │ │ │
│ └─────────────────────────┘ │ │ │
│ ┌─────────────────────────┐ │ │ │
│ │ accelerator (redb) │◄──┼─── hot_paths ───────┤ │
│ └─────────────────────────┘ │ │ │
│ ┌─────────────────────────┐ │ │ │
│ │ metrics HTTP :9990 │──────► Prometheus │ │
│ └─────────────────────────┘ │ │ │
└────────────────────────────────┘ └──────────────────┘
The same daemon delivers both capabilities. The fs watcher (inotify Linux / ReadDirectoryChangesW Win32) feeds:
- Detection engine: 4 heuristic rules + hysteresis scoring → policy engine.
- Accelerator (redb): hot_paths index → consulted by FD plugin at job start.
3. Incremental Accelerator — before/after
The FD plugin queries the daemon before iterating the FileSet:
Director → Job runs → plugin asks sentinel for hot paths (live) → FD backup
(exactly N stat calls for N modified files)
+ ransomware detection running in parallel on the same events
+ automatic VSS/btrfs/zfs snapshot + Close-SmbSession on signature
The FD’s ack_backup to the daemon clears the hot-path index, marking the point-in-time as backed-up. Next Incremental starts from zero.
4. Benchmark — 2026-04-23
Linux, 60K-file corpus, 1,000 modifications, cold cache:
| Scenario | Incremental time | Rate |
|---|---|---|
| Accelerator OFF | 2.93 s | 311.6 KB/s |
| Accelerator ON | 0.98 s | 954.7 KB/s |
Speedup: 3.00× (saved 66.7%). Scales linearly: projected ~20× on 600K-file file servers.
Windows Server 2025, same workload — 1.71× speedup (Windows has higher per-file FD cost, so walk savings are a smaller share of total time).
5. Detection engine — 4 rules
| Rule | Signal | Default threshold |
|---|---|---|
burst_rename |
N renames in short time window | 50 renames in 60s |
suspicious_ext |
Known extensions (.locked, .encrypted, .crypt, .crypted, .locky, …) |
5 occurrences in 60s |
high_entropy |
Shannon entropy of content > threshold (random data has high entropy) | > 7.5 bits/byte sustained |
altered_ratio |
Files-altered / directory-size ratio high in short window | > 30% in 5 min |
5.1 Hysteresis scoring
Each rule contributes points to a per-path/dir score. Score accumulates with time decay (single event << sustained pattern). Action thresholds:
- Score < 30 → telemetry only
- 30 ≤ score < 60 → WARN-level actions (log, webhook)
- 60 ≤ score < 80 → ALERT-level actions (syslog/EventLog, alert_cmd)
- score ≥ 80 → CRITICAL-level actions (smb_kill_sessions, readonly_remount, fs_snapshot, emergency_backup, kill_suspect_processes)
6. Policy engine — 9 actions
| Action | Behaviour |
|---|---|
log |
Structured line in daemon log |
webhook |
POST JSON to configurable URL (Slack, PagerDuty, Mattermost, custom) |
syslog / EventLog |
Linux syslog or Windows Event Log for SOC ingestion |
alert_cmd |
Shell command with incident env vars |
smb_kill_sessions |
Close-SmbSession against SMB attacker (Windows); smbcontrol kill (Linux Samba) |
readonly_remount / ACL deny |
Remount partition ro or apply ACL deny to share |
fs_snapshot |
VSS (Windows) / btrfs snapshot / zfs snapshot |
emergency_backup |
Triggers a Bacula emergency Full job before encryption advances |
kill_suspect_processes |
Terminates processes identified as source (PID correlation via fanotify Linux / minifilter Win32) |
7. Compatibility
| OS | Versions |
|---|---|
| Linux | RHEL 8/9, Oracle Linux, Rocky, Alma, Debian 11/12, Ubuntu 20/22/24 |
| Windows | Server 2019/2022/2025, Windows 10/11 |
| Bacula | Community 15.0.3+ or Enterprise compatible |
Same code base; platform-specific paths via Rust #[cfg] / #ifdef. Windows uses Named Pipes instead of Unix sockets, Win32 services instead of systemd, ReadDirectoryChangesW instead of inotify.
8. Prometheus metrics
HTTP /metrics on loopback :9990 exposes:
sentinel_events_total{type="rename|create|modify|delete"}sentinel_score_current{path}(gauge)sentinel_actions_fired_total{action, severity}sentinel_accelerator_hot_paths_count(gauge)sentinel_accelerator_queries_total,sentinel_accelerator_acks_totalsentinel_redb_size_bytes,sentinel_daemon_rss_bytes
Prometheus alerts + Grafana dashboard included in monitoring/.
9. Documented anti-patterns
- Don’t disable the
fs_snapshotaction at score ≥ 80. Local snapshots are the safety net against ransomware that wipes shadow copies. - Don’t set thresholds too low without a watchlist.
high_entropyfalse positives on legitimately compressed files (zip, JPEG, mp4) are expected — exclude known extensions viawatch_exclude_ext. - Don’t run
kill_suspect_processeswithout an allowlist. An incorrect PID match can kill critical services. Configureprocess_allowlistwith system PIDs/binaries. - Don’t trust
burst_renamein isolation. Legitimate workflows (rsync, git, IDE mass-rename refactors) can fire it. Pair withsuspicious_extorhigh_entropyvia hysteresis.
10. License posture
The plugin ships under LicenseRef-PodHeitor-Proprietary. No Bacula AGPLv3 source is statically linked. The FD plugin is a Rust cdylib that talks PTCOMM to the daemon; the daemon is a standalone Rust binary. Bacula integration is exclusively via the public plugin API.
Ready to evaluate?
Free 30-day trial for Bacula Community/Enterprise servers. We guarantee at least 50% discount vs Bacula Enterprise (which has no active ransomware detection), Veeam Threat Protection or Commvault, with Incremental acceleration and remediation actions included.
Heitor Faria — Founder, PodHeitor International
✉ [email protected]
☎ +1 (789) 726-1749 · +55 (61) 98268-4220 (WhatsApp)
🔗 PodHeitor Sentinel plugin page
Disponível em:
Português (Portuguese (Brazil))
English
Español (Spanish)