嘗試使用 SSH 連線至 EC2 執行個體時收到「連線遭拒」或「連線逾時」錯誤。如何解決此錯誤?

上次更新日期:2022 年 10 月 28 日

嘗試使用 SSH 連線至 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體時收到 "Connection refused" (連線遭拒) 或 "Connection timed out" (連線逾時) 錯誤。

簡短描述

錯誤訊息:「ssh:連線到主機 ec2-X-X-X-X.compute-1.amazonaws.com 連接埠 22:連線逾時」。此錯誤訊息來自 SSH 用戶端。該錯誤表示伺服器沒有回應用戶端,用戶端程序已放棄 (逾時)。以下是造成此錯誤的常見原因:

  • 安全群組或網路 ACL 不允許存取。
  • 執行個體的作業系統上有防火牆。
  • 用戶端與伺服器之間有防火牆。
  • 主機不存在。

錯誤訊息:"ssh: connect to host ec2-X-X-X-X.compute-1.amazonaws.com port 22: Connection refused (ssh:連線到主機 ec2-X-X-X-X.compute-1.amazonaws.com 連接埠 22:連線遭拒)"。此訊息來自遠端主機。以下是造成此錯誤的常見原因:

  • 主機已連線到執行個體,但沒有服務在 SSH 連接埠上接聽。
  • 防火牆已封鎖,並設定為拒絕套裝服務,而非捨棄套裝服務。

解決方案

對於 “Connection timed out” (連線逾時),請驗證以下內容

注意:最後兩個驗證步驟需要執行個體的作業系統層級存取權。

對於“Connection refused”(連線遭拒) 錯誤,請驗證以下內容

  • 執行個體上沒有防火牆拒絕 SSH 連線。
  • SSH 常駐程式 (sshd) 正在執行並監聽連接埠 22。

注意:這兩個驗證步驟都需要執行個體的作業系統層級存取權。

如果執行個體通過這兩種運作狀態檢查,請在您的組態中使用下列四種方法之一

  • 方法 1:使用適用於 Linux 的 EC2 序列主控台。
  • 方法 2:使用 AWS System Manager Session Manager。
  • 方法 3:執行 AWSSupport-TroubleshootSSH 自動化執行手冊。
  • 方法 4:使用使用者資料指令碼。

方法 1:使用適用於 Linux 的 EC2 序列主控台

如果已設定,您可以使用適用於 Linux 的 EC2 序列主控台,針對支援的 Nitro 型執行個體類型進行作業系統層級問題的疑難排解。序列主控台能讓您針對啟動問題、網路組態和 SSH 組態問題進行疑難排解。序列主控台可使用 Amazon EC2 主控台或 AWS Command Line Interface (AWS CLI) 存取。

使用序列主控台之前,請先在帳戶層級授與存取權。然後,建立 AWS Identity and Access Management (IAM) 政策,向您的 IAM 使用者授予存取權

注意:每個使用序列主控台的執行個體都必須包含至少一個具有 sudo 存取權的以密碼為基礎的 Linux 使用者。

如需更多有關適用於 Linux 的 EC2 序列主控台的設定資訊,請參閱設定對 EC2 序列主控台的存取權。如果沒有已設定登入密碼的 Linux 帳戶,您必須執行 ssm-user 來重設具有 sudo 存取權的帳戶的密碼。如需執行 ssm-user 命令的詳細資訊,請參閱在 Linux 和 macOS 上管理 ssm 使用者 sudo 帳戶權限一節。

設定完成後,使用已設定密碼的 Linux 使用者透過 EC2 序列主控台連線至 EC2 執行個體。

接下來,請執行以下命令。這些命令會驗證 SSH 連線不會被作業系統防火牆或 TCP 包裝函式封鎖。這些命令也會驗證 sshd 服務是否在連接埠 22 上執行並接聽。

1.    如果您設定了 iptables 規則,請執行以下命令以在 iptables 中新增一個規則,接受預設連接埠 22 上的所有 SSH 連線:

$ sudo iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

因為最佳做法是使用安全群組而非作業系統型防火牆,因此可以完全停用防火牆。若要停用作業系統型防火牆,請根據您的作業系統,使用下列其中一組命令:

重要提示:以下命令排清所有主要的 iptables 規則。它們也會新增一個允許傳入 SSH 連線的規則。此外,它們將主鏈的預設政策變更為 ACCEPT (接受),以便排清 iptables 規則不會影響執行個體網路連線。由於這些命令會排清所有主要 iptables,因此它們也會排清任何現有規則。

使用 UFW 的發行版 (Ubuntu、Debian)

$ sudo iptables -F
$ sudo iptables -P INPUT ACCEPT
$ sudo ufw disable

使用防火牆的發行版 (Red Hat、CentOS)

$ sudo iptables -F 
$ sudo iptables -P INPUT ACCEPT
$ sudo systemctl disable firewalld

