Silent by default.
Loud when it matters.

A small security daemon for Linux servers. It watches processes, logins and network activity, and only speaks up when something looks like a real compromise: in your logs, Telegram, email or a webhook. No dashboard, no central server.

Beta · v0.1.0-beta.7Rust · eBPFApache-2.0

Process chains D1

A web server or database spawning a shell. Downloads that get executed. Programs running from /tmp or straight from memory.

systemdpid 1nginx · www-datapid 1842bashpid 3107curlpid 3109sh /tmp/.x.shpid 3110match · D1 · unattended exec from a web-server chainCRITICAL

SSH & auth D2

A login right after a brute-force burst. Root and first-time sources, SSH config and account changes.

deploy@10.0.0.4okroot@45.x.x.xroot loginops@10.0.0.9oksshd_config editHIGH

Persistence D3

Cron, systemd, SSH keys. Shell profiles, PAM, udev and the other ways back in.

Privilege escalation D4

New setuid files, ptrace, LD_PRELOAD and sudoers changes.

Network in context D5

Connections from a flagged chain. New destinations and new listening ports.

Five groups, one goal. Catch a real compromise, not everyday admin work.

How it decides

Thousands of events in. One alert out.

Kernel eventsexecve · connect · ptraceHost signals/proc · inotify · auth log · PAMContextprocess tree · operator sessionDetection rulesD1 · D2 · D3 · D4 · D5SeverityINFO → LOW → HIGH → CRITICAL1 ALERTKernel eventsexecve · connect ·ptraceHost signals/proc · inotify ·auth log · PAMContextprocess tree ·operator sessionDetection rulesD1 · D2 · D3 · D4 · D5SeverityINFO → LOW → HIGH →CRITICAL1 ALERT

Investigate from the terminal.

$ sudo hermian alerts -s high
HER-2026-1015-210  HIGH      Root login from a new source
HER-2026-1006-415  CRITICAL  Web server chain ran downloaded code
journald has the rest · --json for scripts
$ sudo hermian show HER-2026-1006-415
■■■■ HERMIAN - CRITICAL     Host : web-01
Web server chain ran downloaded code
Chain  nginx → sh → curl → /tmp/.x
Also   Isolate the host unless this is expected.
$ sudo hermian collect HER-2026-0921-001
✓ local context gathered for this alert
nothing is uploaded · it stays on the host
$ sudo hermian blocked
$ sudo hermian unblock <ip>
Telegram buttons block a source or disconnect a session
$ sudo hermian isolate
# needs management CIDRs configured first
# auto-isolation is opt-in and reverts on a timer

One command. Verified before it installs.

curl -fsSL https://github.com/hermian-security/hermian/releases/download/v0.1.0-beta.7/install.sh | sudo sh

The script comes from the release it installs. It uses the .deb on Debian and Ubuntu and the tarball everywhere else, always checks SHA256SUMS, and verifies where the release came from with cosign or gh if you have either. Without them it tells you, and relies on the checksum. Rather read it first? Download install.sh from the release, check it, then run it.

Verify manually
VER=v0.1.0-beta.7
BASE=https://github.com/hermian-security/hermian/releases/download/$VER
curl -fsSLO "$BASE/SHA256SUMS" "$BASE/SHA256SUMS.sigstore"
cosign verify-blob SHA256SUMS \
  --bundle SHA256SUMS.sigstore \
  --certificate-identity \
  "https://github.com/hermian-security/hermian/.github/workflows/release.yml@refs/tags/$VER" \
  --certificate-oidc-issuer \
  https://token.actions.githubusercontent.com
VER=v0.1.0-beta.7
BASE=https://github.com/hermian-security/hermian/releases/download/$VER
curl -fsSLO "$BASE/SHA256SUMS"
DEB=$(grep -o "hermian_.*_$(dpkg --print-architecture)\.deb" SHA256SUMS)
curl -fsSLO "$BASE/$DEB" && sha256sum -c SHA256SUMS --ignore-missing
gh attestation verify "$DEB" --repo hermian-security/hermian # optional
sudo apt install "./$DEB"

# any systemd distro: untar hermian-*-linux-*.tar.gz, then:
sudo sh install.sh

sudo hermian status
sudo hermian test
SHA256SUMS always checkedsystemdkernel 5.4+eBPF on 5.8+amd64 · arm64 buildsField-tested on Ubuntu 22.04APT repo planned

Upgrade: rerun the installer for the new tag. Uninstall: sudo hermian uninstall.

Hear about it only when it counts.

Telegram

Alerts in your chat, with optional buttons on login alerts.

Hermiannow■■■□ HIGH · web-01SSH login after afailed-auth burstIgnoreDisconnect sessionDisconnect and block

Email

Through SMTP or the local sendmail.

[HERMIAN] CRITICAL D1 | web-01Web server chain ran downloaded codenow[HERMIAN] HIGH D3 | web-02SSH key added with no session present12m[HERMIAN] HIGH D2 | db-01Root login from a new source1h

Webhook

