在尝试使用 SSH 连接到我的 EC2 实例时,我收到“连接被拒”或“连接超时”错误。如何解决此问题?

上次更新日期:2020 年 10 月 22 日

在尝试使用 SSH 连接到 Amazon Elastic Compute Cloud (Amazon EC2) 实例时,我收到了“连接被拒”或“连接超时”错误。如何解决此问题?

简短描述

错误消息:“Error connecting to [instance], reason: Connection timed out: connect”是指与实例的连接出现问题,意味着请求无法到达实例且超时。如果未在实例上运行 SSH 或防火墙阻止访问,可能会出现这种情况。

错误消息:"ssh: connect to host ec2-X-X-X-X.compute-1.amazonaws.com port 22: Connection refused" 表示实例拒绝连接或 SSH 服务守护程序未运行。如果防火墙拒绝对实例的访问,也可能出现此错误。

解决方法

确认没有防火墙阻止连接,实例上运行的 SSH 服务以及 SSH tcp 端口 22 处于侦听状态。

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

方法 1:使用 AWS Systems Manager Session Manager

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

1.    打开 AWS Systems Manager 控制台

2.    启动会话

3.    要禁用防火墙并重新启动 SSH 服务,请运行以下命令。

$ sudo iptables -F
$ sudo service sshd restart

注意:上述命令会刷新所有主要 iptables 规则,而不仅仅是端口 22。重新获取对您实例的访问权限后,请检查您的防火墙配置(例如 ufw、firewalld、iptables)。

4.    验证 SSH tcp 端口 (22) 是否处于侦听状态。

$ sudo netstat -tnlp | grep :22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      849/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      849/sshd

5.    终止会话

6.    使用 SSH 连接到实例。

方法 2:运行 AWSSupport-TroubleshootSSH 自动化文档

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

方法 3:使用用户数据脚本

重要提示

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

1.    查看 EC2 实例控制台日志。如果启用 ufw,则 EC2 实例控制台日志中将会显示以下条目。

systemd[1] : starting Uncomplicated Firewall
Starting Uncomplicated firewall...

2.    打开 Amazon EC2 控制台

3.    从导航窗格中选择实例,然后选择尝试连接的实例。

4.    停止该实例

5.    依次选择操作实例设置查看/更改用户数据

6.    将以下用户数据脚本复制到查看/更改用户数据对话框,然后选择保存

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
iptables -F
service sshd restart
--//

注意:上述命令会刷新所有主要 iptables 规则,而不仅仅是端口 22。重新获取对实例的访问权限后,请检查您的防火墙配置(例如 ufw、firewalld、iptables)。

7.    使用 SSH 连接到实例。

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

要删除用户数据:

1.    完成方法 3:使用用户数据脚本部分的第 1–4 步。

2.    在 View/Change User Data(查看/更改用户数据)对话框中删除用户数据脚本。