我对 EC2 实例的 sshd_config 文件进行了更改,现在我无法使用 SSH 访问我的实例。如何解决此问题?

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

我更改了 Amazon Elastic Compute Cloud (Amazon EC2) 实例的 sshd_config 文件,现在我无法使用 SSH 访问我的实例。如何进行故障排查并解决此问题?

简短描述

通过 SSH 建立连接时,更改实例的 sshd_config 文件可能会导致连接被拒绝错误。

为了确认由于连接被拒绝错误而导致无法访问实例,请在详细消息打开的情况下通过 SSH 访问实例:

$ ssh -i "myawskey.pem" ec2-user@ec2-11-22-33-44.eu-west-1.compute.amazonaws.com -vvv

在上例中,使用 myawskey.pem 作为私钥文件,ec2-user@ec2.11.22.33.44 作为用户名。请用您的密钥文件和用户名替换示例中的密钥文件和用户名。确保使用实例所在的区域。

以下示例输出显示了 connection refused(连接被拒绝)错误消息:

OpenSSH_7.9p1, LibreSSL 2.7.3
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 48: Applying options for *
debug1: Connecting to ec2-11-22-33-44.eu-west-1.compute.amazonaws.com port 22.
ssh: connect to host ec2-11-22-33-44.eu-west-1.compute.amazonaws.com port 22: Connection refused
解决方法

注意:如果您使用的是基于 Nitro 的实例,则设备名称与以下步骤中给出的示例不同。例如,基于 Nitro 的实例上的设备名称是 /dev/nvme,而非 /dev/xvda/dev/sda1。有关更多信息,请参阅 Linux 实例上的设备名称。

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

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

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

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

方法 2:使用救援实例

警告:停止并启动实例前,确保了解以下内容:

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

1.在虚拟私有云 (VPC) 中启动新 EC2 实例。在同一可用区中使用与受损实例相同的 Amazon Machine Image (AMI)。此新实例将成为您的救援实例。

2.停止受损的实例。

注意:如果您使用存储支持的实例或拥有包含数据的实例存储卷,则在停止实例时,数据将会丢失。有关更多信息,请参阅确定实例的根设备类型。

3.从受损实例中分离 Amazon Elastic Block Store (Amazon EBS) 根卷(/dev/xvda/dev/sda1)。

4.将 EBS 卷作为辅助设备 (/dev/sdf) 附加到救援实例。

5.使用 SSH 连接到您的救援实例。

6.运行 lsblk 命令以查看设备:

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0   8G  0 disk
 └─xvdf1 202:81   0   8G  0 part

7.为在第 4 步中附加到救援实例的新卷创建挂载点目录 (/rescue)。

$ sudo mkdir /mnt/rescue

8.将该卷挂载到您在第 7 步中创建的目录:

$ sudo mount -t xfs -o nouuid /dev/xvdf1 /mnt/rescue/

9.再次运行 lsblk 命令以验证卷已挂载该目录:

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0   8G  0 disk
└─xvdf1 202:81   0   8G  0 part /mnt/rescue
更正或复制 sshd_config 文件

您可以调查受损实例上的 sshd_config 文件并回滚所做的更改。使用 SSH 详细消息输出将您引导到文件中的错误位置。

$ sudo vi /mnt/rescue/etc/ssh/sshd_config

或者,使用以下命令将 sshd_config 文件从救援实例复制到受损实例。此命令替换原始实例上的 sshd_config 文件的内容。

$ sudo cp /etc/ssh/sshd_config /mnt/resscue/etc/ssh/sshd_config
将卷重新附加到原始实例并测试连接

注意:如果您使用方法 2:使用救援实例,请完成以下步骤。

1.运行 umount 命令以卸载该卷:

$ sudo umount /mnt/rescue/

2.将辅助卷从救援实例分离,然后将该卷以 /dev/xvda(根卷)的形式附加到原始实例。

3.启动实例。

4.使用 SSH 连接到实例以验证您是否可以访问该实例。