Verifying BitFolk's SSH fingerprints

From BitFolk
Jump to navigation Jump to search

At some point or another you'll have a need to connect to a BitFolk host via SSH. For example, the Xen Shell is accessed via SSH. This article discusses how to verify the SSH fingerprints of BitFolk hosts.

SSH fingerprints

SSH uses public key cryptography to, amongst other things, verify that the host you're connecting to is really the host you intended to connect to. As is always the case with public key cryptography though, the initial key exchange has to be done by some other secure method. SSH displays fingerprints so that you can easily verify that you're connecting to the correct place. If you've ever seen something like this:

$ ssh strugglers.net
The authenticity of host 'strugglers.net (212.13.194.70)' can't be established.
RSA key fingerprint is 3d:34:13:36:9e:10:ac:20:5c:a6:38:fa:e8:3e:a0:2a.
Are you sure you want to continue connecting (yes/no)?

then you've seen an SSH fingerprint - it's the 3d:34:13:36:9e:10:ac:20:5c:a6:38:fa:e8:3e:a0:2a part.

In order to securely connect to the above host for the first time, you need to have been given the fingerprint in advance by some secure means so that you can compare it to the fingerprint that the server shows you. If you haven't then you are trusting DNS that this host is really the one that you intended to connect to. Most people just type yes and trust DNS.

SSH fingerprints of BitFolk hosts

The following examples assume that your BitFolk account name is "ruminant" and you're trying to connect to its Xen Shell host.

Verifying BitFolk SSH host fingerprints with SSH itself

All of the BitFolk hosts that customers are expected to ever SSH to have their SSH host fingerprints stored in DNS and secured by DNSSEC. So, if:

  • your local DNS resolver validates DNSSEC and;
  • you've configured your SSH client to do so;

then your SSH client can verify BitFolk's SSH host fingerprints by itself.

For OpenSSH the configuration option is VerifyHostKeyDNS and it defaults to no. You would normally set it in your client configuration file but it can also be set on the command line:

$ ssh -v -oVerifyHostKeyDNS=yes ruminant@ruminant.console.bitfolk.com
[…]
debug1: found 1 secure fingerprints in DNS
debug1: matching host key fingerprint found in DNS
[…]
This computer system is the property of BitFolk Ltd.

Disconnect NOW if you have not been expressly authorised to
use this system.  Unauthorised use is a criminal offence 
under the Computer Misuse Act 1990.

Communications on or through BitFolk's computer systems may
be monitored or recorded to secure effective system
operation and for other lawful purposes.

Password:

If you do not have a recursor performing DNSSEC validation you'll see something like:

$ ssh -v -oVerifyHostKeyDNS=yes ruminant@ruminant.console.bitfolk.com
[…]
debug1: found 1 insecure fingerprints in DNS
debug1: verify_host_key_dns: matched SSHFP type 1 fptype 2
debug1: matching host key fingerprint found in DNS
[…]
The authenticity of host 'ruminant.console.bitfolk.com (85.119.80.22)' can't be established.
RSA key fingerprint is SHA256:cO9wMH2pkR7Y4BVytdyydRFLfXtfvF9V2YZsK9io1M0.
Matching host key fingerprint found in DNS.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

At this point SSH has validated the host key via DNS, but not in a secure way, it then asks you the normal TOFU question with the extra line: "Matching host key fingerprint found in DNS."; it is up to you whether you trust it at this point.

Configuring VerifyHostKeyDNS for all hosts will result in an extra DNS lookup on each SSH connection. You may wish to add something like this to ~/.ssh/config:

Host *.console.bitfolk.com
  VerifyHostKeyDNS yes

Note that if you do not run your own DNS recursor (e.g. you use the one supplied by your ISP, a public DNS recursor or whatever the local network you happen to be on provides to you by DHCP) then it is theoretically possible that this recursor might lie to you about the DNSSEC-authenticated nature of the responses it gives you.

Manually checking the fingerprints from DNS

If your SSH client of choice does not support checking SSHFP records then you can check them yourself.

1. Query the SSHFP record

$ dig +nosplit -t sshfp ruminant.console.bitfolk.com

; <<>> DiG 9.11.3-1ubuntu1.18-Ubuntu <<>> +nosplit -t sshfp ruminant.console.bitfolk.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24933
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ruminant.console.bitfolk.com.  IN      SSHFP

