EC2 インスタンスに SSH で接続しようとすると、「接続が拒否されました」または「接続がタイムアウトしました」というエラーが表示されます。これを解決するにはどうすればよいですか?

最終更新日: 2021 年 10 月 8 日

SSH を使用して Amazon Elastic Compute Cloud (Amazon EC2) インスタンスに接続しようとすると、「接続が拒否されました」または「接続がタイムアウトしました」というエラーが表示されます。これを解決するにはどうすればよいですか?

簡単な説明

エラーメッセージ:「ssh: ホスト ec2-X-X-X-X.compute-1.amazonaws.com ポート 22 への接続: 接続がタイムアウトしました」。このエラーメッセージは SSH クライアントから送信されます。このエラーは、サーバーがクライアントに応答しなかったため、クライアントのプログラムが断念した (タイムアウトした) ことを示します。このエラーの一般的な原因は次のとおりです。

  • セキュリティグループまたはネットワーク ACL がアクセスを許可しない。
  • インスタンスのオペレーティングシステムにファイアウォールがある。
  • クライアントとサーバーの間にファイアウォールがある。
  • ホストが存在しない。

エラーメッセージ:「ssh: ホスト ec2-X-X-X-X.compute-1.amazonaws.com ポート 22 への接続: 接続が拒否されました」。このメッセージはホストからリモートで送信されます。このエラーの一般的な原因は次のとおりです。

  • ホストはインスタンスに到達したが、SSH ポートでリッスンしているサービスがなかった。
  • ファイアウォールがブロックし、パッケージをドロップする代わりに拒否するように設定されていた。

解決方法

以下について確認してください。

これらのタスクを実行する方法は 4 つあります。

方法 1: EC2 シリアルコンソールを使用する

Linux 用 EC2 シリアルコンソールを設定している場合は、それを使用して、サポートされている Nitro ベースのインスタンスタイプのトラブルシューティングを行うことができます。シリアルコンソールは、起動の問題、ネットワーク設定、および SSH 設定の問題のトラブルシューティングに役立ちます。シリアルコンソールは、正常に動作するネットワーク接続を必要とすることなく、インスタンスに接続します。シリアルコンソールには、Amazon EC2 コンソールまたは AWS コマンドラインインターフェイス (AWS CLI) を使用してアクセスできます。

シリアルコンソールを使用する前に、アカウントレベルでコンソールにアクセス権を付与します。その後、IAM ユーザーにアクセス権を付与する AWS Identity and Access Management (IAM) ポリシーを作成します。また、シリアルコンソールを使用するすべてのインスタンスには、少なくとも 1 名のパスワードベースユーザーを含める必要があります。インスタンスが到達不能で、シリアルコンソールへのアクセスを設定していない場合は、方法 2、3、または 4 の手順に従います。Linux 用の EC2 シリアルコンソールの設定の詳細については、「EC2 シリアルコンソールへのアクセスを設定する」を参照してください。

注: AWS CLI コマンドの実行時にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください

方法 2: AWS Systems Manager Session Manager を使用する

注: この方法を使用するには、SSM エージェントをインストールする必要があります。Session Manager の詳細と前提条件の一覧については、Session Manager の開始方法をご参照ください。

1.    AWS Systems Manager コンソールを開きます。

2.    セッションを開始します

3.    ルールテーブルの先頭に次の行を追加して、SSH サービスを再開します。

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

あるいは、ファイアウォールを非アクティブ化することもできます。ファイアウォールではなくセキュリティグループを使用するのがベストプラクティスです。

ファイアウォールを非アクティブ化するには、オペレーティングシステムに応じて、次のいずれかのコマンドセットを使用します。

複雑でないファイアウォールを使用する Ubuntu

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

firewalld を使用するディストリビューション (例えば、Red Hat や CentOS)

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

注: 前述のコマンドは、すべての主要な iptables ルールをフラッシュし、着信 SSH 接続を許可するルールを追加します。設定に他のルールが必要となる場合があるため、これらのコマンドを実行する前にこの点を考慮してください。ご使用のインスタンスへのアクセスを回復したら、ファイアウォール設定 (例: UFW、firewalld、iptables) を確認します。

4.    SSH が実行中であることを確認し、SSH TCP ポート (22) がリスニング状態であることを確認します。

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

注: システムに ss コマンドがない場合は、前述の例で示されているのと同じ構文を使用してレガシー netstat コマンドを使用できます。

5.    セッションを終了します

6.    SSH を使ってインスタンスに接続します。

方法 3: AWSSupport-TroubleshootSSH オートメーションドキュメントを実行する

AWSSupport-TroubleshootSSH オートメーションドキュメントは、Amazon EC2Rescue ツールをインスタンスにインストールします。このツールは、SSH 経由で Linux マシンに接続する時にリモート接続エラーを引き起こすいくつかの問題を確認して修正します。詳細については、「SSH を使用して EC2 インスタンスに接続しようとすると、エラーが発生します。AWSSupport-TroubleshootSSH Automation ワークフローを使用して、SSH 接続の問題をトラブルシューティングする方法を教えてください」を参照してください。

方法 4: ユーザーデータスクリプトを使用する

重要

  • この手順では、EC2 インスタンスの停止と開始が必要です。インスタンスが instance store-backed であるか、データを含むインスタンスストアボリュームがインスタンスにある場合、インスタンスが停止するとデータが失われることにご注意ください。詳細については、「インスタンスのルートデバイスタイプの判別」を参照してください。
  • インスタンスが Amazon EC2 Auto Scaling グループの一部である場合、またはインスタンスが AWS Auto Scaling を使用するサービス (Amazon EMR、AWS CloudFormation、AWS Elastic Beanstalk など) によって起動された場合には、インスタンスを停止するとインスタンスが終了する可能性があります。このシナリオでのインスタンスの削除は、Auto Scaling グループのインスタンススケールイン保護設定によって異なります。インスタンスが Auto Scaling グループの一部である場合は、解決手順を開始する前に、一時的に Auto Scaling グループからインスタンスを削除してください。
  • インスタンスを停止および再開すると、インスタンスのパブリック IP アドレスが変更されます。インスタンスに外部トラフィックをルーティングするときは、パブリック IP アドレスではなく Elastic IP アドレスを使用することがベストプラクティスです。

1.    EC2 インスタンスコンソールログを表示します。UFW が有効な場合、EC2 インスタンスコンソールログに次のエントリが表示されます。

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

2.    Amazon EC2 コンソールを開きます。

3.    ナビゲーションペインで [インスタンス] を選択し、接続しようとしているインスタンスをクリックします。

4.    インスタンスを停止します

5.    [Actions] (アクション)、[Instance Settings] (インスタンス設定)、[Edit user data] (ユーザーデータを編集) の順に選択します。

6.    [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 -F
service sshd restart
--//

注: 前述のコマンドは、ポート 22 だけでなく、すべての iptables ルールをフラッシュします。インスタンスへのアクセスを回復したら、ファイアウォール設定 (例: UFW、firewalld、iptables) を確認します。

7.    SSH を使ってインスタンスに接続します。

8.    前述のユーザーデータスクリプトは、インスタンスを再起動するたびに実行されるように設定されています。インスタンスへのアクセスを回復したら、ユーザーデータスクリプトを削除します。

ユーザーデータの削除方法:

1.    方法 4: ユーザーデータスクリプトを使用するのセクションのステップ 1~4 を実行します。

2.    [Edit User Data] (ユーザーデータを編集) ダイアログボックスでユーザーデータスクリプトを削除します。