Skip to content

fix(firewall): close the firewall's own addresses to every segment, key-only sshd - #1503

Draft
Gerrrt wants to merge 1 commit into
mainfrom
gerrrt/morpheus-self-access-key-only
Draft

Gerrrt wants to merge 1 commit into
mainfrom
gerrrt/morpheus-self-access-key-only

Conversation

@Gerrrt

@Gerrrt Gerrrt commented Nov 14, 2026 •

Copy link
Copy Markdown
Owner

What changed

Every interface's Block SSH/HTTPS/HTTP to pfSense rows are to name This Firewall (self) instead of that interface's own address. Winterfell gains Allow SSH to pfSense from prometheus, and sshd goes to Public Key Only (ADR-0117). The firewall change is made in the pfSense UI by the new runbook, close-the-firewall-to-its-segments.md.

check_firewall_claims.py gains a second question: per interface, which of the firewall's own addresses a host there reaches on ssh, http and https. It evaluates the ruleset the way pf does, one address at a time, and names addresses by segment, WAN or link-local, never by number. Unknowns resolve toward "reachable". It also gets its first fixtures (11), which CI now runs through self-tests.sh.

Draft until the runbook is applied. firewall-claims.yaml declares the state after the change. Merged before that, the 08:15 homelab-firewall-claims timer fails. Run against today's firewall, the check prints 21 FAIL lines, one for every segment and port in the audit's finding.

Why

A read-only audit of morpheus on 2026-11-13 found two problems:

  • Every segment reached the admin UI and sshd on the WAN address. The per-interface blocks named only their own address, and the catch-all's to any carried the rest. From prometheus, HTTPS there answered 200 and port 22 gave a banner. network.md said Winterfell was blocked from the UI.
  • Hicks also reached both on 10.0.30.1, through Allow Hicks access to ImaginationLAN.

sshd accepted passwords. The existing claims check could not see any of this, because the WAN address is in no segment.

Blast radius

  • No change to network segmentation or firewall rules. It changes rules: three blocks per interface are re-pointed, Hicks' three move above its lab rule, and one pass is added on Winterfell.
  • No new port published to a VLAN that could not already reach the service
  • No credential added outside secrets/*.sops.yaml

If the Hicks rows go in the wrong order, the UI locks out from Hicks. The runbook gives two ways back: the console's Restore recent configuration, and the anti-lockout rule on the switch LAN. If the Winterfell pass is wrong, prometheus's collectors, the nightly export and this check lose SSH. Runbook §2.3 tests for that before going on. oracle and trinity lose port 22 on the firewall; nothing scheduled on either uses it. Key-only SSH locks out any machine whose key is not on admin, and §1 proves each key first.

Verification

  • make validate passes (5 local skips: worktree-only timer and unit checks and the tmpfs offsite refusal; CI runs them)
  • Deployed to the lab and confirmed working: not yet. This is the runbook, then make check-firewall from prometheus showing every line PASS.
  • Docs updated: network.md, security.md, firewall-claims.yaml, the changelog, ADR-0117 and the runbook

python3 scripts/check_firewall_claims.py --self-test: 11 PASS. --derive against the live firewall reproduces the audit by hand: Winterfell reaches only the WAN address on https and http. scripts/check_docs.py and scripts/lint.sh pass, with nothing skipped.

🤖 Generated with Claude Code

…ey-only sshd

Every interface's Block SSH/HTTPS/HTTP to pfSense rows named only that
interface's address, so every segment reached the admin UI and sshd on the
WAN address, and Hicks on the lab gateway too (2026-11-13 audit). ADR-0117
re-points them at This Firewall (self), adds a prometheus-only SSH pass on
Winterfell, and sets SSHd Key Only. The UI change is the new runbook.

check_firewall_claims.py now also asks which of the firewall's own
addresses each segment reaches on ssh, http and https, evaluated the way pf
does, with its first fixtures under self-tests.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant