SSH を使用して EC2 インスタンスに接続しようとすると、「接続が拒否されました」または「接続がタイムアウトしました」というエラーが表示されます。これを解決する方法を教えてください。

所要時間4分
0

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 ポートでリスニングしているサービスはありませんでした。
  • ファイアウォールがブロックされ、パッケージをドロップする代わりに拒否するように設定されました。

解決策

「接続タイムアウト」エラー

「接続がタイムアウトしました」エラーについては、以下を確認してください。

  • インスタンスの IP アドレスまたはホスト名に間違いがないこと。
  • インスタンスがヘルスチェックに合格していること。
  • インスタンスのセキュリティグループが TCP ポート 22 の受信トラフィックを許可していること。
  • インスタンスサブネットのネットワーク ACL が、受信トラフィックを TCP ポート 22 で許可しており、さらに、送信トラフィックには一時ポートを許可していること。
  • インスタンスのサブネットのルートテーブルで、EC2 インスタンスと SSH クライアント間の接続を提供するように適切な設定が行われていること。
  • SSH クライアントと EC2 インスタンス間の接続をブロックするような、ファイアウォールが存在しないこと。
  • SSH が (Red Hat ウェブサイト上の) インスタンスの TCP ラッパーによってブロックされていないこと。

注: 最後の 2 つの検証ステップでは、インスタンスの OS レベルのアクセスが必要です。

「接続拒否」エラー

「接続が拒否されました」というエラーについては、以下を確認してください。

  • インスタンスに SSH 接続を拒否するファイアウォールがないこと。
  • SSH デーモン (sshd) が実行中で、ポート 22 でリッスンしていること。

注: どちらの検証ステップでも、インスタンスへの OS レベルのアクセスが必要です。

インスタンスが両方のヘルスチェックに合格した場合は、以下の 4 つの方法のいずれかを設定で使用してください

  • 方法 1: Linux 用 EC2 シリアルコンソールを使用する。
  • 方法 2: AWS Systems Manager Session Manager を使用する。
  • 方法 3: AWSSupport-TroubleshootSSH 自動化ランブックを実行する。
  • 方法 4: ユーザーデータスクリプトを使用する。

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

設定すると、Linux 用 EC2 シリアルコンソールを使用して、サポートされている Nitro ベースのインスタンスタイプの OS レベルの問題をトラブルシューティングできます。シリアルコンソールを使用すると、起動に関する問題、ネットワーク構成、および SSH 設定の問題をトラブルシューティングできます。Amazon EC2 コンソールまたは AWS コマンドラインインターフェイス (AWS CLI) を使用してシリアルコンソールにアクセスすることができます。

シリアルコンソールを使用する前に、アカウントレベルでシリアルコンソールへのアクセスを許可する必要があります。次に、IAM ユーザーにアクセス権を付与する AWS ID およびアクセス管理 (IAM) ポリシーを作成します。

注: シリアルコンソールを使用する各インスタンスには、sudo アクセス権を持つパスワードベースの Linux ユーザーが少なくとも 1 人含まれている必要があります。

Linux 用 EC2 シリアルコンソールの設定の詳細については、「EC2 シリアルコンソールへのアクセスを設定する」を参照してください。ログインパスワードが設定されている Linux アカウントがない場合は、ssm-user を実行して sudo アクセス権のあるアカウントのパスワードをリセットする必要があります。ssm-user コマンドの実行について詳しくは、「Linux と macOS での ssm ユーザーの sudo アカウント権限の管理」を参照してください。

設定後、パスワードが設定された Linux ユーザーを使用して EC2 シリアルコンソールから EC2 インスタンスに接続します。

以下のコマンドを実行します。これらのコマンドは、SSH 接続が OS ファイアウォールまたは TCP ラッパーによってブロックされていないことを確認します。これらのコマンドは、sshd サービスがポート 22 で実行され、リッスンされていることも確認します。

1. iptables ルールを設定している場合は、次のコマンドを実行して、デフォルトポート 22 ですべての S SH 接続を受け入れるルールを iptables に追加します。

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

OS ベースのファイアウォールの代わりにセキュリティグループを使用するのがベストプラクティスなので、ファイアウォールを完全に無効にすることができます。OS ベースのファイアウォールを無効にするには、オペレーティングシステムに応じて、次のいずれかのコマンドセットを使用します:

