How do I validate the ECDSA key fingerprint of my newly-created Droplet?

October 25, 2017 393 views
Security Ubuntu 16.04

The first time I connect to a newly-created Droplet, I expect to be able to validate that the ECDSA key fingerprint is valid before adding it to my known_hosts file. I have not been able to find this information on the forum, how-to's, or in the web console.

I've read through How To Connect To Your Droplet with SSH, and the DO moderator surprisingly recommends disregarding the possibility of a man-in-the-middle attack and blindly accepting the key. The actual statement is as follows: "The first time you attempt to connect to your server, you will likely see a warning that looks like this... The authenticity of host ' (' can't be established... Go ahead and type yes to continue to connect. Here, your computer is telling you that the remote server is not recognized. Since this is your first time connecting, this is completely expected." I agree that it's expected. However, I don't agree that that means it's safe to assume that the connection is not compromised.

Back to my question then: Is there any way to validate the host's fingerprint before connecting? Ideally it would be part of the response body when a new droplet is created or have its own API call.

1 comment
1 Answer
asb MOD February 22, 2018
Accepted Answer

There are a number of methods you can use to verify the host keys on a Droplet. Each has some pros and cons.

The first way is to launch the web console while it is in the process of booting and view the output. This includes the key's fingerprint. It looks like:

Generating public/private ecdsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_ecdsa_key.
Your public key has been saved in /etc/ssh/
The key fingerprint is:
SHA256:Xsq8YwExqeayL+OFLq1hRL4o6I0SK7gzL9+in2bjPlc root@ubuntu-s-1vcpu-1gb-nyc3-01
The key's randomart image is:
+---[ECDSA 256]---+
|       .         |
|      +          |
| .   . o         |
|o   o .          |
| o o   .S .      |
|= o.. E+.o       |
|**.o..  =.       |
|&o&+.   o.       |
|*^XXo  ...       |

Unfortunately, that can be very hard to catch as it scrolls by.

The second option would be to log into the Droplet via the web console. This requires that you have a user with password authentication enabled. While you can disable this latter, I still consider this a major drawback. Once on the Droplet, you can check the fingerprint by running:

  • ssh-keygen -lf /etc/ssh/

DigitalOcean has support for cloud-init which enables another set of options for verify the host keys.

The first option utilizing cloud-init is generating a key locally and providing it via user data. One draw back to this approach is that the user-data is also served via the DigitalOcean metadata service. So any user on that specific Droplet could retrieve the key by running curl Here's an example:

  rsa_private: |
    -----END RSA PRIVATE KEY-----

Next, you can use the "phone home" module provided by cloud-init. This is probably the cleanest solution, but it requires that you have a service listening for callbacks. It allows you to provide a URL which will receive a POST containing the Droplet's public keys. You can limit it to only the ones you want, like so:

        - pub_key_ecdsa
        - instance_id

Another draw back to the above approach is that you can not modify the format of the content. So if the service requires a specific format (e.g. Slack's incoming webhooks), you'll need a different approach. This is what I've used to post the fingerprint to Slack:

    - DROPLET=`curl`
    - SSH_PUB_KEY=`ssh-keygen -lf /etc/ssh/`
    - |
        curl -X POST --data-urlencode "payload={\"text\": \"SSH Public key for Droplet $DROPLET\n$SSH_PUB_KEY\"}"

This fetches both the fingerprint and the Droplet's ID and POSTs them to a Slack URL in the required JSON format.

The DigitalOcean metadata service includes a field called "user-data", which can be used to specify a script that will be run as your server is brought online. The CloudInit program, which runs these scripts, can process a special script type called "cloud-config". In this guide, we'll explore how to create cloud-config files and the best ways to leverage their power.
Have another answer? Share your knowledge.