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

上次更新日期:2021 年 9 月 21 日

我在访问 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 Command Line Interface(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
OS_USER=@@@@@@
chown root:root /home 
chmod 755 /home
chown $OS_USER:$OS_USER/home/$OS_USER -R
chmod 700 /home/$OS_USER
chmod 700 /home/$OS_USER/.ssh
chmod 600 /home/$OS_USER/.ssh/authorized_keys
--//

注意:OS_USER 的值替换为与从中启动实例的 AMI 关联的用户名。有关更多信息,请参阅连接问题的常见原因中的获取用于启动实例的 AMI 的原定设置用户名

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

注意:OS_USER 的值替换为与从中启动实例的 AMI 关联的用户名。有关更多信息,请参阅连接问题的常见原因中的获取用于启动实例的 AMI 的原定设置用户名

8.    启动您的实例

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

要删除用户数据:

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