为什么我在尝试使用 SSH 连接 EC2 实例时收到“服务器拒绝我们的密钥”错误?

上次更新日期:2021 年 4 月 26 日

我在使用 SSH 连接到 Amazon Elastic Compute Cloud (Amazon EC2) 实例时收到“服务器拒绝我们的密钥”错误。如何修复此问题?

简短描述

SSH 服务器 (sshd) 拒绝私有 SSH 密钥的原因有多种。以下是您可能会收到此错误的一些常见原因:

解决方法

您在连接到 EC2 实例时为 AMI 使用不正确的用户名

尝试访问实例的用户已从服务器中删除,或账户已锁定

如果尝试访问实例的用户已从服务器中删除,则将该用户作为新用户添加回来。有关更多信息,请参阅如何将具有 SSH 访问权限的新用户账户添加到 Amazon EC2 Linux 实例?

实例存在权限问题,或者您丢失了目录

可以通过四种方法验证实例上的权限和目录:

方法 1:使用 EC2 串行控制台

如果您为 Linux 启用了 EC2 串行控制台,则可以使用它来排查受支持的基于 Nitro 的实例类型。串行控制台可帮助您排查启动问题、网络配置和 SSH 配置问题。串行控制台无需网络连接即可连接到您的实例。您可以使用 Amazon EC2 控制台或 AWS 命令行界面 (AWS CLI) 访问串行控制台。

在使用串行控制台之前,您必须在账户层面授予对串行控制台的访问权限。然后,您必须创建 AWS Identity and Access Management (IAM) 策略,授予对 IAM 用户的访问权限。此外,每个使用串行控制台的实例都必须至少包含一个基于密码的用户。如果您的实例无法访问,并且尚未配置对串行控制台的访问权限,请按照方法 2、3 或 4 中的说明进行操作。有关为 Linux 配置 EC2 串行控制台的信息,请参阅配置对 EC2 串行控制台的访问权限

方法 2:使用 AWS Systems Manager Session Manager 登录实例并检查权限

注意:必须安装 SSM 代理才能使用此方法。有关 Session Manager 和先决条件完整列表的更多信息,请参阅设置 Session Manager

1.    打开 AWS Systems Manager 控制台

2.    启动会话

3.    使用 stat 命令确保目录下的文件权限正确。以下是正确权限的列表:

  • Linux 主目录(例如 /home)应为 (0755/drwxr-xr-x)
  • 用户的主目录(例如 /home/ec2-user/)应为 (0700/drwx------)
  • .ssh 目录权限(例如 /home/ec2-user/.ssh)应为 (0700/drwx------)
  • authorized_keys 文件权限(例如 /home/ec2-user/.ssh/authorized_keys)应为 (0600/-rw-------)

以下为 stat 命令及所生成输出的示例。在本示例中,ec2-user 为用户名。根据您的特定 AMI 更改用户名

$ stat /home/ec2-user/
  File: '/home/ec2-user/'
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: 10301h/66305d	Inode: 18322       Links: 3
Access: (0700/drwx------)  Uid: (  500/ec2-user)   Gid: (  500/ec2-user)

4.    如果此权限与上述值不匹配,则运行以下命令。

$ sudo chown root:root /home
$ sudo chmod 755 /home
$ sudo chown ec2-user:ec2-user /home/ec2-user -R
$ sudo chmod 700 /home/ec2-user /home/ec2-user/.ssh
$ sudo chmod 600 /home/ec2-user/.ssh/authorized_keys

5.    结束会话

6.    通过 SSH 连接到您的实例。

方法 3:通过运行 AWSSupport-TroubleshootSSH 文档自动更正导致错误的问题

AWSSupport-TroubleshootSSH 自动化文档会在实例上安装 Amazon EC2Rescue 工具,然后检查并更正在使用 SSH 连接至 Linux 计算机时导致远程连接错误的部分问题。有关更多信息,请参阅如何通过 AWSSupport-TroubleshootSSH 自动化工作流程排查 SSH 连接问题?

方法 4:使用用户数据修复实例权限

重要提示!

  • 此恢复过程需要您停止并启动您的实例。执行此操作时,实例存储卷上的数据会丢失。有关更多信息,请参阅确定实例的根设备类型
  • 如果您的实例是 Amazon EC2 Auto Scaling 组的一部分,则停止实例可能会终止实例。这也可能发生在使用 AWS Auto Scaling 的服务启动的实例上,例如 Amazon EMR、AWS CloudFormation、AWS Elastic Beanstalk 等。在这种情况下,是否会发生实例终止取决于您的 Auto Scaling 组的实例缩减保护设置。如果您的实例是 Auto Scaling 组的一部分,请在开始执行解决步骤之前,暂时从 Auto Scaling 组中删除该实例
  • 停止和重新启动实例会更改实例的公有 IP 地址。在将外部流量路由到您的实例时,最佳做法是使用弹性 IP 地址而不是公有 IP 地址。
  • 如果您的实例根设备为实例存储卷,您无法使用用户数据更改 SSH 密钥。有关更多信息,请参阅确定实例的根设备类型
  • 更新实例的用户数据将应用于支持 cloud-init 指令的所有分发。要使这些指令成功,必须安装并配置 Cloud-init。有关 cloud-init SSH 模块的更多信息,请参阅 SSH - 配置 SSH 和 SSH 密钥

1.    打开 Amazon EC2 控制台,然后选择您的实例。

2.    依次选择 Instance State(实例状态)、Stop instance(停止实例)。

注意:如果停止处于禁用状态,则表示要么实例已停止,要么其根设备是一个实例存储卷。

3.    依次选择 Actions(操作)、Instance Settings(实例设置)和 Edit User Data(编辑用户数据)。

4.    将以下脚本复制到用户数据字段中,然后选择保存。确保复制整个脚本,不要添加额外的空格。

注意:以下脚本使用用户名 ec2-user。将 ec2-user 更改为您的 AMI 的用户名

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:
- [scripts-user, always]

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

#!/bin/bash
chown root:root /home
chmod 755 /home
chown ec2-user:ec2-user /home/ec2-user -R
chmod 700 /home/ec2-user /home/ec2-user/.ssh
chmod 600 /home/ec2-user/.ssh/authorized_keys
--//

5.    启动实例,然后通过 SSH 连接到实例。

注意:默认情况下,每个实例运行一次用户数据脚本。此程序将更改默认行为,从而将公有密钥添加到实例的每次重启、停止或启动中。要恢复默认行为,请删除自定义的用户数据。作为最佳实践,请考虑允许用户数据在第一次启动实例后运行的安全启示。您可以使用 ModifyInstanceAttribute API 方法修改实例的用户数据。要限制对此方法的访问,请使用 IAM 策略