NexusShield —
an adaptive application-layer
and host-layer security gateway.
A pure-Rust gateway combining abstract-syntax-tree SQL injection detection, server-side request forgery guarding, adaptive multi-stage rate limiting, multi-signal threat scoring, and a hash-chained tamper-evident audit log with an eighteen-module host-protection engine spanning signature, heuristic, and pattern-based malware detection, process and network behaviour analysis, in-memory shellcode detection, rootkit and file-integrity monitoring, and container and supply-chain inspection. Distributed as a single binary. Deployed in production environments across application gateways, mail relays, and developer endpoints.
Abstract
Background
Application-layer security gateways traditionally rely on regular-expression rule sets to identify SQL injection, server-side request forgery, and other input-borne attacks. Such systems suffer well-documented evasion vectors arising from input encoding, comment injection, and whitespace manipulation [Halfond 2006; OWASP 2021]. Endpoint protection is conventionally implemented in C/C++ with kernel components, an architecture associated with significant attack surface (memory-safety defects in privileged code) and operator burden (driver signing, kernel-version coupling).
Approach
NexusShield is a pure-Rust security gateway that performs SQL injection detection by constructing an abstract syntax tree using the sqlparser crate and analysing structural properties rather than surface form. It pairs the gateway with an optional eighteen-module host-protection engine that operates exclusively in user space, eliminating kernel-mode code as a precondition. Per-request risk is computed as a weighted combination of behavioural signals — request fingerprint anomaly, rate-limit history, and per-source request history — yielding a numeric score in [0, 1] with operator-tunable Allow / Warn / Block thresholds. Audit events are chained by SHA-256 such that any modification to a prior event invalidates all subsequent links.
Results
The system ships as a Rust binary set of approximately twenty-six thousand lines with three executables (nexus-shield, security-ticker, daily-report), thirteen gateway modules, and eighteen endpoint-protection modules. It exposes ten authenticated HTTP endpoints plus two unauthenticated probes, integrates with seven outbound notification channels (SMTP, SMS, three webhook flavours, three SIEM destinations, the systemd journal), and runs with no kernel components. Audit-chain integrity is verified by verify_chain(), which returns the index of the first broken link if any modification has occurred.
Conclusion
Memory-safe implementation of an application-layer gateway with AST-based input analysis and a user-space host-protection engine is feasible without sacrificing the breadth of capability associated with traditional endpoint and gateway products. The architecture trades rule-set ergonomics (regular expressions are familiar to operators) for parser-based correctness (the analyser sees the same structure the application's database driver will). Detection rules, threshold tuning, and the contents of the threat-intelligence database are intentionally not enumerated in this paper to preserve their operational utility.
| Package version | 0.4.4 (Rust 2024, MSRV 1.85) |
| License | MIT |
| Source size | ~22,000 lines of Rust across gateway + endpoint engine |
| Gateway modules | 13 |
| Endpoint protection modules | 18 |
| Binaries | nexus-shield, security-ticker, daily-report |
| Detection categories | blocked · sql · ssrf · rate · threats |
| Outbound integrations | Ferrum Mail · NexusPulse SMS · webhooks (Slack, Discord, generic) · SIEM (syslog, ES, Splunk HEC) · systemd journal |
| Audit chain | SHA-256 hash-chained, tamper-evident |
| Live since | 2026-04-12 (daily-report; 07:00 UTC) |
Executive overview
NexusShield combines an application-layer HTTP gateway with an optional host-layer protection engine, both implemented in safe Rust and distributed as a single binary. The gateway performs structural rather than lexical input analysis: SQL traffic is parsed to an abstract syntax tree before classification; outbound URL requests are resolved and validated against IP-range and DNS-rebinding policies before connection.
The system is organised in three concentric layers. The gateway pipeline processes each HTTP request through SQL injection detection, SSRF guarding, rate governance, request fingerprinting, threat scoring, email injection prevention, input sanitisation, and structured-data quarantine. The endpoint engine performs concurrent file, process, network, memory, rootkit, file-integrity, USB, DNS, container, and supply-chain monitoring. The audit and integration layer appends every security event to a hash-chained log and exports to seven outbound channels.
What ships
Design rationale
Three architectural decisions follow from the system's stated goals (memory safety, kernel-free deployment, parser-based input analysis). Each is presented with the trade-off it implies.
Structural input analysis (parser-based, not lexical)
SQL injection detection is performed by constructing the input's abstract syntax tree with the sqlparser crate and analysing properties of the tree (presence of UNION nodes outside expected schema, tautology subexpressions in WHERE clauses, comment-injection terminators inside string literals). The same principle governs the SSRF guard, which parses outbound URLs with the url crate and validates against IP-range policies before connection, and the request fingerprinter, which composes header signals into a structured RequestFingerprint with an anomaly score [Halfond 2006; OWASP 2021]. Trade-off: parser-based analysis incurs higher per-request CPU than regex matching and is constrained to inputs the parser can accept; malformed input that cannot be parsed at all is treated as a strong negative signal.
Append-only hash-chained audit
The audit log is structured as a hash chain: each event ei records SHA-256(ei-1.hash ‖ ei.payload). Tampering with any ej for j < n invalidates the recorded hash of every ek for k ≥ j. The verification function verify_chain() returns ChainVerification { valid: bool, broken_at_event_id: Option<EventId> } identifying the first inconsistent link. Trade-off: the chain provides tamper-evidence (modification is detectable) but not tamper-resistance (a sufficiently-privileged adversary can rewrite the entire chain from e0); external replication of the chain head to an out-of-band consumer (SIEM destination, signed remote witness) is required for stronger guarantees.
Single-binary user-space deployment
The system is distributed as a single ELF / PE binary with no kernel module, driver, or auxiliary daemon. Operating modes are selected by command-line flag: --standalone exposes only the management surface; --upstream <URL> activates reverse-proxy traffic interception; --endpoint activates the host-protection engine in the same process. Trade-off: user-space-only operation forfeits visibility into kernel-level activity (kernel-mode rootkits, syscalls bypassing libc) that a kernel module could observe; the system mitigates this by reading /proc structures directly and cross-referencing observed process / file system state against the ground-truth views the kernel exposes.
Threat model
The threat model is stated formally in terms of the categories described by Microsoft's STRIDE framework [Hernan 2006] augmented with the OWASP Top 10 [OWASP 2021]. Threats addressed by the system are listed below; threats explicitly out of scope are stated separately. Defence-in-depth assumes complementary controls (network segmentation, identity, OS hardening) at adjacent layers.
Threats addressed
| Layer | Threat | Module |
|---|---|---|
| Gateway | SQL injection (UNION, tautologies, comment / hex / encoded payloads) | SQL firewall (AST-level) |
| Gateway | SSRF, internal network probing, DNS rebinding, cloud-metadata access | SSRF guard |
| Gateway | Brute force, credential stuffing, scraper bots, DoS | Adaptive rate governor |
| Gateway | Bot traffic, anomalous header patterns, fingerprintable scrapers | Request fingerprinter |
| Gateway | Email header injection, email bombing | Email guard |
| Gateway | Path traversal, malicious connection strings, error-message leakage | Input sanitiser |
| Gateway | Malicious CSV / JSON imports | Data quarantine |
| Endpoint | Known malware (signature match) | Signature engine |
| Endpoint | Packed / encrypted / obfuscated binaries; embedded executables | Heuristic engine |
| Endpoint | Reverse shells, miners, deleted-binary processes | Process monitor |
| Endpoint | C2 beaconing, suspicious port use, malicious-IP egress | Network monitor |
| Endpoint | In-memory shellcode, RWX regions, Meterpreter-class injection | Memory scanner |
| Endpoint | Rootkits (kernel module / LD_PRELOAD / hidden process) | Rootkit detector |
| Endpoint | System binary tampering, /etc modification | File integrity monitoring |
| Endpoint | Malicious USB autoruns, suspicious removable media | USB / removable monitor |
| Endpoint | Malicious DNS lookups, sinkhole-class blocking | DNS filter |
| Endpoint | Insecure container images (root user, secrets, dangerous bases) | Container scanner |
| Endpoint | Typosquat / malicious / dependency-confusion packages | Supply-chain scanner |
Threats out of scope
- Application-level authorisation defects — broken access control, insecure direct object references, business-logic flaws. The system has no model of the protected application's authorisation policy.
- Post-exploitation privilege escalation — once an adversary obtains shell access under the service account, the audit chain records their activity but cannot prevent further action; complementary controls (NexusVault for credential isolation, OS hardening, capability dropping) bound blast radius.
- Encrypted command-and-control over standard ports — TLS to benign-appearing destinations is not detectable without endpoint TLS interception, which is explicitly out of scope.
- Kernel-level zero-day exploits — user-space tooling cannot observe kernel-mode activity that bypasses standard syscall interfaces.
- Authorised-insider misuse — the audit chain establishes attribution and tamper-evidence but does not constitute an access-control mechanism.
Defence-in-depth assumption
The system is positioned as a single layer in a defence-in-depth architecture and presupposes complementary controls at adjacent layers: network segmentation (firewall, VPN ACLs), identity (multi-factor authentication, short-lived credentials), OS hardening (systemd directives, capability bounding, mandatory access control), credential isolation (NexusVault), and physical security. Reference deployments combine NexusShield with Tailscale ACLs, NexusVault, and systemd-level confinement.
Architecture
The shield is one Tokio process. Every request flows through the same Axum middleware chain. The endpoint engine is an optional set of Tokio tasks that share the process's audit log and SSE event stream.
Process layout
// nexus-shield process
┌────────────────────────────────────────────────────┐
│ Axum HTTP server (8080 by default) │
│ /health /dashboard /status /audit /stats │
│ /report /events /metrics /endpoint/* │
├────────────────────────────────────────────────────┤
│ Middleware chain (per request) │
│ ① Bearer-token auth (if api_token set) │
│ ② Request fingerprint │
│ ③ Rate governor │
│ ④ SQL firewall │
│ ⑤ SSRF guard │
│ ⑥ Sanitiser │
│ ⑦ Threat-score → Allow / Warn / Block │
│ ⑧ Audit-chain append (every event) │
├────────────────────────────────────────────────────┤
│ Endpoint engine (optional, --endpoint) │
│ inotify watcher → scanner trait → detections │
│ process_monitor (poll /proc every 2 s) │
│ network_monitor (poll /proc/net/tcp every 5 s) │
│ memory_scanner / rootkit_detector │
│ dns_filter (UDP 127.0.0.1:5353) │
│ fim · usb_monitor · container_scanner │
│ supply_chain · file_quarantine · allowlist │
├────────────────────────────────────────────────────┤
│ Outbound integrations │
│ Ferrum Mail · NexusPulse · Slack · Discord │
│ SIEM (syslog / ES / Splunk HEC) · systemd journal│
└────────────────────────────────────────────────────┘
Stack
- HTTP — Axum 0.7 + Hyper 1 + Tower 0.5 middleware composition
- TLS — Rustls 0.23 via
axum-server0.7 with PEM cert/key loading - Async — Tokio 1, full feature set
- Logging —
tracing+tracing-subscriberwith env-filter and JSON output for journal - Synchronisation —
parking_lotRwLocks (no lock poisoning) - Cryptography —
aes-gcm0.10 (credential vault),sha20.10 (audit chain, file hashing) - Parsing —
sqlparser0.41 (SQL AST),url2 (SSRF),regex1 (script obfuscation) - Endpoint primitives —
notify7 (inotify),procfs0.17 (/proc parsing),nix0.29 (signals + uid) - UI (optional) — eframe 0.29 + egui 0.29 for the security ticker (feature
ticker) - CLI — clap 4 with derive
Source layout
| Component | LoC | Files |
|---|---|---|
| Gateway modules (src/*.rs) | ~9,900 | 13 modules |
| Endpoint engine (src/endpoint/*.rs) | ~12,100 | 18 modules |
| nexus-shield binary (src/bin/main.rs) | ~1,100 | 1 binary |
| daily-report binary (src/bin/daily_report.rs) | ~730 | 1 binary |
| security-ticker (src/ui/security_ticker.rs) | ~2,400 | egui widget, feature-gated |
| TOTAL | ~26,300 | ~22,000 excl. binaries & ticker |
Lexical web-application firewalls operate on the surface form of HTTP request bodies and are routinely bypassed by encoding manipulation, comment injection, and concatenation across boundaries [Halfond 2006]. The SQL firewall instead delegates parsing to the sqlparser crate and analyses the resulting abstract syntax tree. Disposition follows from structural properties: the presence of UNION nodes outside the application's expected query shape, tautology subexpressions in WHERE clauses, comment terminators occurring within string literals, and similar patterns. Inputs that fail to parse altogether are treated as a strong negative signal and rejected.
Public API
| analyze_query(sql, config) | Returns SqlAnalysis { risk_score, violations: Vec<SqlViolation> } |
| SqlAnalysis | Numeric risk score (0.0 – 1.0) plus structured violation list. |
| SqlViolation | Each violation names a category (e.g., UnionInjection, Tautology, CommentInjection) and a severity. |
The detector ships with a published count of pattern categories ("30+" per the README) covering UNION-based injection, tautology fragments, comment-injection terminators, and several encoding variants. The exact pattern set, regex shapes, and threshold tuning are intentionally not enumerated in this paper — publishing them publicly would only help attackers tune around the specific signatures.
Rationale for AST-level detection
Encoding-based evasion (hex literals, URL escapes, comment injection) defeats lexical detectors precisely because the input is rendered equivalent at the database layer. AST-based detection inverts the asymmetry: the database accepts only inputs the parser can construct, so any input that bypasses the gateway must either parse to a structure the gateway considers benign or fail to parse at the database too. This bounds the evasion space to inputs whose AST shape mimics legitimate application traffic.
SSRF guard & rate governor
The SSRF guard parses every outbound URL with the url crate, resolves the destination, and validates it against a deny-list of ranges that internal services would never legitimately call: RFC 1918 private IPv4, link-local, loopback, RFC 4193 unique-local IPv6, the cloud-metadata service IP (169.254.169.254), and DNS-rebinding signals. Hosts that resolve to allowed IPs at parse time but to denied IPs at connect time are blocked by re-validating after resolution. Protocol allow-lists prevent file:// / gopher:// / dict:// from sneaking in.
Rather than a single token bucket, the governor escalates through five levels: None → Warn → Throttle → Block → Ban. First-time over-rate clients get a warn entry in the audit log and a soft throttle. Persistent abusers are escalated; the time spent in each level is configurable. check(&ip) returns RateCheckResult { level: EscalationLevel, retry_after: Option<u64> }, which the gateway converts into HTTP 429 + Retry-After headers.
Key insight: a Block level fires after a configurable count of Throttle events, and a Ban level fires after a configurable count of Block events. The shield treats persistence as the signal worth catching — single bursts get throttled, sustained pressure gets banned.
Fingerprinting & threat scoring
Bots leak themselves through header inconsistencies — a User-Agent claiming Chrome paired with an Accept header no real Chrome ever sent, a missing Accept-Language, a referer pointing nowhere consistent. The fingerprinter composes those signals into a structured RequestFingerprint with a numeric anomaly score and a stable hash. The hash is the primitive that lets repeat-offender bots be identified across IP rotation.
A request's threat score in 0.0–1.0 is a weighted blend of four signals — fingerprint anomaly (≈30%), rate-governor history (≈25%), behavioural signals from the request itself (≈30%), and request-history signals from the same client (≈15%) — yielding a final ThreatAction::{Allow, Warn, Block}.
Two thresholds matter and both are configurable on the command line: --block-threshold (default 0.7) and --warn-threshold (default 0.4). Below warn, the request goes through silently. Between warn and block, the request goes through but an audit entry is appended. Above block, the request is rejected with 403 and the entry is escalated.
Two attack classes need stopping at the application boundary: header injection (CR/LF in form fields that get spliced into outgoing mail) and email bombing (a single web form that fires off thousands of confirmations to one inbox). The email guard handles both. Per-recipient rate limits are tracked in memory; spikes against any single address are blocked before the application's mail-sending code runs. Header injection attempts (CR/LF in any field that will end up in an SMTP envelope) are rejected outright and audit-logged.
Public surface: EmailRateLimiter::check(to_addr) -> Result. The API mirrors the rate-governor surface so the integrating application can ask "is this destination currently throttled?" without a custom database.
Sanitiser & quarantine
Three exposed primitives: validate_connection_string() for catching injected database connection strings, validate_file_path() for catching path traversal, and sanitize_error_message() for stripping internal IP addresses, stack traces, and absolute paths from anything the application might bubble back to a client. The last one is the often-forgotten win: error messages leak more than people realise, and a centralised redactor saves having to remember to scrub at every ?.
CSV and JSON ingest paths are a perennially under-defended attack surface — formula injection in spreadsheets, prototype pollution in JSON, deserialisation gadgets that arrive as innocent-looking strings. The quarantine module validates incoming structured data against a small allow-list of safe shapes before the application is allowed to deserialise.
Credential vault & audit chain
Sensitive fields stored alongside user records — third-party API keys, OAuth refresh tokens, integration passwords — are encrypted at the field level with AES-256-GCM. The encryption key for each user record is derived from a server-held master and the user's identifier, so a database leak alone does not expose plaintext secrets.
| encrypt_source_config() | Encrypt a configuration blob for storage. |
| decrypt_source_config() | Decrypt at use time. |
| is_encrypted() | Tell whether a field has already been encrypted (idempotent migrations). |
For larger-scale secret management — versioned secrets, transit encryption, full audit trails of every read — see the companion NexusVault project, which is the standalone vault NexusShield will reach for when the workload outgrows in-place field encryption.
Each appended event includes the SHA-256 hash of the previous event. Tampering anywhere in the chain — modifying an event, removing one, inserting one out of order — breaks the chain at the point of tampering, and verify_chain() returns the offending broken_at_event_id. The chain is the primitive that makes the daily report, the compliance report, and the SIEM export trustable: any consumer can verify the chain themselves.
| AuditChain::append(event) | Append a new event; computes hash of (previous_hash · event). |
| verify_chain() | Returns ChainVerification { valid, broken_at_event_id }. |
Endpoint engine overview
Eighteen modules, ~12,100 lines of Rust, all running inside the same Tokio process as the gateway. inotify-driven, near-zero idle CPU, configurable from the same TOML the gateway uses.
The orchestrator
endpoint/mod.rs (1,152 LoC) is the conductor. It defines the Scanner trait — the interface every detection module implements — and the EndpointEngine that schedules concurrent scans across all engines. The shared types are minimal:
Severity { Info, Low, Medium, High, Critical }DetectionCategory { MalwareSignature, HeuristicAnomaly, SuspiciousProcess, NetworkAnomaly, MemoryAnomaly, RootkitIndicator, YaraMatch, FilelessMalware }ScanResult { id, timestamp, scanner, target, severity, category, description, confidence, action, artifact_hash }
Every endpoint module returns the same shape, which means the audit chain, the SSE event stream, the SIEM export, and the daily-report binary all speak the same vocabulary regardless of which detector fired.
Filesystem watcher
endpoint/watcher.rs (289 LoC) is the trigger for almost everything else. It uses notify 7's inotify backend, debounces events at 300 ms to coalesce build-system thrash, and excludes the usual high-volume directories (node_modules, target, .git, __pycache__) by default. Files larger than 100 MB are skipped. When something inside a watched path changes, the orchestrator spawns scans across each registered engine.
Signatures, heuristics, YARA
Three detection layers — exact match, structural analysis, pattern rules — chained so each compensates for the others' blind spots.
Streaming SHA-256 of file contents in 8 KB chunks; fast hashes give exact-match detection of known malware. Built-in entries cover the EICAR test file and an additional eleven test signatures (Trojan, Backdoor, Ransomware, Rootkit, Miner, Exploit, Webshell, etc.). Custom signatures load from an NDJSON feed:
{"hash":"<sha256hex>","name":"...","family":"Trojan","severity":"High","description":"..."}
- Shannon entropy threshold (high entropy = packed / encrypted / obfuscated)
- ELF header analysis (stripped binaries, writable+executable segments)
- File-type / magic mismatch (a
.pdfwith anMZheader is rarely a PDF) - Script obfuscation (long base64 blobs, eval+decode chains)
- Embedded executable detection (
MZ/ELFmagic past byte 1024)
A pure-Rust pattern engine — no C/C++ dependency on libyara — covering the common rule families anyone running an endpoint protection product needs: EICAR, suspicious PowerShell encoding patterns, Linux reverse-shell patterns, web-shell indicators, crypto-miner signatures. Custom rule loading at startup; rule shapes are intentionally not enumerated here.
Detection rules are not enumerated
Specific rule contents, exact magic-byte offsets, regex shapes, and threshold tuning across the three detection layers are intentionally redacted from this document. They live in the source tree and in the threat-intel feed; publishing them publicly would only help attackers shape payloads to slip past the specific signatures.
Process · network · memory
Polls /proc at 2-second intervals. Three detection categories:
- Reverse shell patterns — bash/python/perl/ruby/PHP/socat/openssl-s_client invocation shapes that almost never appear in benign workloads
- Miner patterns — known miner names, stratum protocol fragments, common miner CLI flags
- Deleted-binary processes — when
/proc/<pid>/exeresolves to a path containing "(deleted)", a process is running from a binary that's been removed from disk; a strong signal of a self-deleting payload
Total numbers (per the source): nineteen reverse-shell patterns and seventeen miner patterns. The exact pattern strings are not in this document — see the same redaction note as the YARA engine.
Parses /proc/net/tcp at 5-second intervals. Three detection categories: connections to known-malicious IPs (cross-referenced against the threat-intel database), use of suspicious ports (a small set widely associated with reverse shells), and C2 beaconing (regular intervals of outbound connections with low timing jitter — a strong signal of programmatic callbacks).
Reads /proc/<pid>/maps looking for memory regions that are simultaneously readable, writable, and executable — a configuration almost no legitimate program needs and a hallmark of in-memory shellcode injection. When an RWX region is found, the scanner sweeps it for shellcode patterns (syscall preambles, NOP sleds, Meterpreter-class markers) using mask-based matching that tolerates polymorphic encodings.
Rootkit · FIM · DNS · USB
Four detection signals: SHA-256 baseline checks of system binaries (anything that's been swapped out is a strong signal); kernel-module name check against a small blacklist of known userspace-rootkit modules; LD_PRELOAD detection in /etc/ld.so.preload and process environments; and hidden-process detection by cross-referencing /proc directory listing against the kernel's task list.
Persistent baselines, configurable poll interval (default 60 s), exclude patterns, severity by path. /etc/passwd changing is Critical. /usr/bin/* changing is High. /etc/* changing is Medium. Detects content modifications, permission and ownership changes, new files, and deletions. Survives restarts via on-disk baselines.
A loopback DNS proxy. Queries that match the threat-intel domain list (or a custom blocklist) are answered with 0.0.0.0 (sinkhole). Everything else is forwarded to the configured upstream (default 8.8.8.8). Subdomain matching, whitelist override, runtime management via the HTTP API, and per-query logging.
Polls every 3 seconds for new mountable devices. When a device appears: autorun-file detection (autorun.inf, autorun.sh, autoexec.bat, desktop.ini), hidden executables (dot-prefixed files with the executable bit), and suspicious script extensions at the volume root.
Container & supply-chain
Wraps docker inspect and docker history to inspect images. Findings: containers running as root, hardcoded secrets in environment variables (password=, api_key=, aws_secret=), dangerous base images (security-test distributions), suspicious package presence (nmap, netcat, socat, hydra, sqlmap, metasploit), pipe-to-shell idioms (curl ... | bash) anywhere in the build, privileged-mode flags, suspicious port exposes, world-writable permissions, and disabled security features (SELinux / AppArmor / seccomp turned off in the build).
Parses Cargo.lock, package-lock.json, yarn.lock, requirements.txt, Pipfile.lock, go.sum. Detects: known-malicious packages cross-referenced against an internal database, typosquatted package names (Levenshtein distance ≤2 from a known-popular package), suspicious version strings (0.0.x packages with no commit history), and dependency-confusion signals (a package present in a custom registry that shadows the same name on the public registry). Built-in popular-package databases for Rust, npm, and PyPI keep typosquat detection meaningful out of the box.
Quarantine vault & developer-aware allowlist
Detected files are quarantined into an encrypted vault at ~/.nexus-shield/quarantine/. Permissions are stripped to 0o000 on the quarantined copy. SHA-256 chain of custody. Auto-cleanup after 30 days, max 1 GB total. Restoration replays the original permissions. quarantine_file(path) and restore(quarantine_id) are the public surface; everything else is internal.
The single most important quality-of-life feature for running endpoint protection on a developer's laptop. The allowlist auto-detects Rust (rustc, cargo, rust-analyzer), Node (node, npm, npx, yarn, pnpm, bun, deno), Python (python, pip, conda), Go, Docker, Java, C/C++, common editors and IDEs (code, nvim, vim, emacs), and Git. Build directories (target/debug, node_modules, .git) are skipped wholesale. The result is an endpoint protection product that doesn't fight the developer who installed it.
Additions to the allowlist made from the security-ticker UI are persisted back to config.toml using toml_edit for lossless round-tripping (preserves comments, formatting, and ordering). Restart-safe.
Three binaries
nexus-shield — gateway + endpoint daemon
The main binary. Reverse proxy, standalone gateway, optional endpoint protection agent. Listens on --port (default 8080). Modes: --standalone (gateway + status surface only), --upstream <URL> (full reverse proxy in front of an application), --endpoint (enable real-time host protection), --scan <DIR> (one-shot scan), --scan-file <FILE> (single-file scan). Threshold knobs: --block-threshold 0.7, --warn-threshold 0.4, --rps 50. Config path: --config /etc/nexus-shield/config.toml.
security-ticker — desktop egui widget
Optional binary built behind the ticker Cargo feature (which pulls in eframe 0.29 + egui 0.29). Renders live detections, audit-chain status, and recent activity in a small persistent window. Useful when running NexusShield locally on a developer's laptop or on a server you frequently SSH-tunnel to.
daily-report — automated 24-hour HTML email
Generates an HTML summary of the last 24 hours by querying the running shield's /status, /audit, and /endpoint/detections endpoints. Renders a Ferrum-Mail-styled HTML email (cream header, teal pill, severity-coloured cards) and ships it via the Ferrum Mail API. Live since 2026-04-12; fires daily at 07:00 UTC via a systemd timer; recipients are automatanexus@ferrum-mail.com and devops@automatanexus.com. CLI flags: --out, --hours 24, --sample, --send, --to (repeatable), --subject, --print-meta. Credentials are pulled from environment variables or HashiCorp Vault path secret/ferrum-mail.
HTTP API surface
Two access tiers: unauthenticated probes for load balancers and dashboards, authenticated endpoints for everything else. When api_token is set in config, every authenticated endpoint requires a Bearer token.
Unauthenticated
| Method | Path | Purpose |
|---|---|---|
| GET | /health | Always 200. Load balancer probe. |
| GET | /dashboard | Browser HTML widget. Public assets only. |
Authenticated (Bearer)
| Method | Path | Purpose |
|---|---|---|
| GET | /status | Shield status JSON: uptime, chain integrity. |
| GET | /audit | Recent audit events (last 50). |
| GET | /stats | Request statistics (5-minute, 1-hour windows). |
| GET | /report | HTML compliance report. |
| GET | /events | SSE real-time security event stream (15-second keepalive). |
| GET | /metrics | Prometheus metrics text format. |
| GET | /endpoint/status | Endpoint engine stats: files scanned, threats, active monitors. |
| GET | /endpoint/detections | Recent detections (last 100). |
| GET | /endpoint/quarantine | Quarantined files list. |
| POST | /endpoint/scan | On-demand scan. Body is a file or directory path. |
Detection categories tracked in the audit chain
| blocked | RequestBlocked events. |
| sql | SqlInjectionAttempt. |
| ssrf | SsrfAttempt. |
| rate | RateLimitHit. |
| threats | MalwareDetected (endpoint). |
Outbound integrations
A security tool that catches things and tells nobody is half a tool. NexusShield ships seven outbound paths so the right alert lands at the right team in the right format.
Ferrum Mail (HTML alerts)
The ferrum_integration module (341 LoC) sends formatted HTML security alerts via the Ferrum Mail HTTP API. JWT login flow: POST /mailbox/api/v1/auth/login → JWT → POST /mailbox/api/v1/send. Rate-limited at twenty alerts per hour (the daily-report binary captures the full tally). Configurable per-recipient minimum severity. Public surface: send_alert_email(event, config).
NexusPulse (SMS)
SMS alerts via the NexusPulse platform using the built-in alert template. Idempotency keys per event ID. High-priority delivery for Critical events. Configurable minimum severity per recipient.
Webhooks (Slack, Discord, generic)
HTTP POST to multiple endpoints with per-webhook minimum severity. Slack uses emoji-coded severity headers; Discord uses embeds with colour-coded severity bars; generic mode posts the raw event JSON.
SIEM export (syslog, Elasticsearch, Splunk HEC, generic)
Multi-destination event export. Syslog (UDP / TCP, RFC 5424 structured data). Elasticsearch (bulk index API, NDJSON). Splunk HEC (HTTP Event Collector). Generic webhook (JSON). Every exported event includes its audit-chain hash so the downstream SIEM can verify chain integrity at query time. Per-destination batch size and flush interval tunable.
systemd journal
Structured journal entries with fields EVENT_TYPE, SOURCE_IP, THREAT_SCORE, EVENT_ID, CHAIN_HASH. Query: journalctl -u nexus-shield -o json.
Server-Sent Events
Real-time event stream at /events. Format: event: security · id: <uuid> · data: {...}. Fifteen-second keepalive. Replaces polling for any consumer that wants live updates.
Signature auto-update
The signature_updater module fetches malware signatures from a remote NDJSON feed on a configurable timer. Per-line JSON validation. Atomic writes (temp file + rename) so a partial fetch never corrupts the live signature set. Optional auth header for private feeds.
Configuration
A single TOML file at /etc/nexus-shield/config.toml drives everything. Sections map one-to-one with modules.
# Top-level
api_token = "<bearer-token>" # Optional. When set, all authenticated endpoints require it.
tls_cert = "/etc/nexus-shield/cert.pem" # Optional. Enables HTTPS via rustls.
tls_key = "/etc/nexus-shield/key.pem"
# Endpoint engine — toggle each module independently
[endpoint]
watcher = true
process_monitor = true
network_monitor = true
memory_scanner = true
rootkit_detector = true
dns_filter = false
usb_monitor = true
fim = true
[endpoint.watcher]
watch_paths = ["/etc", "/usr/bin", "/opt"]
exclude_patterns = ["node_modules", "target", ".git"]
max_file_size = 104857600 # 100 MB
debounce_ms = 300
[endpoint.dns_filter]
listen_addr = "127.0.0.1:5353"
upstream_dns = "8.8.8.8"
custom_blocklist = "~/.nexus-shield/threat-intel/domains.txt"
whitelist = []
[endpoint.fim]
poll_interval_ms = 60000
watch_dirs = ["/etc", "/usr/bin", "/sbin", "/bin"]
alert_on_new = true
alert_on_delete = true
alert_on_perm = true
[siem]
enabled = true
min_threat_score = 0.4
batch_size = 100
flush_interval_ms = 5000
[[siem.destinations]]
type = "syslog_udp"
target = "siem.example.com:514"
[[siem.destinations]]
type = "elasticsearch"
endpoint = "https://es.example.com/_bulk"
[ferrum_mail]
api_url = "https://ferrum-mail.com"
api_key = "<login-passphrase>"
from_address = "shield@automatanexus.com"
alert_recipients = ["devops@automatanexus.com"]
min_severity = "High"
[nexus_pulse]
api_url = "https://nexuspulse.example.com"
api_key = "<api-key>"
alert_recipients = ["+1234567890"]
min_severity = "Critical"
[[webhook_urls]]
url = "https://hooks.slack.com/services/..."
min_severity = "Medium"
webhook_type = "slack"
[signature_update]
feed_url = "https://signatures.example.com/latest.ndjson"
interval_secs = 3600
auth_header = "Bearer <token>"
Deployments
Three live deployments today. All three run from the same binary, the same configuration schema, the same audit-chain primitives.
Production application droplet
NexusShield runs in front of the production HTTP service on the AutomataNexus production droplet, in reverse-proxy mode (--upstream) with the endpoint engine enabled (--endpoint). Binds :8080. Audit chain persisted to disk; Prometheus metrics scraped by the internal observability stack.
Inbound mail relay (hetzner-mx)
The Postfix-based inbound mail relay runs NexusShield in standalone mode for the management endpoint and the host's endpoint protection. The shield's host-side modules are doing the heavy lifting here — process monitor, network monitor, FIM on Postfix configs, and DNS filter.
Developer laptops
Daily-driver developer laptops run NexusShield in --endpoint-only mode, with the gateway disabled. The developer-aware allowlist is the load-bearing feature here: the same workstation that's used to compile Rust, run npm, drive Docker, and rebase a thousand commits has zero false positives at idle.
Daily report (live since 2026-04-12)
The daily-report binary runs as a systemd timer at 07:00 UTC. It queries the running shield instance, builds an HTML summary mirroring the Ferrum Mail transactional palette (cream / teal / orange), and ships it via Ferrum to automatanexus@ferrum-mail.com and devops@automatanexus.com. Includes detection counts by category, threat-score distribution, top blocked source IPs, and a chain-integrity verdict.
Hardening posture
What the shield protects against versus how the shield itself should be deployed.
Recommended systemd unit
[Service]
ExecStart=/usr/local/bin/nexus-shield --config /etc/nexus-shield/config.toml --upstream http://127.0.0.1:3000 --endpoint
User=nexus-shield
Group=nexus-shield
PrivateTmp=yes
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ReadWritePaths=/var/lib/nexus-shield /var/log/nexus-shield
AmbientCapabilities=
CapabilityBoundingSet=
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
SystemCallFilter=@system-service
LockPersonality=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
RestrictNamespaces=yes
Always-on recommendations
- TLS via
--tls-cert+--tls-key, or a TLS-terminating reverse proxy in front (nginx, Caddy) - Bearer token required for every authenticated endpoint (set
api_tokenin config; fetch from NexusVault or a systemdLoadCredential=) - Dedicated user (no shared account; no shell)
- Audit chain persisted to disk so verification survives restarts
- Daily report enabled so missed incidents are visible by morning
- SIEM destination configured so events leave the host in case the host itself is compromised
Limitations
Five limitations of the current implementation are stated explicitly. They are direct consequences of the architectural decisions in Section 03 (Design rationale) and Section 02 (Threat model).
1 · No kernel-level visibility
The endpoint engine operates exclusively in user space. Adversary activity that bypasses standard syscall interfaces — kernel-mode rootkits, syscall-table manipulation, hardware-virtualisation-based hiding — is invisible to the system regardless of detector configuration. Mitigation: complementary deployment of kernel-attached integrity monitoring (e.g., AIDE, kernel-mode AV) for environments where this attack class is in scope.
2 · Tamper-evidence rather than tamper-resistance
The audit chain detects modification but does not prevent it. An adversary with sufficient privilege to rewrite the chain from event e0 can produce an internally-consistent chain that passes verify_chain(). Tamper-resistance requires external replication of the chain head to an out-of-band consumer that the host's adversary cannot reach. The SIEM destinations and systemd journal export paths support this pattern; their use is recommended for compliance-sensitive deployments.
3 · No protection against authorised insider misuse
The system records action attribution but does not implement access control. An authorised user with credentials valid at the protected application can perform any action the application permits; the audit chain establishes what they did but does not constrain them. Mitigation: NexusVault for credential isolation, application-level authorisation policy, and least-privilege identity-provider configuration are complementary controls.
4 · Encrypted-channel C2 detection is out of scope
Command-and-control traffic over TLS to benign-appearing destinations is not detectable without endpoint-side TLS interception, which the architecture explicitly excludes. Network-layer signals (timing-based beaconing detection in the network monitor; threat-intel-derived destination IP / domain matches in the DNS filter) provide partial coverage but are bypassable by adversaries adopting low-and-slow timing strategies and reputable hosting. Mitigation: out-of-band TLS-interception proxy at the network boundary.
5 · Detection-rule disclosure trade-off
The system intentionally does not enumerate threat-intelligence database contents, YARA rule bodies, SQL-firewall pattern sets, or threshold tuning across modules in this paper or in publicly distributed binaries. This preserves operational utility against signature-evasion attacks but prevents independent third-party academic verification of detection coverage. Mitigation: the architectural shape (parser-based detection, multi-signal scoring, hash-chained audit) is publishable and verifiable; specific rule sets are reviewed under non-disclosure for compliance audits.
Forward work
Three improvements are tracked. First, a Merkle-tree-backed audit log would permit efficient inclusion proofs without requiring a full chain re-walk, supporting larger event volumes than the current linear chain. Second, an eBPF-based optional kernel-visibility module could provide syscall-level observation for environments where the kernel-free deployment trade-off is unacceptable. Third, an in-process AST-level inspection layer for outbound database driver traffic would extend AST-based protection from inbound HTTP into the application's own outbound query path.
Metrics & events
Prometheus counters exposed at /metrics. Names are stable across versions.
| nexus_shield_audit_events_total | Total audit events appended. |
| nexus_shield_requests_blocked_total | Requests blocked by the threat scorer. |
| nexus_shield_sql_injection_total | SQL injection attempts detected. |
| nexus_shield_ssrf_total | SSRF attempts detected. |
| nexus_shield_chain_valid | 1 if audit chain verifies, 0 if broken. |
Event categories on the SSE stream are the same five that drive the audit chain: blocked, sql, ssrf, rate, threats.
Comparison with adjacent tools
| Capability | NexusShield | Typical WAF | OSSEC / Wazuh | EDR (commercial) |
|---|---|---|---|---|
| SQL injection detection | AST-level (sqlparser) | regex-level | — | partial |
| SSRF guard | URL-parse + IP validation | regex / blocklist | — | — |
| Adaptive rate limiting | 5-level escalation | token bucket | — | — |
| Hash-chained audit | SHA-256 by default | — | optional | varies |
| File integrity monitoring | built-in | — | built-in | built-in |
| YARA rules | pure-Rust engine | — | via libyara | via libyara |
| Container image scan | built-in | — | — | some |
| Supply-chain scan | built-in | — | — | some |
| Memory shellcode scan | built-in | — | — | built-in |
| Kernel module required | no | no | no | often yes |
| Single binary | yes | varies | no | no |
| Open source | yes (MIT) | varies | yes | no |
| Memory-safe runtime | Rust | varies | C | varies |
License
NexusShield is released under the MIT License. Use it in commercial products, modify it, distribute it. Include the copyright notice and license text in distributions. Optional enterprise services (priority support, custom development, on-site training, indemnification) available via enterprise@automatanexus.dev.
Detection rules redacted
The exact contents of the threat-intel database, the YARA rule bodies, the SQL-firewall pattern set, and the precise threshold tuning across modules are intentionally not enumerated in this paper. They live in the source tree and in the auto-update feed; publishing them here would only help attackers shape payloads to slip past specific signatures. The architectural surface — what each module looks at, what shape it returns, how the layers interact — is the public contract.
References
- Halfond, W. G. J., Viegas, J., and Orso, A. A Classification of SQL Injection Attacks and Countermeasures. In Proc. IEEE International Symposium on Secure Software Engineering (ISSSE), 2006.
- OWASP Foundation. OWASP Top 10:2021 — A03:2021 Injection; A10:2021 Server-Side Request Forgery. https://owasp.org/Top10/, 2021.
- Hernan, S., Lambert, S., Ostwald, T., and Shostack, A. Uncover Security Design Flaws Using The STRIDE Approach. MSDN Magazine, November 2006.
- Bellare, M., and Namprempre, C. Authenticated Encryption: Relations among Notions and Analysis of the Generic Composition Paradigm. Journal of Cryptology, vol. 21, no. 4, 2008. doi:10.1007/s00145-008-9026-x
- National Institute of Standards and Technology. NIST SP 800-38D — Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. 2007.
- Merkle, R. C. A Digital Signature Based on a Conventional Encryption Function. In Proc. CRYPTO 1987, LNCS 293, pp. 369–378. (Foundational hash-chain construction.)
- Andress, J. Foundations of Information Security. No Starch Press, 2019. ISBN 978-1-71850-004-4. (Defence-in-depth model.)
- Apache Software Foundation. sqlparser-rs: a SQL parser library for Rust. https://github.com/apache/datafusion-sqlparser-rs
- RustCrypto Contributors. aes-gcm: Pure-Rust AES-256-GCM Authenticated Encryption. https://github.com/RustCrypto/AEADs
- Smith, B. et al. ring: Safe, fast, small crypto using Rust. https://github.com/briansmith/ring
- Tokio Contributors. Axum: Ergonomic and modular web framework built with Tokio, Tower, and Hyper. https://github.com/tokio-rs/axum
- VirusTotal. YARA: The Pattern Matching Swiss Army Knife for Malware Researchers. https://virustotal.github.io/yara/, 2024.
- Cid, D. B. et al. OSSEC: Host-Based Intrusion Detection. Trend Micro, 2024. (Comparable file-integrity monitoring architecture.)
- Gerhards, R. RFC 5424 — The Syslog Protocol. Internet Engineering Task Force, March 2009.
- Elastic N.V. Bulk API. Elasticsearch Reference, 2024.
- Splunk Inc. HTTP Event Collector (HEC) Reference. Splunk Documentation, 2024.
- Provos, N., Mavrommatis, P., Rajab, M. A., and Monrose, F. All Your iFRAMEs Point to Us. In Proc. USENIX Security Symposium, 2008. (Drive-by-download landscape; relevant to URL/IP threat-intel feed design.)
Public surface only; detection rules, attack signatures, and threshold tuning intentionally omitted to preserve operational utility.