Repository navigation
fix(lab): fence lab Grafana, BloodHound and scratch's UIs to Hicks - #1429
Merged
Merged
Conversation
Traffic inside VLAN 30 never crosses pfSense, so lab Grafana and BloodHound, and scratch's Wazuh dashboard and Velociraptor GUI, answered the whole segment, the weak domain included. Each is now expose-only, behind a Caddy that publishes the same host port, terminates TLS with the UI's own leaf, verifies the upstream against the CA, and answers Hicks's /24 alone: soc's #1139 shape. The READMEs and security.md follow. Closes #1428. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L2EweeKAdMf5A1aeFy1anN
4 of 6 tasks
Gerrrt
enabled auto-merge (squash)
November 11, 2026 21:24
Owner
Author
|
Lint failed on 3d2622b for a reason unrelated to this PR. There's no fix to port, because the cause is the registry. GitHub refused to re-run the job while the rest of the run was still going, so I'll re-run it once when the run finishes. Generated by Claude Code |
…d and scratch headers Validate configs' caddy fmt check failed on both new Caddyfiles for the one blank line between the header comment and the global block, which soc's Caddyfile does not have. Both adapted and provisioned already; only the format check failed. Local runs skipped it for want of a docker daemon. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L2EweeKAdMf5A1aeFy1anN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
soc's #1139 fence, applied to the three other web UIs on VLAN 30:
stacks/lab(alexander): Grafana isexpose-only. The existingcaddy(the ingest proxy) gains a:3443site, published on the host port Grafana had (GRAFANA_PORT, default 3000). It terminates TLS with Grafana's own leaf, verifies the upstream againstcertificates/ca.pemasgrafana(the SAN its cert carries), answersremote_ip 10.0.50.0/24, and returns403to everyone else. Caddy getsgroup_add: RENDER_GIDto read the 0640 key, the way Grafana reads it.stacks/bloodhound(eden): BloodHound isexpose-only. A newcaddy(bloodhound-ui-proxy) does the same onBLOODHOUND_PORT(8443), with BloodHound's leaf and upstream namebloodhound. It's hardened like the estate's Caddys: read-only,cap_drop: ALL, uid 65534, a 64m limit and a healthcheck.stacks/scratch(diabolos, not yet built): the dashboard and GUI are unpublished, and a newcaddy(scratch-ui-proxy) is soc's, minus the agent-MSI site, recorded as DIFFERENCE 6.security.mdthreat-table row next to the SOC UIs row.Why
Traffic between VLAN 30 hosts never crosses pfSense, so each of these answered the whole segment, the six deliberately weak domain guests included. BloodHound's graph is the domain's attack-path map, and diabolos is where samples are detonated. You decided these get fenced before the first red-team exercise (audit finding #9).
Closes #1428.
Not in this PR: the lab ingest proxy's plain HTTP (the other half of finding #9). It needs a server certificate on alexander and a trust change on six agents, so it gets its own issue and PR next.
Blast radius
alexander: the lab Caddy is also the ingest proxy. If it can't read Grafana's cert or key, it fails to start, and lab ingest from six agents stops until that's fixed. It reads the same files Grafana already reads, through the same group, so I expect it to start. Check
docker logs lab-ingest-proxyafter the nextmake up STACK=lab.Reachability: Grafana and BloodHound now answer Hicks only. A WireGuard peer or any other VLAN that reached them before gets
403. I found nothing server-side that probes either port; Glance's link is a browser link used from Hicks.scratch: not deployed anywhere yet.
No change to network segmentation or firewall rules (pfSense untouched; this is in-guest source filtering)
No new port published to a VLAN that could not already reach the service (the same host ports, now narrower)
No credential added outside
secrets/*.sops.yamlVerification
make validate: exit 0, 164 PASS, 0 FAIL, 41 SKIP. That's two more SKIPs thanmain, and they're the point:bloodhoundandscratchnow have Caddyfiles, so theirno Caddyfile — nothing to validatePASSes becameno docker daemon — Caddyfile uncheckedSKIPs.caddy validateandcaddy fmton all three Caddyfiles are skipped here and run in CI (the Validate Caddyfiles step, underrequire-no-skip.sh).I parsed the three compose files: each
caddypublishes the expected host ports (lab: 9090, 3100 on the ingest address, plusGRAFANA_PORT→3443; bloodhound:BLOODHOUND_PORT→8443; scratch: 443→8443, 8889→8889).The Caddyfiles are tab-indented, matching
caddy fmt.editorconfig-checkeris clean on all changed files.markdownlint-cli20.24.0 found 0 issues.check_docs.pypassed.Not provable here: a live request from Hicks (200) versus one from VLAN 30 (403). That's for after deploy, on alexander and eden:
curl -k https://10.0.30.40:3000/api/healthfrom Hicks, and the same from a lab guest, which should get403.make validatepasses (with the skips above)Deployed to the lab and confirmed working (the two curl checks above, on alexander and eden)
Docs updated (three stack READMEs,
docs/security.md)Generated by Claude Code