重要: 以下のコマンドは、iptables のメインルールをすべてフラッシュします。また、SSH 接続を許可するルールも追加します。さらに、iptables ルールをフラッシュしてもインスタンスのネットワーク接続に影響を与えないように、メインチェーンのデフォルトポリシーを ACCEPT に変更します。これらのコマンドはメインの iptables をすべてフラッシュするので、既存のルールもすべてフラッシュされます。

UFW を使用するディストリビューション (Ubuntu、Debian)

$ 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

注: インスタンスに再びアクセスしたら、ファイアウォールの設定 (UFW、firewalld、iptables) を確認します。

2. SSH が動作していることを確認し、SSHTCP ポート (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 Systems Manager Session Manager を使用する

注: この方法を使用するには、インスタンスが SSM マネージドインスタンスで、SSM エージェントの ping ステータスがOnlineである必要があります。Session Manager の詳細と前提条件の一覧については、「Session Manager のセットアップ」を参照してください。

SSH 接続がファイアウォールまたは TCP ラッパーによってブロックされていないこと、および sshd サービスがポート 22 で実行およびリッスンされていることを確認するには、以下を行います。

1. AWSSystemsManager を開きます。

2. Session Manager を使用してインスタンスのセッションを開始します。

3. 方法 1 のステップ 1 ~ 4 に従います。 Linux 用の EC2 シリアルコンソールを使用します。

4. 不要になった場合は、Session Manager セッションを閉じます。

方法 3: AWSSupport-TroubleshootSSH ランブックを実行する

AWSSupport-TroubleshootSSH 自動化ランブックは Linux 用のAmazon EC2Rescue ツールをインスタンスにインストールします。このツールは、Linux ホストに SSH 経由でリモート接続できない問題をチェックし、修正を試みます。

AWSSupport-TroubleshootSSH ランブックを実行するには、以下を行います。

1. AWSSupport-TroubleshootSSH ページを開きます。

2. [このオートメーションを実行 (コンソール)] を選択します。

詳細については、「SSH を使用して EC2 インスタンスに接続しようとするとエラーが発生します。AWSSupport-TroubleshootSSH 自動化ワークフローを使用して SSH 接続に関する問題をトラブルシューティングするにはどうすればよいですか?」を参照してください。

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

説明されている方法のいずれも環境に適していない場合は、EC2 ユーザーデータスクリプトを使用してください。EC2 ユーザーデータスクリプトは OS レベルのファイアウォールと TCP ラッパーをオフにしてから、sshd サービスを再起動します。

重要:

  • この手順では、EC2 インスタンスを停止して起動する必要があります。インスタンスにインスタンスストアボリュームに保存されているデータがある場合、そのデータはインスタンスを停止した後に削除されます。
  • インスタンスが Amazon EC2 Auto Scaling グループの一部である場合、インスタンスを終了すると Auto Scaling グループ内のインスタンスも停止する可能性があります。
  • インスタンスが AWS Auto Scaling を使用するサービスによって起動された場合、インスタンスを終了すると Auto Scaling グループ内のインスタンスも停止する可能性があります。
  • インスタンスの終了は、Auto Scaling グループのインスタンススケールイン保護設定によって異なります。インスタンスが Auto Scaling グループの一部である場合は、解決手順を開始する前に Auto Scaling グループから一時的にインスタンスを削除します
  • インスタンスを停止および再開すると、インスタンスのパブリック IP アドレスが変更されます。外部トラフィックをインスタンスにルーティングする場合は、パブリック IP アドレスの代わりに Elastic IP アドレスを使用するのがベストプラクティスです。

以下の手順に従って、インスタンスのユーザーデータを設定します。

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

2. ナビゲーションペインから [インスタンス] を選択し、接続する予定のインスタンスを選択します。

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

4. [アクション][インスタンス設定][ユーザーデータを編集] を選択します。

5. 次のユーザーデータスクリプトを [ユーザーデータを編集] ダイアログボックスにコピーし、[保存] を選択します。

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. **[ユーザーデータを編集]**ダイアログボックスでユーザーデータスクリプトを削除します。

関連情報

インスタンスへの接続中にエラーが発生しました: 接続がタイムアウトしました

インターネットからの Amazon EC2 インスタンスの「接続がタイムアウトしました」というエラーをトラブルシューティングする方法を教えてください。

SSH を使用して Amazon EC2 Linux インスタンスへの接続をトラブルシューティングする方法を教えてください。

EC2 Linux インスタンスにアクセスできず、ステータスチェックの一方または両方が失敗するのはなぜですか?

AWS公式
AWS公式更新しました 1年前
コメントはありません

関連するコンテンツ