使用EC2 Userdata为丢失密钥的EC2更换密钥

一、背景

AWS云上EC2默认使用比密码认证更安全的密钥登录方式,并且默认不允许SSH密码验证。于此同时,为了提升安全性,密钥一旦创建好只允许下载一次。一旦密钥被下载过,AWS控制台上不再提下载按钮。因此保存密钥就成了一项非常重要的工作。

在一台已经登录上的EC2上,可以访问EC2的元数据来获取当前EC2使用的是哪一个密钥。

curl http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key

如果丢失了密钥,现有EC2将无法登录。

如果希望抢救这台EC2并更换为新的密钥,则可以采取如下的方法:

  • 1)使用非SSH的其他任意办法登录到EC2上,修改EC2上的/home/ec2-user/.ssh/authorized_keys文件,将新的公钥补充进入。可采用的修改办法又包括:
    • 在已经安装了System Manager Agent的EC2上使用Session Manager自动登录,然后修改authorized_keys文件;
    • 使用EBS Recovery的办法,将本EC2的磁盘挂载到其他服务器上,并替换authorized_keys文件;
  • 2)使用EC2 Userdata在EC2启动时候自动替换authorized_keys文件。

本文将介绍方法2。同时方法2还有一个前提,需要具备有登录AWS控制台的IAM user和并具有对EC2的Full Access,可以通过Userdata脚本的方式更换密钥。

具体方法如下。

二、创建新的私钥并获得公钥

首先你如EC2界面,在左侧Network & Security菜单中找到Key Pairs,在此创建一个新的密钥。

重新创建新的密钥时候,界面提示选择密钥类型是RSA还是ED25519。ED25519是由一套比RSA更安全的随机数算法生成的,但是仅支持Linux和Mac,不支持Windows上的Putty,也不支持EC2控制台界面上的EC2 Instance Connect功能(此连接方式目前仅AWS海外提供,中国区未提供)。请酌情选择。

创建完毕,将密钥下载到本地后,在Linux或MacOS上执行如下命令:

chmod 400 newkey.pem
ssh-keygen -y -f newkey.pem

这里请注意先私钥文件权限改为400,执行第二条命令。否则ssh会提示权限错误拒绝执行。

即可查询本私钥对应的公钥,例如返回的公钥信息内容如下:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCNCwYGHZaabUBUHLxd3bJMTZQO/CaXvFxVBkn5vUVkeUEK+8uORh3431l3hI0WEnuF8G5V3MOc4HTS4IJ9uablXTuHILDQ3MIXHstd73s0vuMGAjjvXhil9hSbOFjjlMF5gquiYQ7jn5dr3pOGB0AR+0VxGNtz2lUZOoMjZ80u4vUQi765vF/yRpiAvUUGmYTmLmzep+ym6gJeiRmrF5+VhPCPrOJowIRo+tFGyy6IQ4mhf/9TnLc4GZ4z0/8Pe9N9Os0VNTzdSfgyuZh49jEUPm4IW4QOsAlnTlMewX53OHoAqdWQJemlT3gRLaxZQLeus1kFCI9CdXJwuJgQSAYX

将这一段复制下来,下一个步骤将会使用。

三、编辑Userdata脚本并重置EC2

1、编辑Userdata

准备如下Userdata脚本,替换username为要登录的用户名,例如Amazon Linux 2的默认用户名ec2-user,然后替换Publickey的部分为上一步复制下来的公钥的内容。

Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [users-groups, once]
users:
- name: username
  ssh-authorized-keys:
  - PublicKeypair

替换之后的效果如下:

Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [users-groups, once]
users:
- name: ec2-user
  ssh-authorized-keys:
  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCNCwYGHZaabUBUHLxd3bJMTZQO/CaXvFxVBkn5vUVkeUEK+8uORh3431l3hI0WEnuF8G5V3MOc4HTS4IJ9uablXTuHILDQ3MIXHstd73s0vuMGAjjvXhil9hSbOFjjlMF5gquiYQ7jn5dr3pOGB0AR+0VxGNtz2lUZOoMjZ80u4vUQi765vF/yRpiAvUUGmYTmLmzep+ym6gJeiRmrF5+VhPCPrOJowIRo+tFGyy6IQ4mhf/9TnLc4GZ4z0/8Pe9N9Os0VNTzdSfgyuZh49jEUPm4IW4QOsAlnTlMewX53OHoAqdWQJemlT3gRLaxZQLeus1kFCI9CdXJwuJgQSAYX

将以上一段Userdata准备好复制下来。

2、重置EC2

首先对当前正在运行状态的EC2点击关闭。关机成功后,选中这个EC2,点击右上角的Actions操作按钮,展开Instance settings菜单,选择Edit user data。如下截图。

在弹出的窗口内,粘贴上一步替换好用户名和公钥的userdata脚本。如下截图。

点击保存。

现在启动EC2,并等待一段时间。

如果需要确认EC2启动状态,可以通过查看截图的功能确认。选中这个EC2,点击右上角的Actions操作按钮,展开Monitor and troubleshoot菜单,选择Get instance screenshot,即可查看EC2运行状态。如下截图。

确认EC2已经启动完成后,使用新的密钥登录EC2进行验证。

可发现新的密钥登录成功。

3、删除Userdata中的公钥

在新密钥第一次登录完成后,还需要再次停止EC2并移除userdata。

对当前正在运行状态的EC2点击关闭。关机成功后,选中这个EC2,点击右上角的Actions操作按钮,展开Instance settings菜单,选择Edit user data。将userdata中的信息完全清空,然后点击保存按钮。

重启启动这个EC2即可。

至此整个更换密钥的过程完成。

三、参考文档

更换EC2密钥知识库:

https://aws.amazon.com/cn/premiumsupport/knowledge-center/user-data-replace-key-pair-ec2/

通过挂载EBS磁盘的办法更换密钥:

https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/replacing-lost-key-pair.html