Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually set ssh host keys on server / Digital Ocean Droplet

I want to do the following:

  1. Create Digital Ocean droplets from my development machine (to distribute my tests, which are taking too long).
  2. Securely issue a commands to the droplet.
  3. Destroy the droplet.

I'm stuck on #2. I can successfully create the droplets through the Digital Ocean API, and I can set my SSH key in the authorized_keys area, but if I allow Digital Ocean to create the key then I have no way of verifying the server's public key.

Now normally if this were within the same data centre, it wouldn't be a concern, since I could rely on Digital Ocean not implementing a MITM attack because they have root anyway, but since I'm connecting from my development machine I need a way of trusting the public key.

I've tried following various cloud-init guides, but I always get the error:

ssh [email protected]
Connection closed by 178.62.69.133

I've tried to eliminate any possibility for error, I've even resorted to base64 encoding the private key, thinking that there might be some escaping issue.

This is the command I use to create the keys:

e = "ssh-keygen -t ecdsa-sha2-nistp256 -f #{loc} -q -N #{password} -C \"\""
system(e)

Which expands to this:

ssh-keygen -t ecdsa-sha2-nistp256 -f /tmp/testing-60f42fcf -q -N 77924d8f4fa12a365c8c003ca091f5ad6a2c4c22 -C ""

I then base64 encode it,

private_key = `base64 --wrap=0 #{loc}`.chomp
public_key = `base64 --wrap=0 #{loc}.pub`.chomp

and place it into the cloud-init yaml file (didn't want to use | because it is a special character in Yaml, and I wanted to avoid it if possible):

#cloud-config
---
runcmd:
- echo test > /root/test
- rm /etc/ssh/ssh_host*
- echo LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tClByb2MtVHlwZTogNCxFTkNSWVBURUQKREVLLUluZm86IEFFUy0xMjgtQ0JDLEY3MDNDNzM1QTAxQzgyNEVBRjhCODA4NkVDREIyMjAwCgpiYlpCa3A2Ujcyd1RRNUsyL2w4QW9YU3FQNllRVjV0aVJETytmU1FqZTlEUjY4MG9wY3RCRGhKRWdPQ0prSkw1CmhOUGxydzUveHFwTHM5UXc3cWJaWlUvRHR0YnlxZTFWUDcyVHBRS1pFL2FDcTdGTWFpbFJrcUpFa3JobVdCcFEKbWtQTW15M3BwVFZZKzJvRDZTdmMzdzZyTW1JTlpKUkltRUxiUk81S2M4bz0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
  > /tmp/base64_pri && base64 --decode /tmp/base64_pri > /etc/ssh/ssh_host_ecdsa_key
- echo ZWNkc2Etc2hhMi1uaXN0cDI1NiBBQUFBRTJWalpITmhMWE5vWVRJdGJtbHpkSEF5TlRZQUFBQUlibWx6ZEhBeU5UWUFBQUJCQkVHSDJBS3BVcVE0NVZQWGNFK3h5NXV6elVnajhKelBxODJNaERLV0szaGltUVBReWRPQ0RlRVdyRVJzeCtUTEtPSjBlRElJWU9jT2RWT0FteHZycG1nPSAK
  > /tmp/base64_pub && base64 --decode /tmp/base64_pub > /etc/ssh/ssh_host_ecdsa_key.pub
- sleep 1 && service ssh restart

(Don't worry, that ssh key / droplet has been destroyed, this is for demonstration purposes)

I can verify that when I leave out the rest of the commands that the echo test > /root/test runs successfully. I've also tested this on my local machine and the md5sums match:

028760a9374f9abd9c2c66eceb20f245  /tmp/pub_key_check
028760a9374f9abd9c2c66eceb20f245  /tmp/testing-60f42fcf.pub

2bf65516aaef01c731d061fa4ba788c5  /tmp/pri_key_check
2bf65516aaef01c731d061fa4ba788c5  /tmp/testing-60f42fcf

So I know I'm decoding them correctly.

I've tried other key types, but I'd like to use ecdsa keys if possible, because it is the default for my other boxes. What am I doing wrong here? Also, am I the only one doing this? I've Google around and it looks like the common answer is that people just auto-trust the generated public key which I think is insane if you are doing this cross data centre since any random ISP (or, in my case, cafe) could passively MITM you.

like image 338
zachaysan Avatar asked Aug 21 '15 16:08

zachaysan


1 Answers

I have determined the solution!

Two mistakes were made. The first was this:

e = "ssh-keygen -t ecdsa-sha2-nistp256 -f #{loc} -q -N #{password} -C \"\""

Adding a password is something I do out of habit, but of course the machine didn't know the password in the first place! so the -N #{password} bit should be removed to just this:

e = "ssh-keygen -t ecdsa-sha2-nistp256 -f #{loc} -q -C \"\""

The second error was that I didn't set the permissions on the key! So the following two commands were added:

- chmod 600 /etc/ssh/ssh_host_ecdsa_key
- chmod 644 /etc/ssh/ssh_host_ecdsa_key.pub

to the runcmd

I really wish that Digital Ocean would just return the keys. If you think so too upvote it here: https://digitalocean.uservoice.com/forums/136585-digitalocean/suggestions/9307569-return-the-droplet-s-ssh-public-key-as-part-of-api

Thanks to @shazow for asking me the right questions :)

like image 151
zachaysan Avatar answered Nov 15 '22 12:11

zachaysan