注意:在重新取得執行個體的存取權後,請檢閱您的防火牆組態 (UFW、firewalld、iptables)。

2.    驗證 SSH 正在執行,並驗證 SSH TCP 連接埠 (22) 處於接聽狀態:

$ sudo systemctl restart sshd
$ sudo ss -tpln | grep -iE '22|ssh'
LISTEN 0 128 *:22 *:* users:(("sshd",pid=1901,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1901,fd=4))

注意:如果您的系統沒有 ss 命令,則能搭配使用舊式 netstat 命令與前面範例所示的同一個語法。

3.    確保 TCP 包裝函式未阻止 SSH 連線:

$ if [[ $( cat /etc/hosts.[ad]* | grep -vE '^#' | awk 'NF' | wc -l) -ne 0 ]];\
then sudo sed -i '1i sshd2 sshd : ALL: allow' /etc/hosts.allow; fi

4.    接下來,使用 SSH 連線至執行個體。

5.    如果不再需要 EC2 序列主控台工作階段,請中斷連線。

方法 2:使用 AWS System Manager Session Manager

注意:若要使用此方法,執行個體必須是 SSM 受管執行個體,且其 SSM 代理程式 Ping 狀態必須為 Online (線上)。如需工作階段管理員和完整必要條件清單的詳細資訊,請參閱設定工作階段管理員

若要確認 SSH 連線未被防火牆或 TCP 包裝函式封鎖,而且 sshd 服務正在執行並在連接埠 22 上接聽:

1.    開啟 AWS Systems Manager

2.    使用工作階段管理員啟動執行個體的工作階段

3.    遵循方法 1 中的步驟 1-4:使用適用於 Linux 的 EC2 序列主控台。

4.    如果不再需要工作階段管理員工作階段,請關閉該工作階段。

方法 3:執行 AWSSupport-TroubleshootSSH 執行手冊

AWSSupport-TroubleshootSSH 自動化執行手冊會在執行個體上安裝 Amazon EC2Rescue 工具。此工具會檢查並嘗試修正阻止透過 SSH 遠端連線 Linux 主機的問題。

若要執行 AWSSupport-TroubleshootSSH 執行手冊:

1.    開啟 AWSSupport-TroubleshootSSH 頁面。

2.    選取 Run this Automation (執行此自動化) (主控台)。

若要進一步了解,請參閱如何使用 AWSSupport-TroubleshootSSH 自動化工作流程來排查 SSH 連線問題?

方法 4:使用使用者資料指令碼

如果所描述的方法都不適合您的環境,請使用 EC2 使用者資料指令碼。EC2 使用者資料指令碼會關閉作業系統層級防火牆和 TCP 包裝函式,然後重新啟動 sshd 服務。

重要提示:

  • 此程序需要停止和啟動 EC2 執行個體。如果執行個體有任何資料儲存在執行個體儲存體磁碟區上,該資料會在停止執行個體後刪除。
  • 如果執行個體屬於 Amazon EC2 Auto Scaling 群組,則終止執行個體也可能會停止 Auto Scaling 群組內的執行個體。
  • 如果執行個體是由使用 AWS Auto Scaling 的服務啟動,則終止執行個體也可能會停止 Auto Scaling 群組內的執行個體。
  • 執行個體是否終止取決於 Auto Scaling 群組的執行個體縮減保護設定。如果執行個體屬於 Auto Scaling 群組,請先從 Auto Scaling 群組中暫時移除該執行個體,然後再執行解決方案步驟。
  • 停止和啟動執行個體會變更執行個體的公有 IP 地址。在將外部流量路由到執行個體時,最佳實務是使用彈性 IP 地址而不是公有 IP 地址。

請依照下列步驟設定執行個體的使用者資料:

1.    開啟 Amazon EC2 主控台

2.    從導覽窗格中選擇 Instances (執行個體),然後選取您計劃要連線到的執行個體。

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
iptables -P INPUT ACCEPT
iptables -F
systemctl restart sshd.service || service sshd restart
if [[ $( cat /etc/hosts.[ad]* | grep -vE '^#' | awk 'NF' | wc -l) -ne 0 ]];\
then sudo sed -i '1i sshd2 sshd : ALL: allow' /etc/hosts.allow; fi
--//

6.    使用 SSH 連線至執行個體。

7.    前述的使用者資料指令碼設為在每次重新啟動執行個體時執行。重新獲得對執行個體的存取權後,移除使用者資料指令碼。

注意:上述命令排清所有主要的 iptables 規則。在重新取得執行個體的存取權後,請檢閱防火牆組態的準確性 (例如,UFW、firewalldiptables)。

若要移除使用者資料:

1.    完成方法 4:使用使用者資料指令碼一節中的步驟 1 到步驟 4。

2.    在 Edit User Data (編輯使用者資料) 對話方塊中刪除使用者資料指令碼。