我想连接到 Amazon Elastic Compute Cloud (Amazon EC2) 实例,但是丢失了 SSH 密钥对。
简短描述
要在丢失 SSH 密钥对时连接到 EC2 实例,请使用以下方法之一:
- 输入用户数据以创建新的密钥对。
- 对于托管节点实例,请使用 AWS Systems Manager 恢复您的密钥对。
- 对于运行 Amazon Linux 2 (AL2) 版本 2.0.20190618 及更高版本或 Amazon Linux 2023 (AL2023) 的实例,请使用 EC2 Instance Connect。
- 如果您可以访问您的实例并且可以访问 EC2 Serial Console,请使用串行控制台。
**注意:**此方法不需要您停止和启动实例。
- 创建救援实例以创建新的公钥。
**重要事项:**在停止和启动实例之前,请执行以下操作:
**注意:**当停止或启动某个实例时,该实例的公共 IP 地址将发生变化。最佳实践是使用弹性 IP 地址而不是公共 IP 地址将外部流量路由到您的实例。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
输入用户数据脚本
**重要事项:**不要在用户数据脚本中存储敏感数据。而应使用诸如 AWS Secrets Manager 之类的安全方法。
如果您的实例无法访问 cloud-init 或者您遇到 cloud-init 问题,请继续参阅使用救援实例。
创建新的密钥对
完成以下步骤:
- 创建新密钥对。
- 如果您在 Amazon EC2 控制台中创建私钥,请检索密钥对的公钥。
- 打开 Amazon EC2 控制台。
- 停止实例。
- 选择 Actions(操作),然后选择 Instance settings(实例设置)。
- 选择 Edit user data(编辑用户数据),然后输入以下脚本:
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
**注意:**请将 username 替换为默认用户名或先前创建的自定义用户名。将 PublicKeypair 替换为公钥。当您输入整个公钥时,从 ssh-rsa 开始。
- 选择 Save(保存)。
- 启动实例。
确认 cloud-init 阶段完成
在实例控制台输出中,检查以下因素以确保 cloud-init 阶段已完成:
- 没有错误消息。
- 所有 cloud-init 指令都列为 Executed(已执行)。
- 您将看到 cloud-init 的 Finished(已完成)消息,类似于以下示例: “Finished [0;1;39mCloud-init: Final Stage[0m Cloud-init v.A.B.C finished at ..”。
从实例的用户数据中移除命令
完成以下步骤:
- 停止实例。
- 选择 Actions(操作),然后选择 Instance settings(实例设置)。
- 选择 Edit user data(编辑用户数据),然后清除该字段中的所有内容。
- 选择 Save(保存)。
- 启动实例。
使用 Systems Manager
要在 Systems Manager 中恢复托管节点的实例,请使用 AWSSupport-ResetAccess 运行手册恢复密钥对。AWSSupport-ResetAccess 使用 EC2Rescue 在实例上自动生成和添加新的 SSH 密钥对。
Systems Manager 加密您的实例的新 SSH 私钥并在 AWS Systems Manager 的功能 Parameter Store 中将其保存为 /ec2rl/openssh/instance_id/key。
要从 Parameter Store 获取 SSH 私钥,请运行 get-parameters AWS CLI 命令:
aws ssm get-parameters --names "/ec2rl/openssh/instance_id/key" --with-decryption --output json --query "Parameters[0].Value" | sed 's:\\n:\n:g; s:^"::; s:"$::' > key-pair-name
**注意:**将 instance_id 替换为您的实例 ID,并将 key-pair-name 替换为您的密钥对的名称。
然后,使用参数的值作为内容创建一个新的 .pem 文件。使用 .pem 文件重新连接到您无法访问的实例。
要将私钥转换为 .pem 文件,请运行以下命令:
ssh-keygen -f key-pair-name -e -m pem > key-pair-name.pem
**注意:**将 key-pair-name 替换为您的密钥对的名称。
自动化运行手册创建了密码激活的备份亚马逊机器映像 (AMI)。Amazon EC2 不会自动删除新的 AMI,因此它会保留在您的 AWS 账户中。
要找到 AMI,请完成以下步骤:
- 打开 Amazon EC2 控制台。
- 选择 AMI。
- 在搜索字段中输入自动化 ID。
选择 EC2 Instance Connect
要连接到 Amazon Linux 实例,请参阅使用 EC2 Instance Connect 连接到 Linux 实例。
使用 EC2 Serial Console
如果您可以访问适用于 Linux 的 EC2 Serial Console,请使用该控制台对受支持的基于 Nitro 的实例类型进行故障排除。有关详细信息,请参阅配置对 EC2 Serial Console 的访问权限。
使用救援实例
完成以下步骤:
-
停止实例。
-
将根 EBS 卷与实例分离。
-
在与原始实例相同的可用区中启动救援实例。
-
将原始实例的根卷作为辅助卷附加到救援实例。
-
启动救援实例。
-
要获取根卷设备名称,请运行以下命令:
sudo lsblk -f
输出示例:
NAME FSTYPE LABEL UUID MOUNTPOINT
xvda └─xvda1 xfs 1234abcd-56ef-78gh-90ij-1234klmnopqr /
xvdf └─xvdf1 xfs abcd1234-ef56-gh78-ij90-qr1234klmnop
-
要将附加的卷挂载到救援实例,请运行以下命令:
sudo mkdir /mnt/target
sudo mount /dev/xvdf1 /mnt/target
**注意:**请将 /dev/xvdf1 替换为原始实例的根卷设备名称。
-
要创建新的公钥,请运行以下命令:
sudo mkdir -p /mnt/target/home/USER/.ssh
echo "your_new_public_key" | sudo tee -a /mnt/target/home/USER/.ssh/authorized_keys
**注意:**请将 USER 替换为原始实例的用户名,将 your_new_public_key 替换为您的公钥。公钥名称以 ssh-rsa 开头。
-
要配置对实例中密钥的访问权限,请运行以下命令:
OS_USER=os-user
sudo chown -R $OS_USER:$OS_USER /mnt/target/home/$OS_USER/.ssh
sudo chmod 700 /mnt/target/home/$OS_USER/.ssh
sudo chmod 600 /mnt/target/home/$OS_USER/.ssh/authorized_keys
**注意:**请将 os-user 替换为与用于启动实例的 AMI 关联的用户名。
-
要卸载卷,请运行以下命令:
sudo umount /mnt/target
- 将卷与救援实例分离,然后将其重新附加到原始实例。
- 启动原始实例。