
AWS EC2 SSH接続トラブルシューティング実践ガイド – Permission deniedからタイムアウトまで完全解決
お疲れ様です!IT業界で働くアライグマです!
「AWS EC2にSSH接続できない…Permission deniedって何?」
「昨日まで問題なく接続できていたのに、今日突然タイムアウトする」
「セキュリティグループは正しく設定しているはずなのに接続できない」
EC2インスタンスへのSSH接続トラブルは、クラウドインフラを運用する上で避けて通れない課題です。
私がPjMとして複数のAWSプロジェクトを担当してきた中でも、SSH接続エラーは開発チームが最も頻繁に遭遇する問題の1つでした。
本記事では、AWS EC2におけるSSH接続トラブルの診断から解決までを体系的に解説します。
エラーパターンごとの具体的な対処法、EC2 Instance Connectの活用方法、そしてトラブルを未然に防ぐための設定ベストプラクティスまで、実務で即活用できる知識を提供します。
AWS EC2でSSH接続できない主な原因パターン5つ
EC2へのSSH接続が失敗する原因は多岐にわたりますが、実際の運用現場で遭遇する問題の大半は5つのパターンに分類できます。
ここでは各パターンの特徴と、どのような状況で発生するのかを整理します。
認証エラー(Permission denied, publickey)
最も頻繁に遭遇するのが認証関連のエラーです。
このエラーは、SSH接続時に使用する秘密鍵とEC2インスタンスに登録されている公開鍵が一致しない場合に発生します。
具体的には以下のような状況で発生します。
インスタンス起動時に指定したキーペアと異なる秘密鍵を使用している場合、秘密鍵ファイルのパーミッションが適切でない場合(600以外)、またはキーペアを再生成したが古い秘密鍵を使い続けている場合などです。
私が担当したプロジェクトでは、開発メンバーが複数のAWSアカウントを使い分けていたため、異なるアカウントのキーペアを誤って使用してしまうケースが頻発しました。
この問題を解決するため、チーム内でキーペア命名規則を統一し、SSH configファイルでアカウントごとに秘密鍵を自動選択する設定を導入しました。インフラエンジニアの教科書では、このような運用設計の基本が体系的に解説されています。
ネットワーク到達性の問題(Connection timeout)
接続試行後にタイムアウトが発生する場合、ネットワークレイヤーでの通信障害が原因です。
このパターンでは、セキュリティグループの設定ミス、ネットワークACL(NACL)の制限、またはルートテーブルの設定不備が主な原因となります。
タイムアウトエラーは、エラーメッセージが表示されるまでに時間がかかるため、原因の切り分けに時間を要する点が特徴です。
セキュリティグループでSSH(ポート22)が適切に開放されているか、送信元IPアドレスが正しく指定されているか、インターネットゲートウェイが正しくアタッチされているかなど、複数のチェックポイントを順番に確認する必要があります。ゼロトラストネットワーク[実践]入門では、ゼロトラストの観点からネットワークセキュリティ設計を見直す手法が紹介されています。
ホスト鍵検証エラー(Host key verification failed)
「Host key verification failed」エラーは、接続先サーバーのホスト鍵が~/.ssh/known_hostsファイルに保存されているものと異なる場合に発生します。
このエラーは、EC2インスタンスを停止・起動した際にパブリックIPアドレスが変わった場合や、同じIPアドレスで異なるインスタンスが起動された場合に表示されます。
セキュリティ上の理由から、SSHクライアントが接続先の変更を検知して警告を出している状態です。
実務では、開発環境のインスタンスを頻繁に起動・停止するため、このエラーに遭遇する頻度が高くなります。
一時的な回避策として、known_hostsファイルから該当エントリを削除する方法がありますが、根本的にはElastic IPを使用してIPアドレスを固定する、またはホスト名ベースの接続に切り替えることで問題を解消できます。
インスタンスの状態異常
EC2インスタンス自体に問題がある場合、SSH接続は確立できません。
インスタンスのステータスチェックが失敗している場合や、OS起動時にエラーが発生している場合がこれに該当します。
AWSコンソールの「ステータスチェック」で、システムステータスチェックとインスタンスステータスチェックの両方が「合格」になっているか確認する必要があります。
どちらかが失敗している場合、EC2インスタンスの再起動や、最悪の場合はスナップショットからの復元が必要になります。
私が経験したケースでは、ディスク容量が100%になったことでSSHデーモンが正常に動作せず、接続できなくなった事例がありました。
この時はEC2 Instance Connectを使って緊急アクセスし、不要なログファイルを削除することで復旧できました。3カ月で改善!システム障害対応 実践ガイドには、このような障害対応の実践的な手順が詳しく記載されています。
SSHデーモンの設定問題
EC2インスタンス内のSSHデーモン(sshd)の設定が適切でない場合も接続エラーの原因となります。
/etc/ssh/sshd_configファイルで、公開鍵認証が有効になっているか(PubkeyAuthentication yes)、パスワード認証が無効になっているか(PasswordAuthentication no)、そして適切なポートが設定されているかを確認する必要があります。
また、sshdサービスが正常に起動しているかも重要なチェックポイントです。
システム起動時にsshdが自動起動するよう設定されていない場合、インスタンスを再起動した後にSSH接続ができなくなります。ロジクール MX KEYS (キーボード)のような高品質な入力デバイスを使うことで、設定ファイルの編集作業を快適に行えます。
Permission denied (publickey) エラーの完全解決法
Permission deniedエラーは、SSH接続トラブルの中で最も遭遇頻度が高く、原因の特定にも時間がかかりやすい問題です。
ここでは、このエラーを体系的に診断し、確実に解決するための手順を解説します。
秘密鍵ファイルのパーミッション確認
まず最初に確認すべきは、秘密鍵ファイルのパーミッションです。
SSHクライアントは、セキュリティ上の理由から、秘密鍵ファイルのパーミッションが厳格に設定されていることを要求します。
秘密鍵ファイルのパーミッションは必ず600(所有者のみ読み書き可能)に設定する必要があります。
以下のコマンドで確認と修正を行います。
確認コマンド: ls -la ~/.ssh/your-key.pem
修正コマンド: chmod 600 ~/.ssh/your-key.pem
パーミッションが644や755に設定されていると、「WARNING: UNPROTECTED PRIVATE KEY FILE!」という警告とともに接続が拒否されます。
この問題は、WindowsからLinux/macOSに秘密鍵ファイルを移動した際に頻発します。
正しいキーペアの使用確認
次に、使用している秘密鍵がEC2インスタンス起動時に指定したキーペアと一致しているか確認します。
AWSコンソールでEC2インスタンスの詳細を開き、「キーペア名」フィールドに表示されている名前を確認します。
この名前と、手元にある秘密鍵ファイルの名前が一致していることを確認してください。
SSH接続時に明示的に秘密鍵を指定する場合は、以下のようにコマンドを実行します。
接続コマンド例: ssh -i ~/.ssh/your-key.pem ec2-user@your-instance-public-ip
-iオプションで秘密鍵ファイルのパスを指定することで、どの秘密鍵を使用しているか明確になります。実践Terraform AWSにおけるシステム設計とベストプラクティスでは、Terraformを使ったキーペア管理の自動化手法が解説されており、複数環境での運用時に有用です。
SSH接続ユーザー名の確認
AMI(Amazon Machine Image)によって、デフォルトのSSHユーザー名が異なることに注意が必要です。
Amazon Linux 2/2023ではec2-user、Ubuntuではubuntu、RHELではec2-userまたはrhel、Debianではadmin、SUSEではec2-userまたはrootが使用されます。
誤ったユーザー名で接続を試みると、Permission deniedエラーが発生します。
使用しているAMIのドキュメントを確認し、適切なユーザー名を使用してください。
実際のプロジェクトで、開発メンバーがAmazon LinuxとUbuntuを混同し、間違ったユーザー名で接続を試みていたケースがありました。
この問題を防ぐため、SSH configファイルにホストごとのユーザー名を記載する運用に変更しました。Dell 4Kモニターのような大画面モニターを使うことで、複数のターミナルウィンドウを並べて作業効率を高められます。
詳細ログでの診断
原因が特定できない場合は、SSH接続時に詳細ログを出力することで問題を特定できます。
詳細ログ出力コマンド: ssh -vvv -i ~/.ssh/your-key.pem ec2-user@your-instance-public-ip
-vvvオプションを付けることで、SSH接続のプロセスが詳細に表示されます。
このログから、どの段階で認証が失敗しているか、どの秘密鍵ファイルが試行されているか、サーバーからどのようなレスポンスが返ってきているかを確認できます。
ログの中で「debug1: Offering public key」の後に「debug1: Server accepts key」が表示されれば認証成功、「debug1: Authentications that can continue: publickey」が表示されれば認証失敗を意味します。実践サイバーセキュリティ入門講座では、SSH認証の仕組みとセキュリティベストプラクティスが詳しく解説されています。
下記のグラフは、実際の運用現場で発生したSSH接続エラーの種類別発生頻度を示しています。
Permission deniedエラーが全体の約45%を占めており、適切な診断手順の確立が重要であることが分かります。
Connection timed out エラーの診断と対処フロー
Connection timeoutエラーは、クライアントからEC2インスタンスへのネットワーク通信が確立できない場合に発生します。
このエラーは複数のネットワーク層で問題が発生している可能性があるため、体系的な診断が必要です。
セキュリティグループの設定確認
最も頻繁な原因はセキュリティグループの設定不備です。
セキュリティグループは、EC2インスタンスに対するファイアウォールとして機能し、どのIPアドレスからどのポートへのアクセスを許可するかを制御します。
AWSコンソールでEC2インスタンスのセキュリティグループを開き、インバウンドルールを確認します。
SSH接続のためには、タイプがSSH、プロトコルがTCP、ポート範囲が22、ソースが接続元のIPアドレスという設定が必須です。
ソースの設定は、セキュリティ上の理由から、0.0.0.0/0(すべてのIPアドレス)ではなく、特定のIPアドレスまたはIPレンジに制限することを推奨します。
自分の現在のパブリックIPアドレスは、「curl ifconfig.me」コマンドで確認できます。
私が担当したプロジェクトでは、リモートワーク環境への移行に伴い、メンバーのIPアドレスが頻繁に変わるようになりました。
この課題に対し、VPN経由でのアクセスに統一することで、セキュリティグループの管理を簡素化しました。
ネットワークACL(NACL)の確認
セキュリティグループが正しく設定されていてもタイムアウトする場合、ネットワークACL(NACL)の設定を確認します。
NACLはサブネットレベルで動作するファイアウォールで、セキュリティグループとは異なり、ステートレスな制御を行います。
つまり、インバウンドとアウトバウンドの両方で明示的に通信を許可する必要があります。
AWSコンソールでVPCサービスを開き、該当するサブネットに関連付けられているNACLを確認します。
デフォルトのNACLはすべてのトラフィックを許可していますが、カスタムNACLを使用している場合は、SSH通信(ポート22)とエフェメラルポート(1024-65535)の両方向通信が許可されているか確認してください。
ルートテーブルとインターネットゲートウェイ
パブリックサブネットにあるEC2インスタンスにインターネット経由で接続する場合、ルートテーブルとインターネットゲートウェイの設定が適切である必要があります。
ルートテーブルに、送信先0.0.0.0/0のトラフィックをインターネットゲートウェイに向ける設定が含まれているか確認します。
この設定がない場合、インスタンスはインターネットとの通信ができず、SSH接続もタイムアウトします。
また、インスタンスにパブリックIPアドレスまたはElastic IPが割り当てられているかも確認してください。
プライベートIPアドレスのみが割り当てられている場合、インターネット経由での直接接続はできません。
実務では、開発環境と本番環境でネットワーク構成が異なるため、環境ごとにチェックリストを作成して確認漏れを防ぐことが重要です。
Infrastructure as Code(IaC)ツールを使用することで、ネットワーク設定の一貫性を保つことができます。
接続元ネットワークの確認
意外と見落とされがちなのが、接続元のネットワーク環境です。
企業ネットワークやカフェのWi-Fiなど、一部のネットワーク環境では、SSH通信(ポート22)がファイアウォールでブロックされている場合があります。
この場合、セキュリティグループやNACLの設定が正しくても接続できません。
確認方法として、telnetコマンドでポート22への到達性をテストできます。
到達性確認コマンド: telnet your-instance-public-ip 22
接続が確立されれば「Connected to…」と表示され、SSH通信が可能な環境であることが分かります。
接続できない場合は、別のネットワーク環境(例:スマートフォンのテザリング)から試すか、VPN接続を使用してください。
EC2 Instance Connectの活用と制限事項
EC2 Instance Connectは、ブラウザベースでEC2インスタンスにSSH接続できるAWSの機能です。
秘密鍵ファイルの管理が不要で、緊急時のアクセス手段として非常に有用です。
EC2 Instance Connectの仕組み
EC2 Instance Connectは、一時的な公開鍵をEC2インスタンスに送信し、60秒間だけ有効なSSHセッションを確立します。
この仕組みにより、開発者が秘密鍵ファイルをローカルに保存する必要がなくなり、キーファイルの紛失や漏洩のリスクを軽減できます。
また、AWS IAMと統合されているため、誰がいつどのインスタンスにアクセスしたかをCloudTrailで監査できる点も大きなメリットです。
私が担当したチームでは、新入社員のオンボーディング時にEC2 Instance Connectを使うことで、キーペアの配布作業を省略し、初日からスムーズに開発環境にアクセスできるようになりました。
EC2 Instance Connectの使用手順
EC2 Instance Connectを使用する手順は非常にシンプルです。
まず、AWSコンソールでEC2サービスを開き、接続したいインスタンスを選択します。
「接続」ボタンをクリックし、「EC2 Instance Connect」タブを選択します。
ユーザー名を確認し(通常はec2-userまたはubuntu)、「接続」ボタンをクリックすると、ブラウザ上でターミナルウィンドウが開きます。
AWS CLIを使用する場合は、以下のコマンドで接続できます。
CLI接続コマンド: aws ec2-instance-connect send-ssh-public-key –instance-id i-1234567890abcdef0 –availability-zone us-east-1a –instance-os-user ec2-user –ssh-public-key file://my_rsa_key.pub
この方法では、通常のSSHクライアントを使いながら、EC2 Instance Connectの認証メカニズムを利用できます。
制限事項と注意点
EC2 Instance Connectは便利な機能ですが、いくつかの制限事項があります。
まず、対応AMIが限定されています。
Amazon Linux 2、Ubuntu 16.04以降など、ec2-instance-connect パッケージがプリインストールされているAMIでのみ使用できます。
古いAMIや独自にカスタマイズしたAMIでは、手動でパッケージをインストールする必要があります。
また、セキュリティグループの設定で、AWSのIPアドレスレンジからのSSH接続を許可する必要があります。
EC2 Instance Connectは、各リージョンのAWS管理するIPアドレスから一時的な接続を行うため、このレンジをセキュリティグループで許可していないと接続できません。
さらに、プライベートサブネットにあるインスタンスに対しては、デフォルトでは使用できません。
この場合、EC2 Instance Connect Endpointを使用するか、踏み台サーバー経由でアクセスする必要があります。
実運用では、通常のSSH接続をメインとし、キーファイルの問題や緊急アクセスが必要な場合のバックアップ手段としてEC2 Instance Connectを位置づけることを推奨します。
セキュリティグループ・NACLの設定ミス回避策
ネットワーク設定の誤りは、SSH接続トラブルの約30%を占める重要な問題領域です。
ここでは、設定ミスを未然に防ぎ、迅速に問題を解決するための実践的なアプローチを解説します。
セキュリティグループ設定のベストプラクティス
セキュリティグループは、最小権限の原則に基づいて設計することが重要です。
開発環境であっても、SSH接続のソースIPアドレスは0.0.0.0/0(全世界からのアクセス許可)に設定すべきではありません。
特定の開発者のIPアドレス、オフィスの固定IPアドレス、またはVPNのIPレンジに制限することで、不正アクセスのリスクを大幅に軽減できます。
セキュリティグループには分かりやすい説明文を付けることも重要です。
「SSH access from office」や「Dev team VPN access」といった説明を各ルールに記載することで、後から設定を見直す際に意図が明確になります。
また、セキュリティグループは環境ごとに分けて管理することを推奨します。
開発環境用、ステージング環境用、本番環境用と分けることで、誤って本番環境に過度に緩い設定を適用してしまうリスクを防げます。
私のチームでは、Terraformを使ってセキュリティグループをコード管理し、Pull Requestによるレビュープロセスを導入しました。
これにより、設定変更時に複数人で確認できるようになり、設定ミスが大幅に減少しました。
NACLとセキュリティグループの使い分け
NACLとセキュリティグループは、それぞれ異なる目的と特性を持っています。
セキュリティグループはステートフルで、許可されたインバウンド通信に対する応答は自動的に許可されます。
一方、NACLはステートレスで、インバウンドとアウトバウンドの両方向で明示的に設定する必要があります。
基本的な方針として、日常的なアクセス制御はセキュリティグループで行い、サブネット全体での防御層としてNACLを使用します。
NACLは拒否ルールを設定できるため、特定のIPアドレスからの攻撃を検知した際にブロックリストとして活用できます。
多くの場合、デフォルトNACLをそのまま使用し、セキュリティグループで詳細な制御を行うのが実用的です。
ただし、コンプライアンス要件で多層防御が求められる場合は、NACLとセキュリティグループの両方で制御を行います。
設定変更時のチェックリスト
セキュリティグループやNACLの設定を変更する際は、以下の点を確認することで設定ミスを防げます。
変更内容を事前にドキュメント化し、影響範囲(どのインスタンスに影響するか)を明確にします。
変更前にバックアップとして現在の設定をスクリーンショットまたはテキストで保存し、緊急時に元に戻せるようにします。
変更後は即座に接続テストを実施し、期待通りの動作をするか確認します。
変更内容をチーム内で共有し、他のメンバーが問題に気づいた場合すぐに報告できる体制を整えます。
実務では、本番環境への設定変更は必ず2人以上で確認し、変更承認のプロセスを経ることを推奨します。
トラブル発生時の迅速な診断手順
ネットワーク設定起因のSSH接続トラブルが発生した際は、以下の順序で診断を進めます。
まず、AWSコンソールでセキュリティグループのインバウンドルールを確認し、SSH(ポート22)が適切に許可されているかチェックします。
次に、接続元のパブリックIPアドレスを確認し、セキュリティグループのソース設定と一致しているか検証します。
NACLの設定も確認し、カスタムNACLを使用している場合はインバウンドとアウトバウンドの両方でSSH通信が許可されているか確認します。
ルートテーブルとインターネットゲートウェイの設定を確認し、インターネット経由の通信が可能になっているか検証します。
この診断フローをチェックリスト化しておくことで、トラブル発生時に冷静かつ迅速に対応できます。
SSH接続トラブル予防と運用のベストプラクティス
トラブルが発生してから対処するのではなく、事前に予防策を講じることで、SSH接続の安定性と運用効率を大幅に向上させることができます。
ここでは、実務で効果が実証された予防策と運用方法を紹介します。
SSH Config ファイルの活用
SSH接続の設定を毎回コマンドラインで指定するのは非効率であり、ミスの原因にもなります。
SSH Configファイル(~/.ssh/config)を活用することで、接続設定を一元管理できます。
Config ファイルの設定例:
Host prod-web-server
HostName 54.123.45.67
User ec2-user
IdentityFile ~/.ssh/prod-key.pem
Port 22
Host dev-app-server
HostName 54.234.56.78
User ubuntu
IdentityFile ~/.ssh/dev-key.pem
ServerAliveInterval 60
この設定により、「ssh prod-web-server」というシンプルなコマンドで接続できるようになります。
ServerAliveIntervalオプションを設定することで、長時間のセッションでもタイムアウトを防げます。
私のチームでは、各環境のEC2インスタンスをConfig ファイルに登録し、Gitで管理しています。
新しいメンバーが参加した際は、このConfigファイルを共有することで、すぐに全環境へのアクセスが可能になります。
踏み台サーバー(Bastion Host)の運用
本番環境のEC2インスタンスには、直接インターネットからSSH接続できないようにすることがセキュリティのベストプラクティスです。
踏み台サーバーを経由したアクセスを実装することで、セキュリティを強化しつつ、管理も容易になります。
踏み台サーバーは、セキュリティグループで特定のIPアドレスからのみSSH接続を許可し、そこから内部ネットワークのインスタンスにアクセスする構成です。
SSH Configファイルで ProxyJump オプションを使用すると、踏み台経由の接続を透過的に行えます。
ProxyJump設定例:
Host bastion
HostName 54.123.45.67
User ec2-user
IdentityFile ~/.ssh/bastion-key.pem
Host internal-server
HostName 10.0.1.100
User ec2-user
IdentityFile ~/.ssh/internal-key.pem
ProxyJump bastion
この設定により、「ssh internal-server」コマンドで踏み台を自動的に経由して内部サーバーに接続できます。
実務では、AWS Systems Manager Session Managerを踏み台の代替として使用するケースも増えています。
Session Managerを使用すると、セキュリティグループでSSHポートを開放する必要がなく、よりセキュアな運用が可能です。
AWSの各種サービスを組み合わせた最適なアーキテクチャ設計については、AWS Lambda実践ガイドでも詳しく解説しています。
キーペアのライフサイクル管理
秘密鍵ファイルの管理は、セキュリティと運用の両面で重要です。
キーペアは定期的にローテーション(更新)することを推奨します。
最低でも年1回、理想的には四半期ごとにキーペアを更新することで、万が一の漏洩リスクを最小化できます。
キーペアのローテーション手順としては、新しいキーペアを作成し、EC2インスタンスの~/.ssh/authorized_keysファイルに追加します。
すべてのアクセス元で新しい秘密鍵に切り替えた後、古い公開鍵をauthorized_keysファイルから削除します。
また、メンバーごとに個別のキーペアを発行し、退職や異動時には速やかに該当キーペアを無効化する運用も重要です。
共有キーペアを使用していると、メンバー変更時に全員の秘密鍵を更新する必要があり、運用負荷が高くなります。
セキュリティ鍵の管理については、PC廃棄で情報漏えいリスク急増の記事でも物理的なセキュリティ管理の重要性を解説しています。
監視とアラートの設定
SSH接続の失敗をリアルタイムで検知し、迅速に対応できる体制を整えることも重要です。
CloudWatch Logsを使用して、/var/log/auth.logなどのSSH認証ログを収集し、失敗パターンを監視できます。
特定のIPアドレスから大量の接続試行が発生している場合、ブルートフォース攻撃の可能性があるため、即座にブロックする必要があります。
また、EC2インスタンスのステータスチェックが失敗した場合にSNS通知を送信する設定を行うことで、インスタンスの異常を早期に検知できます。
私が担当したプロジェクトでは、SSH接続失敗が10回連続で発生した場合にSlack通知を送る仕組みを導入しました。
これにより、設定ミスや攻撃の兆候を即座に把握し、迅速に対応できるようになりました。
AWSのセキュリティ運用全般については、AWS Certified AI Practitioner試験対策ガイドでも体系的に学習できます。
まとめ
本記事では、AWS EC2におけるSSH接続トラブルの診断から解決、そして予防策までを体系的に解説しました。
Permission deniedエラー、Connection timeoutエラー、Host key verification failedエラーなど、頻出する5つのエラーパターンそれぞれに対する具体的な診断手順と解決方法を提示しました。
EC2 Instance Connectの活用により、秘密鍵管理の負担を軽減しつつ、緊急時のアクセス手段を確保できることも説明しました。
セキュリティグループとNACLの適切な設定、SSH Configファイルの活用、踏み台サーバーの運用、キーペアのライフサイクル管理といったベストプラクティスを実践することで、SSH接続トラブルを大幅に削減できます。
実務では、トラブルが発生してから対処するのではなく、事前の設計と運用フローの整備が最も重要です。
本記事で紹介した診断フローとチェックリストをチーム内で共有し、誰でも迅速にトラブル対応できる体制を整えることをお勧めします。