;; ANSWER SECTION:
ruminant.console.bitfolk.com. 280 IN    CNAME   console.leffe.bitfolk.com.
console.leffe.bitfolk.com. 83080 IN     CNAME   leffe.bitfolk.com.
leffe.bitfolk.com.      83080   IN      SSHFP   1 2 70EF70307DA9911ED8E01572B5DCB275114B7D7B5FBC5F55D9866C2BD8A8D4CD

Here, the host key fingerprint is 70EF70307DA9911ED8E01572B5DCB275114B7D7B5FBC5F55D9866C2BD8A8D4CD. The ad part of the flags: line says that this is authenticated data. Without DNSSEC there would be no ad flag.

2. Check the fingerprint of what you are actually connecting to

Your SSH client should have some way of showing you the fingerprint of what you're trying to connect to. Newer versions of OpenSSH have a helper command ssh-keyscan for this:

$ ssh-keyscan -D ruminant.console.bitfolk.com
ruminant.console.bitfolk.com. IN SSHFP 1 1 1c77d9c17157f69df07285cb683db6c84455a636
ruminant.console.bitfolk.com. IN SSHFP 1 2 70ef70307da9911ed8e01572b5dcb275114b7d7b5fbc5f55d9866c2bd8a8d4cd

As you can see, 70ef70307da9911ed8e01572b5dcb275114b7d7b5fbc5f55d9866c2bd8a8d4cd and 70EF70307DA9911ED8E01572B5DCB275114B7D7B5FBC5F55D9866C2BD8A8D4CD are the same apart from case (which doesn't matter in DNS).

Only newer versions of ssh-keyscan support the -D option. It's a bit tricker but older versions can be made to display similar data:

$ ssh-keygen -r ruminant.console.bitfolk.com -f \
<(ssh-keyscan -t rsa ruminant.console.bitfolk.com 2>/dev/null \
| sed -r 's/^[^ ]+ //')
ruminant.console.bitfolk.com IN SSHFP 1 1 1c77d9c17157f69df07285cb683db6c84455a636
ruminant.console.bitfolk.com IN SSHFP 1 2 70ef70307da9911ed8e01572b5dcb275114b7d7b5fbc5f55d9866c2bd8a8d4cd

Here you are still trusting the SSHFP records in DNS, so you still have to trust that your local resolver validates DNSSEC.

Verifying BitFolk SSH host fingerprints with PGP

If you can't trust your local resolver to validate DNSSEC then here's an OpenPGP-signed text file listing the SSH fingerprints of BitFolk hosts you might care about:

You'll need to resolve the chain of hosts yourself to find out which real host your console alias is pointing at, e.g.:

$ host ruminant.console.bitfolk.com
ruminant.console.bitfolk.com is an alias for console.leffe.bitfolk.com.
console.leffe.bitfolk.com is an alias for leffe.bitfolk.com.
leffe.bitfolk.com has address 85.119.80.22
leffe.bitfolk.com has IPv6 address 2001:ba8:0:1f1::d

Fingerprints of the SSH host keys for your VPS

BitFolk cannot publish the fingerprints of the SSH host keys of your VPS because BitFolk doesn't know what host name you will be using to connect to it.

BitFolk could conceivably publish a host key for the IP address literal that you use to connect to your VPS for the first time, but this would change even more often than the console host mappings, so it would be a significant administrative burden.

For VPSes installed on your behalf, BitFolk does of course have access to the SSH host key and could communicate the fingerprint to you in your setup email, which is also OpenPGP-signed. That isn't yet implemented.

The very first time you want to connect to your new VPS, you can still work around this by instead first connecting to the Xen Shell, since this is a host whose key you can verify.

  1. If you don't have the password for your BitFolk account you can do a BitFolk password reset to have a new one generated and emailed to you.
  2. Work out what your real console host is.
  3. SSH to it and verify its host key by any of the methods above.
  4. Use the console command to connect to the console of your VPS
  5. Log in to your VPS and display its host key fingerprint
$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub 
1024 62:4a:83:f4:3c:b4:ed:e1:ea:00:7d:be:96:b1:e5:7d /etc/ssh/ssh_host_rsa_key.pub (RSA)