dejima-devbox-hardener made a devbox report what changed. Everything it
reports goes to a log nobody reads: the node's firewall log, and the audit's
own output in a journal. A signal you never see is not detection, and calling
it one would be the same mistake as reporting a timeout as a pass.
This is the part that reads those reports and wakes somebody up.
ITS OWN REPOSITORY because it runs on neither of that project's two machines.
Shipping it inside the hardener would have put a program that must not run on
the devbox in the repository whose whole subject is the devbox.
THE INVERSION IS THE DESIGN. The guard reaches in; the devbox never reaches
out. That falls out of the firewall the devbox already has - inbound SSH from
the admin subnet is permitted, so no new rule is needed - and it buys three
things:
- the baseline lives here, so root on the devbox can lie about the current
state but cannot alter what this machine recorded last week;
- the alert leaves from here, so a compromised devbox can neither suppress
it by going quiet nor drown it by shouting;
- silence becomes a signal. A reporter running on the devbox and switched
off by whoever took it causes nothing to happen, forever. A collection
that stops arriving is itself the alarm, and it is the only mechanism
here a compromised machine cannot defeat by doing nothing.
Not a service: no port, no daemon, nothing inbound. A timer runs it, it makes
a few outbound connections, writes a file and exits - which is why it needs
no machine of its own, and why "another thing to harden" is not the trade.
NOTHING THE DEVBOX CONTROLS REACHES THE PHONE. Alert bodies are composed here
from a fixed vocabulary and counts. A compromised devbox controls every
filename and unit name, and interpolating one into a push hands it a channel
to the operator's phone - the thing dejima's own notification guarantee
exists to prevent, defeated one layer out. Detail stays in the local report.
The documented path is ntfy for alerts and an Uptime Kuma push monitor for
the dead-man's switch, both self-hosted. The alert topic is deliberately not
the one dejima publishes to: that URL lives on the devbox, so root there can
drown the topic or forge an all-clear.
Two bugs the tests found rather than review: `printf '%s\n' ""` writes a
newline, so an audit returning nothing passed a -s check and would have been
recorded as a baseline; and die() inside a command substitution ends the
subshell rather than the program, so a missing host produced an empty result
and the cycle carried on as though the box had answered.
`bats test/` 16 passing.