Repository navigation
Description
docs/security.md states Suricata's three limits plainly: alert-only, two
segments, and plaintext only. ADR-0006
put it on morpheus because the firewall is the only device that sees IoT and
guest — which is right, and which is also why it cannot see the traffic this
issue is about.
Every technique ADR-0029
built the domain to exercise is layer 2 or intra-segment. LLMNR and NBT-NS
poisoning, NTLM relay, Kerberoasting, ARP spoofing — none of it crosses the
router, so morpheus never sees a packet of it. This is
ADR-0014's
own argument for why ifrit is layer-2 adjacent to its targets, applied to
detection instead of attack.
Zeek is not a second Suricata. It is a protocol logger — conn, dns, http,
ssl, files, x509. Two things follow that matter here:
- It reads TLS metadata without decrypting — SNI, JA3/JA3S, certificate
subjects and issuers. That is precisely the ground Suricata's "plaintext only"
limit gives up, and where C2 detection actually lives. - It sees east-west traffic between the six domain guests, which nothing in
this estate currently observes at all.
What this needs on the hypervisor, and it is the awkward part
Saruman's lab bridge is a Linux bridge. Port mirroring needs Open
vSwitch. Converting it touches the box whose own firewall ADR-0014 leans on,
so it is a decision in its own right and belongs in this issue's discussion
rather than in a commit.
The trap, and the estate's own answer to it
A mirror port does not survive a reboot of the hypervisor. A systemd unit
recreates it — but a unit that silently stopped is exactly the
"healthy-looking metric with nothing underneath it" failure this repository
keeps finding one level up each time
(#62,
#63,
#305, the UPS pack).
So the unit ships with a homelab_zeek_mirror_active textfile gauge, in the
exporter-less pattern scripts/run-scheduled.sh and scripts/collect-*.sh
already establish: no new service, no new image, no new port, no new privilege.
Then reboot Saruman and confirm the gauge goes to zero and an alert fires.
If it does not, the unit is decorative.
Where the logs go
The lab's Loki on alexander, never 10.0.99.20. ADR-0007's "lab telemetry
stays in the lab" governs, and #88's
amendment covers the hypervisor's own agent only.
What it waits on
#414. A sensor pointed at a
segment with one guest on it has nothing to say; the six-guest domain is what
makes east-west traffic exist.
Purchases this needs
None. A guest on Saruman, roughly 4 vCPU / 8 GB, plus a data disk.
Corrected 2026-09-19
Two things settled after filing that lived only in a comment:
- This issue owns Zeek's absence detection, inherited from Alert on a sensor that stops logging: absence rules for Suricata and Zeek #441 when it closed 2026-09-17 — and the answer is the
homelab_zeek_mirror_activegauge with a promtool test and the reboot proof, not a Loki rule.docs/security.mdandroadmap.mdalready say so. - It does not depend on Swap the MokerLink for the CRS326 (ADR-0041) #444. The mirror here is an Open vSwitch mirror on
Saruman's own bridge, not a SPAN fromneo(ADR-0039 says so in terms); ADR-0041 keeps the CRS326's mirroring disabled per ADR-0006. The new switch changes nothing here.
Gate stays #414. The Ubuntu template #440 would build for this guest is a Wave-later item; this guest can be built by hand first.
Activity
docs(adr): ADR-0039 — decline Proxmox clustering while ifrit is the r…
docs(adr): ADR-0039 — decline Proxmox clustering while ifrit is the r…
Gerrrt commentedon Sep 17, 2026
This issue now owns Zeek absence-detection. #441 asked for a
ZeekLogsStoppedLoki rule "the same shape against the lab's Loki, once #437 exists". It has been closed, and this is where the question lands instead — a note so the next person does not re-derive it.Why it cannot be a Loki rule here. Three constraints, all already decided:
alexanderand never on10.0.99.20— ADR-0007 requires it, and ADR-0039 reaffirms it by keeping the mirror onSaruman's own bridge rather than a SPAN fromneo.stacks/lab/no Alertmanager on purpose: "nothing in the lab pages." Sostacks/lab/loki/ships no ruler and norules/directory, and its config says why — "a ruler with nowhere to deliver evaluates rules and discards the result, which reads as coverage and is not."A rule in the lab's Loki would evaluate and discard; one in the estate's Loki would need log data ADR-0007 forbids crossing.
Why this issue already solves it. The
homelab_zeek_mirror_activetextfile gauge in the plan above is the answer — read on the hypervisor by the agent that is already there, crossing as hypervisor state under ADR-0028, with the alert on the estate's Prometheus. It is there because a mirror port does not survive a reboot, and it happens to be the same instrument the absence question needs. Nothing extra to build.Two things to carry into the build, both from #441's experience:
promtoolunit test. A stack with rules and no tests is a CI failure, and the reason is ContainerHighMemory cannot fire — no service sets a memory limit #63 — a rule that cannot fire passescheck rules. That gate is why the Suricata half has one and its Loki twin does not.Saruman, confirm the gauge goes to zero and the alert arrives; otherwise the unit is decorative, which is the failure this repo keeps finding one level up.No change to this issue's scope or milestone — just recording where the question went.
Gerrrt commentedon Sep 26, 2026
2026-09-26: The gate has cleared. #414's six guests have been up and joined since 2026-09-25. What's left is this issue's own decision (converting
Saruman's lab bridge to Open vSwitch) and then the build. It still doesn't depend on #444 (ADR-0039, and the 2026-09-19 correction above).roadmap.mdsaid otherwise, and #670 corrects it.Merge origin/main into the Zeek mirror branch (#437)
feat(soc): mirror the lab bridge to Zeek with tc, and a gauge that pr…
style(sensor): zeek.alloy as alloy fmt writes it, so Validate configs…
fix(soc): #762's two lint failures — the tc fixture's tabs as \t, and…
docs(runbook): §2 installs from the 26.04.1 ISO the host has, and fen…
docs(runbook): build-the-sensor-guest §1 as it was run — ifup, not if…
docs(architecture): Saruman's row lists the ten guests it hosts (#437)
docs: fenrir is built and #437's reboot proof passed (#437) (#774)
docs(runbook): a non-ens19 capture NIC changes the offload unit too (#…
fix(sensor): fenrir's 8% capture loss was GRO reordering; offloads of…
feat(sensor): vendor FoxIO's JA4+ scripts into stacks/sensor (#776) (#…
docs(sensor): the compose header says make up, and that fenrir is built
docs(sensor): the runbook has #437's reboot test; the changelog has i…
docs(sensor): the compose header says make up, and that fenrir is bui…