7

我想做以下事情:

  1. 从我的开发机器创建 Digital Ocean 液滴(分发我的测试,这需要很长时间)。
  2. 安全地向液滴发出命令。
  3. 破坏液滴。

我被困在#2上。我可以通过 Digital Ocean API 成功创建 Droplet,并且可以在该区域设置我的 SSH 密钥authorized_keys,但是如果我允许 Digital Ocean 创建密钥,那么我无法验证服务器的公钥。

现在通常如果这是在同一个数据中心内,那就不用担心了,因为我可以依靠 Digital Ocean 不实施 MITM 攻击,因为它们无论如何都有根,但是由于我是从我的开发机器连接的,所以我需要一个信任公钥的方式。

我尝试了各种 cloud-init 指南,但总是收到错误消息:

ssh root@178.62.69.133
Connection closed by 178.62.69.133

我试图消除任何出错的可能性,我什至使用 base64 编码私钥,认为可能存在一些转义问题。

这是我用来创建密钥的命令:

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

扩展为:

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

然后我对它进行base64编码,

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

并将其放入 cloud-init yaml 文件中(不想使用|,因为它是 Yaml 中的特殊字符,我想尽可能避免使用它):

#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

(别担心,那个 ssh key/droplet 已经被破坏了,这是为了演示)

我可以验证,当我省略了成功运行的其余命令时echo test > /root/test。我也在我的本地机器上测试了这个并且 md5sums 匹配:

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

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

所以我知道我正在正确解码它们。

我尝试过其他密钥类型,但如果可能的话,我想使用 ecdsa 密钥,因为它是我其他盒子的默认设置。我在这里做错了什么?另外,我是唯一一个这样做的人吗?我有谷歌,看起来常见的答案是人们只是自动信任生成的公钥,如果你在做这个跨数据中心,我认为这很疯狂,因为任何随机的 ISP(或者,在我的情况下,咖啡馆)都可以被动地MITM你。

4

1 回答 1

3

我已经确定了解决方案!

犯了两个错误。第一个是这样的:

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

添加密码是我出于习惯而做的事情,但是机器当然一开始就不知道密码!所以这个-N #{password}位应该被删除到这个:

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

第二个错误是我没有设置密钥的权限!所以添加了以下两个命令:

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

runcmd

我真希望 Digital Ocean 能把钥匙还给我。如果您也这么认为,请在这里投票:https ://digitalocean.uservoice.com/forums/136585-digitalocean/suggestions/9307569-return-the-droplet-s-ssh-public-key-as-part-of-api

感谢@shazow 向我提出了正确的问题 :)

于 2015-08-21T22:59:17.533 回答