Slack, Discord, ntfy, or plain JSON.

POST /hooks/hermian{"severity": "CRITICAL""detection": "D1"}

journald + file

Always on, even with nothing else set up.

/var/log/hermian/alerts.log14:32:11CRITD1 chain nginx → sh14:28:03HIGHD3 cron, no session14:19:40INFOD2 sshd_config edit14:02:17INFOHERMIAN is active13:58:09INFOD2 SSH auth burst
■■■■ HERMIAN - CRITICAL
Host : web-01

- Web server chain ran downloaded code :

nginx started a shell that downloaded a file and is now running it as www-data.

Chain  nginx → sh → curl → /tmp/.x
File   /tmp/.x
━━━━━━━━━━━━━━━━
Web servers don't normally spawn shells. The chain then downloaded a file from the internet, which is the shape of a web shell dropped on a vulnerable app.

Also
1. Isolate the host unless this is expected.
━━━━━━━━━━━━━━━━
hermian show HER-2026-1006-415
A real alert

Short enough to read on your phone.

  • What happened, in a sentence or two
  • The process chain and the file involved
  • Why it matters, in plain words
  • What to do next
  • A reference for the full record: hermian show

Chat gets the short version. The CLI keeps the full evidence.

HIGH+ notifies by defaultAt-least-once delivery500-alert disk queue per channelSurvives restartsDead-man switch via systemd timer

Telegram buttons are optional and only appear on SSH login alerts and the brute-force digest: Block, Ignore, Disconnect session, Disconnect and block. Only the Telegram users you list can press them; anyone else is refused and logged.

Evidence

Numbers, with receipts. Beta, validated on one host.

7/7

Attack scenarios

Fired at the expected severity on the burn-in host.

0

HIGH+ false positives

Across 26 admin and unattended operations.

0.1%

CPU · 19 MB RSS

About 80k events over 3 hours.

0%100% of one core
~2s

Detection to Telegram

One measured run, not a percentile.

event400 ms debounceTelegram ~2 s
158 core tests103 daemon testsCI on every changeProduction VPS soaking since 2026-09-20Dead-man switch exercised live

Every figure comes from docs/EVIDENCE.md. If a number isn't there, it's unproven. See also the false-positive log and the burn-in matrix.

Compare

How it compares. Honestly.

HERMIANWazuhFalcoauditd
Where Hermian is simpler
SetupOne commandManager, indexer, dashboard, agentsDriver, rules, output wiringWrite rules, parse logs yourself
Central server requiredNoYesNoNo
Ready for one host, out of the boxFive detection groups, on by defaultLarge ruleset you tuneContainer-first defaultsNone, logging only
Plain-language alert, in chatChain, why it matters, next stepVia integrationsVia Falcosidekick—
Context-aware severityKnows operator sessionsPer-rule levelsPer-rule priorities—
Response from the alertOpt-in Telegram buttonsServer-driven active responseVia add-ons—
Where the others lead
Containers and Kubernetes—YesCore strengthHost only
Fleet management and compliance—YesPartial—
MaturityBeta, one host validatedMatureCNCF graduatedLinux kernel standard

Default setups compared; each of these can be extended. Wazuh and Falco are the better fit for fleets and containers. Hermian is for hosts you look after yourself.

Before you install

Know what it is. And what it isn't.

Who it's for

  • A VPS, a homelab, or a few servers you look after yourself
  • Alerts in chat or logs, not another dashboard or account
  • Opt-in response: block a source, disconnect a session, or auto-isolate CRITICAL events

Who it isn't for

  • Containers and Kubernetes: it watches the host, not pods
  • Fleets: no central console, policy management or compliance reports
  • Hosts you can't test first: the burn-in matrix isn't finished
Known limitsUbuntu 22.04 so farSees what it hooksAt-least-once deliveryLocal dead-man switchIsolation isn't a cutoffRoot owns the boxDetails
LIMIT 01One distro so farOnly Ubuntu 22.04 has run it in the field. RHEL/SELinux, the older-kernel fallback and arm64 are untested.
LIMIT 02It sees what it hooksIt only watches kernel and log sources. Anything outside them is invisible, and one incident can trigger more than one rule.
LIMIT 03At-least-once deliveryAlerts queue on disk per channel (500 each) and survive restarts. A crash mid-send can duplicate one.
LIMIT 04The dead-man switch is localA systemd timer pages on a stale heartbeat and restarts the daemon. It isn't an out-of-band monitor.
LIMIT 05Isolation isn't a cutoffIt's an nftables ruleset with documented exceptions, so alerts still go out. Automatic isolation can lift itself on a timer.
LIMIT 06Root owns the boxLocal hashes detect changes. They don't stop someone who already has root.
Open source

Read it. Build it. Break it.

It's a beta with one maintainer, validated on one host so far. Parts of the code, tests and docs are written with AI help; every merge and release is done by hand (AGENTS.md).

Community

Built in the open. Come say hi.

Install it. Forget it. Hear from it when it matters.

Passiveby defaultSignedreleasesApache-2.0licensed