Is it possible to get/set SSH host key programatically?

January 15, 2017 1.3k views
Security API FreeBSD

It seems FreeBSD images does not support user-data, so I cannot set ssh host keys there myself. Is there either another way to set the host key or alternatively read the one generated at first boot programmatically?

The only way to do this I am aware of is to open the console for the droplet via the web interface and read the key there which pretty much defeats the purpose of using the api to programmatically provision droplets in the first place. Not verifying host keys is a terrible idea and a complete showstopper.

Alternatively, can console output somehow be scraped?

Thanks
Troels

5 Answers

Not sure if I got what you are looking for, but I use Terraform and it is able to provision a new FreeBSD droplet with a chosen SSH host key.

If you need the "raw" API endpoint have a look at https://developers.digitalocean.com/documentation/v2/#ssh-keys

Regards,

Nicholas

@tkjacobsen

I'd recommend looking at doctl - GitHub Repository - Usage Guide & Overview.

There's a specific section that deals with SSH Keys here.

Using doctl isn't limited to your local environment. You could deploy it to a web server and call on its functionality from there as well.

You can also pull the data down using JSON if you prefer and then store the output to a file, which could then be called by your application to do whatever needs to be done.

DigitalOcean's web based control panel provides a convenient, point-and-click interface for managing Droplets. There are many times, however, when a command-line tool may be a preferable alternative. doctl, the official DigitalOcean command-line client, leverages the DigitalOcean API to provide access to most account and Droplet features.
  • Thanks for the reply. However, doctl doesn't solve the issue as I still blindly have to type "yes" to accept the SSH host key unless I manually go into the web console and confirm it:

    % doctl compute ssh XXXXXX
    The authenticity of host '[IP] ([IP])' can't be established.
    ECDSA key fingerprint is SHA256YYY.
    No matching host key fingerprint found in DNS.
    Are you sure you want to continue connecting (yes/no)?
    

    As such, I cannot automatically create and start using hosts without having to manually confirm the key.

    • @tkjacobsen

      One way around having to manually confirm each key would be to create a config file in your ~/.ssh directory (i.e. ~/.ssh/config). Within that file, add:

      Host *
          StrictHostKeyChecking no
      

      This won't work if, for instance, you create a Droplet and then re-image it. You would need to clear your known_hosts file first, but then afterwards, it'll work again, or;

      Host *
          StrictHostKeyChecking no
          UserKnownHostsFile=/dev/null
      

      ... and it won't check known_hosts.

      It's a slightly less secure method as you're blindly accepting the keys, but it is one way. I did test this both remotely (on a DigitalOcean Droplet connecting to another Droplet) as well as locally on my MacBook Pro and it worked on both.

      • Hi again.

        Thanks for your suggestion. This will definitely work for development and test purposes. Though, I'm not sure I'm comfortable with this on a production system.

        Would be nice to see a way to at least fetch the console output via the API so I could grep for the key.

        Best regards
        Troels

        • @tkjacobsen

          No problem and I agree. The above is suitable for local deployments, though I'd be on the fence about using it on a production server unless it was fully locked down and access was restricted to either a certain IP or IP range.

          That being said, what exactly are you trying to do? From your last comment, you're wanting to successfully login and grep the key, though beyond that, what are you trying to do afterwards?

          If you can provide more details, I'll see if there's anything I can come up.

          • I'm trying to establish an offsite backup setup where an always-on Raspberry Pi I have at home once a day will do the following:

            1. Spin up a new FreeBSD droplet the API
            2. Do do some initial setup via SSH (change username, reset passwords passwords, install packages, setup firewall, etc.)
            3. Mount a geli-encrypted ZFS volume on the droplet via SSH (I will pipe key-file via SSH so it is never stored on the droplet)
            4. Run a backup-script that backs up all my online services to the ZFS volume (google drive, google mail, evernote, etc.)
            5. Take a snapshot of the ZFS volumen via SSH
            6. Unmount the ZFS volumen via SSH
            7. Shutdown and destroy the droplet via the API

            This way, I will only pay for the block storage and about 30 minutes of droplet use per day. With some light scripting, I've managed to make the setup pretty much work (what nice and simple API!) except for the ssh key. (I have it working in AWS where I inject a ssh host key via user-data but that doesn't work for FreeBSD on DO, unfortunately).

Not sure If I got what you are asking, but I use Terraform and it is able to provision a new FreeBSD droplet with a pre-configured SSH key.

The API it uses is: https://developers.digitalocean.com/documentation/v2/#ssh-keys

Regards,

Nicholas

Have another answer? Share your knowledge.