跳至内容

如果我在 Amazon EC2 实例初次启动后丢失了 SSH 密钥对,我该如何连接到该实例?

3 分钟阅读
0

我想连接到 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 问题,请继续参阅使用救援实例

创建新的密钥对

完成以下步骤:

  1. 创建新密钥对
  2. 如果您在 Amazon EC2 控制台中创建私钥,请检索密钥对的公钥
  3. 打开 Amazon EC2 控制台
  4. 停止实例
  5. 选择 Actions(操作),然后选择 Instance settings(实例设置)。
  6. 选择 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 开始。
  7. 选择 Save(保存)。
  8. 启动实例

确认 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 ..”。

从实例的用户数据中移除命令

完成以下步骤:

  1. 停止实例
  2. 选择 Actions(操作),然后选择 Instance settings(实例设置)。
  3. 选择 Edit user data(编辑用户数据),然后清除该字段中的所有内容。
  4. 选择 Save(保存)。
  5. 启动实例

使用 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,请完成以下步骤:

  1. 打开 Amazon EC2 控制台
  2. 选择 AMI
  3. 在搜索字段中输入自动化 ID。

选择 EC2 Instance Connect

要连接到 Amazon Linux 实例,请参阅使用 EC2 Instance Connect 连接到 Linux 实例

使用 EC2 Serial Console

如果您可以访问适用于 Linux 的 EC2 Serial Console,请使用该控制台对受支持的基于 Nitro 的实例类型进行故障排除。有关详细信息,请参阅配置对 EC2 Serial Console 的访问权限

使用救援实例

完成以下步骤:

  1. 停止实例

  2. 将根 EBS 卷与实例分离

  3. 在与原始实例相同的可用区中启动救援实例

  4. 将原始实例的根卷作为辅助卷附加到救援实例

  5. 启动救援实例

  6. 要获取根卷设备名称,请运行以下命令:

    sudo lsblk -f

    输出示例:

    NAME FSTYPE LABEL UUID MOUNTPOINT
    xvda └─xvda1 xfs 1234abcd-56ef-78gh-90ij-1234klmnopqr /
     xvdf └─xvdf1 xfs abcd1234-ef56-gh78-ij90-qr1234klmnop
  7. 要将附加的卷挂载到救援实例,请运行以下命令:

    sudo mkdir /mnt/target
    sudo mount /dev/xvdf1 /mnt/target

    **注意:**请将 /dev/xvdf1 替换为原始实例的根卷设备名称。

  8. 要创建新的公钥,请运行以下命令:

    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 开头。

  9. 要配置对实例中密钥的访问权限,请运行以下命令:

    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 关联的用户名

  10. 要卸载卷,请运行以下命令:

sudo umount /mnt/target
  1. 将卷与救援实例分离,然后将其重新附加到原始实例
  2. 启动原始实例
1评论

中文版提供的userdata格式错误。使用不正确的格式将导致该方法无法生效。

需要在 Content-Type: multipart/mixed; boundary="//" 和 MIME-Version: 1.0 之间添加换行符。 正确的格式应该是:

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
已回复 6 个月前