SSH を使用して EC2 インスタンスへの接続を試みると、「接続が拒否されました」または「接続がタイムアウトしました」というエラーが表示されます。これを解決する方法を教えてください。
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-user sudo のアカウント許可の管理」を参照してください。
設定後、パスワードが設定された Linux ユーザーを使用して EC2 シリアルコンソールから EC2 インスタンスに接続します。
次に、以下のコマンドを実行します。これらのコマンドは、SSH 接続が OS ファイアウォールや TCP ラッパーでブロックされていないことを確認します。これらのコマンドは、sshd サービスがポート 22 で実行しており、リッスン中であることも確認します。
1. iptables ルールを設定している場合、次のコマンドを実行して、デフォルトのポート 22 ですべての SSH 接続を受け入れるルールを 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 が動作していて、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 Systems Manager Session Manager を使用する
**注:**この方法を使用するには、インスタンスが SSM マネージドインスタンスであり、SSM エージェントの ping ステータスが Online である必要があります。Session Manager の詳細と前提条件の完全なリストについては、「Session Manager のセットアップ」を参照してください。
SSH 接続がファイアウォールまたは TCP ラッパーによってブロックされていないこと、および sshd サービスがポート 22 で実行およびリッスン中であることを確認するには、以下の手順を実施します:
1. AWS Systems Managerを開きます。
2. Session Manager を使用してインスタンスのセッションを開始します。
3. 方法 1 のステップ 1~4 に従います: Linux 用の EC2 シリアルコンソールを使用します。
4. 不要になった場合は、Session Manager セッションを閉じます。
方法 3: AWSSupport-TroubleshootSSH ランブックを実行する
AWSSupport-TroubleshootSSH 自動化ランブックでは、Linux 用の Amazon EC2Rescue ツールがインスタンスにインストールされます。このツールは、SSH 経由の Linux ホストへのリモート接続が妨げられる問題をチェックし、修正を試みます。
AWSSupport-TroubleshootSSH ランブックを実行するには、以下の手順を実施します:
1. AWSSupport-TroubleshootSSHページを開きます。
2. [この Automation (コンソール) を実行する] を選択します。
方法 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、firewalld、iptablesなど) を確認します。
ユーザーデータを削除するには、以下を実施します:
1. 方法 4 の手順 1~4 を完了します: ユーザーデータスクリプトセクションを使用します。
2. [ユーザーデータの編集] ダイアログボックスのユーザーデータスクリプトを削除します。
関連情報
インスタンスへの接続中のエラー: 接続がタイムアウトしました
Amazon EC2 インスタンスの「接続がタイムアウトしました」というインターネットのエラーをトラブルシューティングする方法を教えてください。
SSH を使用して Amazon EC2 Linux インスタンスへの接続をトラブルシューティングする方法を教えてください。
関連するコンテンツ
- 質問済み 2年前lg...
- 質問済み 6ヶ月前lg...
- 質問済み 4ヶ月前lg...
- 質問済み 6ヶ月前lg...
- AWS公式更新しました 1年前