Auto-add unknown jump host keys, on by default #66
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
keyop-go/nfq_forwarder!66
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue17_unknown_host_keys"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #17 (https://gitlab.keyop.co.uk/keyop/go/nfq_forwarder/-/issues/17).
Background
Connecting to a jump host with no
known_hostsentry at all currently fails outright:requiring the host's key to be added manually (e.g. via
ssh-keyscan, orssh-ing to it once)before
nfq_forwardercan be used against it at all. This is reasonable, safe-by-defaultbehavior, but inconvenient - this MR makes it optional (and off by default, i.e. auto-add on).
Fix
golang.org/x/crypto/ssh/knownhostsalready distinguishes the two cases this needs treateddifferently, via
*knownhosts.KeyError.Want:the signal of a possible MITM attack.
sshtunnel.Dial'sHostKeyCallbacknow wrapsknownhosts.New's own callback(
buildHostKeyCallback): on an empty-WantKeyError, it appends a new line toknown_hosts(
knownhosts.Line, the same helper the file format is built from) and accepts the connection,logging that it did so; on anything else - including a real mismatch - the error is returned
unchanged and the connection is refused, exactly as today. A changed key is never
auto-corrected, regardless of this setting.
ssh_strict_host_key_checking(Configuration.SSHStrictHostKeyChecking),a global setting alongside
ssh_key_path/known_hosts_path. Named after OpenSSH's ownwell-known option for the same behavior. Defaults to
false(auto-add on) -deliberately phrased as the "strict" opt-in so Go's normal zero-value already matches the
wanted default, with no special defaulting logic needed in
config.LoadFromFile. Appliesuniformly to both the
--configYAML and legacy CLI-flags paths.known_hosts_pathis now created automatically (empty) when it doesn't already exist andauto-add is enabled (
ensureFileExists) - a brand new setup that's never manuallyssh'danywhere works out of the box, no manual
touch known_hostsneeded first. Withssh_strict_host_key_checking: true, a missing file remains a hard error, matching thatsetting's explicit intent that every key must already be recorded.
Testing
Pure
knownhosts-package logic plus file I/O, so no live SSH handshake is needed -internal/sshtunnel/hostkey_test.gobuilds realssh.PublicKeyvalues (fresh ed25519 keys) andtemp
known_hostsfiles/paths directly:a genuinely unknown host's key is added, and a second, fresh callback built from the
now-updated file also accepts it (round-trip proof, not just "a line got written");
a host already known with a different key is still rejected, and the file is left
byte-for-byte unmodified (the critical security case);
a host already known with the matching key is accepted, unaffected by this change;
with
ssh_strict_host_key_checking: true, an unknown host is still rejected exactly astoday, and the file is left unmodified;
a missing
known_hostsfile is created automatically when auto-add is enabled (and the newlycreated file works correctly for a subsequent check), but remains a hard error in strict mode
(and the file is not created in that case);
ensureFileExistsitself is unit tested directly: creates when missing, leaves an existingfile's content untouched, and a missing parent directory is still a real error;
appendKnownHostKey's open-failure path (e.g. path is a directory) returns an error ratherthan panicking.
go build ./...,go vet ./...make lint(golangci-lint + yamllint)make test(go test -race -cover ./...)Manual sanity check:
docs/config.example.yamlloadsssh_strict_host_key_checking: falsecorrectly viaconfig.LoadFromFileDocs
Updated
README.md,docs/README.md,docs/config.example.yaml, andCLAUDE.md(Designnotes + Testing sections).
added 1 commit
1a791604- Pre-create known_hosts when auto-adding unknown host keysCompare with previous version
changed the description
mentioned in issue #17
added 1 commit
4810b624- Updated notes with redacted gitlab tokens.Compare with previous version
approved this merge request
requested review from @danny
assigned to @danny
mentioned in commit 79f9e6ba9e02eca23090f98a3aad381875fafbf1
mentioned in commit
8d3e7b8280