Supply host fingerprint for openssh at execution time rather than in known_hosts

I have an ephemeral CI runner that needs to execute a command on a server I own/administrate. This runner is built and torn down each CI run, so I am trying to limit the statefulness of the runner, including the creation of files such as ~/.ssh/known_hosts. In the execution script on the CI runner I am supplying the secret key with ssh-add - <<< "${SSH_PRIVATE_KEY}" which adds the key to a running process rather than a file.

I know that openssh has options such as StrictHostKeyChecking=no which can avoid the fingerprint/pub-key checking, but this is an obvious security issue that I would like to avoid.

I am looking for an option in the openssh tool suite to supply a fingerprint/pub-key for that server as an argument to ssh while avoiding creating a known_hosts file. I am aware of ssh-keyscan remotehost, but that either needs to be directed into known_hosts (ideally avoided) or compared with the known pub-key in an if/then block before running the actual ssh command with an insecure StrictHostKeyChecking option (still open to MITM attack on second communication to server).

Does anything like ssh -o ExpectFingerprint=SHA256:KNOWNFINGERPRINT user@remotehost mycommand.sh exist to specify the "known host fingerprint" as part of the execution arguments? Given my security goals, do I have to use the known_hosts file on the short-lived CI runner?


Solution 1:

One alternative to having the host fingerprint stored in ~/.ssh/known_hosts or /etc/ssh/ssh_known_hosts is to have an SSHFP RR-record in the DNS. You need to run ssh-keygen on the server to create a set of record-entries that then needs to be added to the zone on your DNSSEC-enabled DNS-server: ssh-keygen -r host.example.com

To check that zone is answering fingerprint queries: dig -t SSHFP host.example.com

On the client you can then do this to connect to the server: ssh -o "VerifyHostKeyDNS=yes" host.example.com

See also SSHFP: Authenticate SSH Fingerprints via DNSSEC