我在尝试访问 EC2 实例时收到“权限被拒绝 (Publickey)”或“身份验证失败,权限被拒绝”错误。如何解决此问题?

上次更新时间:2021 年 5 月 4 日

我在访问 Amazon Elastic Compute Cloud (Amazon EC2) 实例时收到“权限被拒绝 (Publickey)”或“身份验证失败,权限被拒绝”错误。如何解决此问题?

简短描述

发生以下情况时,会发生“权限被拒绝 (Publickey)”和“身份验证失败,权限被拒绝”错误:

  • 您尝试使用 AMI 的错误用户名连接。
  • 实例上的权限不正确。
  • authorized_keys 文件中的 SSH 公有密钥 (.pub) 文件不正确。

解决方法

验证您在为您的 AMI 使用正确的用户名

验证实例的权限正确,且 authorized_keys 文件中的 SSH 公有密钥正确

可以通过四种方法执行这些任务:

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

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

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

注意:如果在运行 AWS CLI 命令时遇到错误,请确保您使用的是最新版本的 AWS CLI

方法 2:使用 AWS Systems Manager Session Manager 登录实例并进行更正

此方法将更新权限并将您的 SSH 公有密钥注入 authorized_keys 文件中。

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

1.    打开 AWS Systems Manager 控制台

2.    启动会话

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

  • 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-------)

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

$ ls -ld /home/ec2-user/
drwx------ 3 ec2-user ec2-user 4096 Apr  1 08:31 /home/ec2-user/

4.    在您的本地计算机上,验证 SSH 公有密钥

5.    如果 SSH 公有密钥的签名不在输出中,请更新 authorized_keys 文件以允许您的 SSH 密钥。在下面的示例中,将示例密钥替换为您的 SSH 公有密钥。

$ echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVogCW5eZogRp+vF6Ut360b0bYyTmqgYaCXOyiW77I916AS5jFL3zsCtONbGn4hnG/UGGWXpLfUV85qpVJb38fskPZNuyZtjGjXM2W7qqbCZ1N9HBb6IPBaL97tmqBi+8rD7mSkoHc40sIV+KxkQSvD6AAFjQruCjxzfGIApnOvuj6IMsVEuFHBx4QhkbCzafxo02D9BZT4+dMy7tmyuC+UiNEQpgfFoszl+4VNFTIPlQQyn6CpUiV/rFXIadXsHqc+UOdVnfEXP+30YL75RHabze/1F5MY6t94AEcmcb05Dq4vwN9IjcxKmwgvxLOXzryytepvHQU+PobBEXAMPLE' >> /home/ec2-user/.ssh/authorized_keys

6.    要更正权限,对您的 EC2 实例运行以下命令。

$ 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

7.    结束会话

8.    使用 SSH 连接到实例。

方法 3:运行 AWSSupport-TroubleshootSSH 自动化程序

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

方法 4:使用用户数据脚本修复 SSH 权限,并将正确的 SSH 公有密钥添加到 authorized_keys 文件中

重要公告

  • 请注意,如果您的实例受实例存储支持或具有包含数据的实例存储卷,则在实例停止时数据将丢失。有关更多信息,请参阅确定实例的根设备类型
  • 如果您的实例是 Amazon EC2 Auto Scaling 组的一部分,停止实例可能会终止实例。使用 Amazon EMR、AWS CloudFormation 或 AWS Elastic Beanstalk 启动的实例可能是 AWS Auto Scaling 组的一部分。在这种情况下,是否会发生实例终止取决于您的 Auto Scaling 组的实例缩减保护设置。如果您的实例是 Auto Scaling 组的一部分,请在开始执行解决步骤之前,暂时从 Auto Scaling 组中删除该实例
  • 停止和启动实例会更改实例的公共 IP 地址。在将外部流量路由到您的实例时,最佳做法是使用弹性 IP 地址而不是公有 IP 地址。

1.    打开 Amazon EC2 控制台

2.    从导航窗格中选择实例,然后选择尝试启动的实例。

3.    停止该实例

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

5.    将以下用户数据脚本复制到 Edit User Data(编辑用户数据)对话框,然后选择 Save(保存)。

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
--//

6.    在您的本地计算机上,验证 SSH 公有密钥

7.    如果 SSH 公有密钥的签名不在输出中,则将正确的密钥附加到您在步骤 5 中创建的用户数据脚本。如果签名匹配,则可以跳过此步骤。将 SSH 公有密钥附加到用户数据脚本中,如下面的示例所示。将示例密钥替换为您的 SSH 公有密钥。

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
chmod 700 /home/ec2-user /home/ec2-user/.ssh
chmod 600 /home/ec2-user/.ssh/authorized_keys
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVogCW5eZogRp+vF6Ut360b0bYyTmqgYaCXOyiW77I916AS5jFL3zsCtONbGn4hnG/UGGWXpLfUV85qpVJb38fskPZNuyZtjGjXM2W7qqbCZ1N9HBb6IPBaL97tmqBi+8rD7mSkoHc40sIV+KxkQSvD6AAFjQruCjxzfGIApnOvuj6IMsVEuFHBx4QhkbCzafxo02D9BZT4+dMy7tmyuC+UiNEQpgfFoszl+4VNFTIPlQQyn6CpUiV/rFXIadXsHqc+UOdVnfEXP+30YL75RHabze/1F5MY6t94AEcmcb05Dq4vwN9IjcxKmwgvxLOXzryytepvHQU+PobBEXAMPLE' >> /home/ec2-user/.ssh/authorized_keys
chown ec2-user:ec2-user /home/ec2-user -R
--//

8.    启动您的实例

注意:上述用户数据脚本设置为在实例每次重新启动时运行。重新获得对您实例的访问权限后,删除用户数据脚本。

要删除用户数据:

  • 完成本部分的第 1-4 步。
  • Edit User Data(编辑用户数据)对话框中删除用户数据脚本。