If you are reading this blog, odds are you are an System Administrator or at very least someone with technical skill and Linux knowledge. Following this train of thought, giving our connected world, leads us to the fact that you have used ssh at some point. And chances are you seen this prompt:
The authenticity of host 'mx1.alpha-labs.net (126.96.36.199)' can't be established. RSA key fingerprint is 50:88:9e:56:e9:2a:2f:d7:7f:e7:a9:3d:0f:23:9e:52. Are you sure you want to continue connecting (yes/no)?
Be honest: Did you ever really read this passage? I wager you typed “yes” to get on with the job at hand. This however, is a major security concern. You see, encryption is only awesome if you talk to the right person. What use is the most sophisticated encryption if you encrypt with your enemy?
You need to be sure you talk to the right guy, or in this case the right server. The fingerprint printed above should be checked against a trusted source, be it written, given in person or phone call. No one does this, period. So everyone is just typing yes — or even worse: Disabling this check altogether (please don’t).
Do you know DNSSEC? With a fully trusted path coming from the root name servers “.” across the tld registries (.net) all the way down to the local system administrator on fqdn level (alpha-labs.net) or even lower (mx1.alpha-labs.net).
The Solution – Server Side
You simply place your fingerprint inside a DNSSEC secured zone. Even better yet: The resource record for SSH fingerprints is (long) established as an sshfp record and ssh (clients) support dns checking with just one configuration line, if not enabled by default in your distribution. OpenSSH (Linux) does even come with a parameter to generate correct BIND zone entries:
[chris@mx1 ~]$ ssh-keygen -r `hostname -f`. mx1.alpha-labs.net. IN SSHFP 1 1 7dde5d066e43ed330241c36e10ae7fe2692cf38b mx1.alpha-labs.net. IN SSHFP 2 1 4abd9642060ff179d949fa3289b5db050df1fb10
“ssh-keygen -r” generates the bind zone resource records, it even generates one entry for every key(type) you have lying around. The “-r `hostname -f`.” sets the hostname for the DNS record and appends a single dot, needed for full bind compatibility. The resource record parts explained:
- Hostname for the record (mx1.alpha-labs.net)
- IN Internet Record,
- SSHFP Record Type
- Algorithm Specification (1 rsa, 2 dsa, 3 ecdsa)
- fingerprint type (1 sha-1, no others defined)
- The fingerprint itself
This is all you have to do on the server side.
The Solution – Client Side
This is so trivial, this is almost fun: Most Distributions ship with this enabled, if not simply add this line to /etc/ssh/ssh_config:
Possible options are:
- No, do not check DNS at all,
- Ask, Always ask, but say whether this key is (dns)trusted,
- Yes, always accept dns-trusted keys.
Take it for a spin
first, a dry run to check if your DNS is answering with the sshfp records:
~ $ dig sshfp mx1.alpha-labs.net +dnssec ; <<>> DiG 9.8.1-P1 <<>> sshfp mx1.alpha-labs.net +dnssec ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34991 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ;; QUESTION SECTION: ;mx1.alpha-labs.net. IN SSHFP ;; ANSWER SECTION: mx1.alpha-labs.net. 3599 IN SSHFP 1 1 7DDE5D066E43ED330241C36E10AE7FE2692CF38B mx1.alpha-labs.net. 3599 IN SSHFP 2 1 4ABD9642060FF179D949FA3289B5DB050DF1FB10 mx1.alpha-labs.net. 3599 IN RRSIG SSHFP 7 3 3600 [..] 2015043 [...]
The important things are in red: SSHFP resource records in the answer section and the tiny, tiny “ad” in the header meaning authenticated data. The ad is the confirmation that dnssec is working and fully trusted.
With this in place we can try connecting to the server, note that I deleted my know_hosts file, forcing verification of the key:
~ $ rm .ssh/known_hosts ~ $ ssh -v firstname.lastname@example.org OpenSSH_5.9p1 Debian-5ubuntu1.4, OpenSSL 1.0.1 14 Mar 2012 [...] debug1: Server host key: RSA 50:88:9e:56:e9:2a:2f:d7:7f:e7:a9:3d:0f:23:9e:52 debug1: found 2 secure fingerprints in DNS debug1: matching host key fingerprint found in DNS debug1: ssh_rsa_verify: signature correct [...] Last login: Thu Apr 30 15:19:04 2015 from shodan.alpha-labs.net [chris@mx1 ~]$
A direct login! No more “Yes, Sir!“!
Lets try a host where I rotated the ssh keys, resulting in a failed dns-trust:
~ $ ssh -v email@example.com OpenSSH_5.9p1 Debian-5ubuntu1.4, OpenSSL 1.0.1 14 Mar 2012 [...] debug1: Server host key: RSA a1:94:d0:48:8e:6c:90:4b:8a:e8:79:4f:09:64:a0:b3 debug1: found 2 secure fingerprints in DNS debug1: mismatching host key fingerprint found in DNS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the RSA key sent by the remote host is a1:94:d0:48:8e:6c:90:4b:8a:e8:79:4f:09:64:a0:b3. Please contact your system administrator. Update the SSHFP RR in DNS with the new host key to get rid of this message. debug1: checking without port identifier No RSA host key is known for [testing.alpha-labs.net]:22 and you have requested strict checking. Host key verification failed.
That’s it. No vodoo, not difficult. It’s all there from the start, RFC conform and ready to be used, leaving you no excuse to go back to “Yes, Sir!”.