Skip to content

security: SSH host key verification with TOFU#10

Merged
deevus merged 6 commits intomainfrom
security/ssh-host-key-verification
Mar 5, 2026
Merged

security: SSH host key verification with TOFU#10
deevus merged 6 commits intomainfrom
security/ssh-host-key-verification

Conversation

@deevus
Copy link
Owner

@deevus deevus commented Mar 5, 2026

Summary

  • Replace StrictHostKeyChecking=no with accept-new mode using a pixels-managed ~/.config/pixels/known_hosts file — auto-accepts new hosts, rejects changed keys (MITM protection)
  • SSH connections now use the container hostname (px-<name>) instead of IP to avoid stale known_hosts entries from IP reuse across container churn
  • Lifecycle methods (Create, Start, RestoreSnapshot, Delete) clean up both hostname and IP entries from known_hosts

Test plan

  • go build && go test ./... && go vet ./... all pass
  • pixels create <name> creates a container and records its host key in ~/.config/pixels/known_hosts
  • Subsequent pixels exec <name> -- hostname connects without prompts
  • pixels destroy <name> removes the entry from known_hosts
  • Opt-out: setting strict_host_keys = false under [ssh] in config falls back to old behavior

🤖 Generated with Claude Code

Replace StrictHostKeyChecking=no with accept-new mode using a
pixels-managed known_hosts file at ~/.config/pixels/known_hosts.
SSH connections now use the container hostname (px-<name>) instead
of IP to avoid stale entries from IP reuse across container churn.

Lifecycle methods (Create, Start, RestoreSnapshot, Delete) clean up
both hostname and IP entries from known_hosts to prevent false
rejections. Opt out via strict_host_keys = false under [ssh] config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

⬇️ Go test coverage decreased from 30.3% to 25.1% compared to ec55944
⚠️ 1 of 10 packages have zero coverage.
  • github.com/deevus/pixels

Updated Package Coverages:

# Package Name                                |  Prior |    New
- github.com/deevus/pixels/internal/config    |  94.4% |  49.6%
- github.com/deevus/pixels/internal/provision |  79.1% |  78.4%
- github.com/deevus/pixels/internal/ssh       |  34.7% |  25.9%
- github.com/deevus/pixels/sandbox/truenas    |  69.1% |  41.3%
View coverage for all packages
# Package Name                                | Coverage
- github.com/deevus/pixels                    |     0.0%
+ github.com/deevus/pixels/cmd                |     6.5%
+ github.com/deevus/pixels/internal/config    |    49.6%
+ github.com/deevus/pixels/internal/egress    |    93.5%
+ github.com/deevus/pixels/internal/provision |    78.4%
+ github.com/deevus/pixels/internal/retry     |   100.0%
+ github.com/deevus/pixels/internal/ssh       |    25.9%
+ github.com/deevus/pixels/sandbox            |    83.3%
+ github.com/deevus/pixels/sandbox/incus      |     0.1%
+ github.com/deevus/pixels/sandbox/truenas    |    41.3%

deevus and others added 5 commits March 5, 2026 11:40
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add NewConnConfig constructor for secure-by-default ConnConfig
- Rename KnownHostsFile → KnownHostsPath (Go convention)
- Return *tnapi.VirtInstance from ensureRunning to avoid redundant API calls
- Rewrite RemoveKnownHost using golang.org/x/crypto/ssh instead of ssh-keygen
- Add defaultKnownHostsPath() fallback so Args() is always secure
- Replace silent error swallowing (_ = err) with warnf logging
- Fix provision.NewRunner to accept knownHostsPath parameter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace golang.org/x/crypto/ssh ParseKnownHosts loop with a simple
bytes.HasPrefix filter. We control the known_hosts file format, so
full crypto parsing is unnecessary. Removes the x/crypto dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DRY up the repeated remove-known-hosts-then-wait-ssh pattern across
Create, Start, RestoreSnapshot, and Delete in backend.go.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@deevus deevus merged commit 75eca6e into main Mar 5, 2026
2 checks passed
@deevus deevus deleted the security/ssh-host-key-verification branch March 5, 2026 01:21
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