Skip to content

docs(phoenix): key-only sshd and a default-deny inbound policy (ADR-0117) - #1499

Open
Gerrrt wants to merge 2 commits into
mainfrom
gerrrt/phoenix-sshd-ufw-1496
Open

Gerrrt wants to merge 2 commits into
mainfrom
gerrrt/phoenix-sshd-ufw-1496

Conversation

@Gerrrt

@Gerrrt Gerrrt commented Nov 14, 2026

Copy link
Copy Markdown
Owner

What changed

ADR-0117 declares phoenix's own way in. sshd takes keys only: no password, no keyboard-interactive, no root, no X11. Inbound is default-deny with ufw, admitting 22 from Hicks and the tunnel's peers, the WireGuard port, and 8800 from VLAN 30 only while a Debian or Kali template builds. build-the-jumpbox.md gains §6a to apply it, in the order that cannot lock anyone out, with a check for each rule. open-the-remote-path.md §3 and build-the-lab-templates.md §5 gain their matching ufw lines. security.md, architecture.md and network.md state the decision and that it is not yet applied, and roadmap.md lists #1496. security.md's list of phoenix's secrets gains the five it was missing: the gandalf token and four LAB_* passwords.

Nothing is applied to the host by this PR. Nothing converges phoenix, so §6a is run by hand. Refs #1496.

Why

The 2026-11-13 audit of phoenix found the installer's PasswordAuthentication yes and no host firewall. That leaves sshd open to every address on VLAN 30, Hicks and the tunnel. phoenix holds the only key the lab domain accepts, so a password there undoes the key-only rule on the six. The repository never said what phoenix should accept, so the defaults stood. Tracked in #1496, milestone Nothing blocks these.

Blast radius

phoenix only, once §6a is run.

  • A workstation with no key in authorized_keys loses SSH to phoenix. §6a proves every key first, and the console in Saruman's UI is the fallback.

  • The tunnel's forwarding depends on the ufw route rule. Without it the handshake succeeds and nothing forwards. §6a and remote-path §3 both carry it, and the check is the ttl=63 ping.

  • Debian and Kali template builds need the 8800 rule, which is now required rather than conditional.

  • No change to network segmentation or firewall rules (no pf rule changes; this adds a host firewall on phoenix, narrowing who reaches it)

  • No new port published to a VLAN that could not already reach the service

  • No credential added outside secrets/*.sops.yaml

Verification

  • make validate: all checks passed, 38 skipped as not run (no Docker on phoenix).

  • python3 scripts/check_docs.py: docs OK.

  • ./scripts/lint.sh: passed, with 8 skipped (ruff, yamllint, ansible-lint, markdownlint, actionlint, zizmor, editorconfig-checker).

  • markdownlint-cli2 v0.24.1 via npx, not the pinned image, over the changed files: 0 issues.

  • make validate passes (locally, with the skips above)

  • Deployed to the lab and confirmed working (§6a not yet run on phoenix; Give phoenix a key-only sshd and a default-deny inbound policy #1496 stays open for it)

  • Docs updated (docs/, service README, or docs/roadmap.md)

🤖 Generated with Claude Code

…117)

phoenix holds the only key the lab domain accepts, and the repository never
said who may log in to phoenix itself. The 2026-11-13 audit found the
installer's password login and no host firewall. ADR-0117 decides the
following, and build-the-jumpbox.md section 6a applies it by hand, since
nothing converges phoenix:

- sshd takes keys only;
- ufw admits 22 from Hicks and the tunnel's peers, plus the WireGuard
  port;
- the tunnel's routing is left to morpheus, as ADR-0042 has it.

security.md's list of phoenix's secrets gains the gandalf token and four
LAB_* passwords it was missing.

Refs #1496.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings November 14, 2026 00:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The SSH lockout-prevention check can falsely pass by reusing an existing connection, and the network documentation incorrectly describes default-deny inbound as already deployed.

2 open issues
What changed in this PR

This documentation-only PR defines SSH and inbound firewall hardening for phoenix, the lab’s credential-bearing deployment host and WireGuard endpoint. Application remains manual and pending under #1496; this PR changes no host configuration.

Changes:

  • Adds ADR-0117 for key-only SSH and default-deny inbound access while preserving tunnel forwarding.
  • Adds an ordered hardening procedure and updates tunnel and template-build firewall instructions.
  • Updates security inventories, architecture references, roadmap tracking, and the ADR count.
File Description
README.md Updates the ADR count to 117.
docs/​security.md Documents the hardening decision, pending deployment, and missing credential inventory entries.
docs/​runbooks/​open-the-remote-path.md References the three required tunnel firewall rules.
docs/​runbooks/​build-the-lab-templates.md Requires temporary port 8800 access and subsequent removal.
docs/​runbooks/​build-the-jumpbox.md Adds key verification, SSH hardening, firewall setup, and access checks.
docs/​roadmap.md Tracks and prioritizes manual deployment under #1496.
docs/​network.md Describes the intended inbound access policy.
docs/​architecture.md Links the hardening decision and deployment task.
docs/​adr/​0117-give-phoenix-a-key-only-sshd-and-a-default-deny-inbound-policy.md Records the policy, rationale, alternatives, and operational consequences.
docs/​adr/​0043-keep-the-ca-on-prometheus-and-build-phoenix-as-the-deployment-host.md Adds an amendment reference while preserving the original decision text.

Review effort: Balanced

with passwords refused on the client side:

```bash
ssh -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no <user>@10.0.30.70 true && echo key-ok
Comment thread docs/network.md
Comment on lines +718 to +722
lab through it and nothing else. Inbound, it is default-deny
([ADR-0117](adr/0117-give-phoenix-a-key-only-sshd-and-a-default-deny-inbound-policy.md),
applied by [#1496](https://github.com/Gerrrt/HomeLab/issues/1496)). `22`
admits Hicks and the peers, and nothing else on this segment. `8800` opens
to the segment only while a Debian or Kali template builds. Its Alloy pushes to
@Gerrrt
Gerrrt enabled auto-merge (squash) November 14, 2026 06:39
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.

2 participants