2026 年メンテナンス注記:
Permission denied (publickey)は認証結果であり、原因の診断ではありません。この手順は読み取り専用の証拠収集から始め、クライアント、ネットワーク、サーバーの原因を分離し、オフラインのディスク修復より先に AWS がサポートする復旧経路を使います。管理権限を持つインスタンスだけを対象にしてください。
Table of Contents
ガードレールと復旧の判断門
- 変更前に、インスタンス ID、リージョン、Availability Zone、AMI ID、想定 OS ユーザー、キーペア名、現在のアドレス、ルートボリューム ID、ブロックデバイスマッピング、暗号化/KMS 状態、
DeleteOnTermination値を記録します。 - メンテナンス時間を確保し、ロールバック責任者を決めます。オフラインで書き込む前に EBS ルートボリュームのスナップショットを作成します。復元経路と KMS アクセスを理解して初めて、スナップショットは利用可能なバックアップになります。
- 秘密鍵、パスフレーズ、
authorized_keys全文、セッショントークン、未編集のssh -vvvログをチケットやチャットに貼らないでください。ホストキー検証を無効にしないでください。 - 一度に境界の明確な変更を一つだけ行い、別の SSH セッションで検証し、ロールバックが不要になるまで復旧経路を維持します。
- 対象インスタンス、アカウント、リージョン、ボリューム、ファイルシステム、想定ユーザー、鍵指紋、KMS 権限のいずれかが不明なら停止します。
このエラーが示すこと、示さないこと
Permission denied (publickey) は通常、TCP 接続が SSH サービスに到達したものの、そのユーザーに対して提示された公開鍵が一つも受理されなかったことを示します。タイムアウト、DNS 失敗、Connection refused、ホストキー検証失敗、EC2 ステータスチェック失敗は別の分岐です。分岐が明確になるまで鍵の交換やサーバーファイルの編集を行わないでください。
機密情報を含めず AWS 側の識別情報を取得します:
aws ec2 describe-instances
--instance-ids i-REPLACE_WITH_INSTANCE_ID
--query 'Reservations[0].Instances[0].{State:State.Name,ImageId:ImageId,KeyName:KeyName,AZ:Placement.AvailabilityZone,PublicIp:PublicIpAddress,PrivateIp:PrivateIpAddress,SubnetId:SubnetId,VpcId:VpcId,SecurityGroups:SecurityGroups[*].GroupId,RootDevice:RootDeviceName}'
--output yaml
EC2 の KeyName は起動時に選んだ鍵を記録するだけで、現在の authorized_keys が未変更であることを証明しません。イメージ、構成管理、user-data スクリプト、管理者が後から変更している場合があります。
1. AWS を変更する前にクライアントの識別情報を確認する
公式 Ubuntu AMI の初期ユーザーは通常 ubuntu ですが、別の AMI や後から作成したアカウントでは異なります。ユーザー名を順番に試すのではなく、AMI と対象アカウントを確認します。-i が .pub ではなく秘密鍵を指すことを確認し、AWS の要件どおりローカル秘密鍵の権限を制限します:
chmod 400 /secure/path/to/private-key.pem
ssh-keygen -lf /secure/path/to/private-key.pem
ssh-keygen -y -f /secure/path/to/private-key.pem | ssh-keygen -lf -
最後のコマンドはメモリ上で公開鍵部分だけを導出し、その指紋を表示します。秘密鍵は公開しません。すでに信頼できる復旧経路から、対象ユーザーに期待される正確な行の指紋と比較します:
sudo -u ubuntu ssh-keygen -lf /home/ubuntu/.ssh/authorized_keys
アルゴリズム名が同じだけでは不十分で、指紋が許可された行の一つと一致する必要があります。AWS キーペアの指紋計算は鍵の生成元とアルゴリズムで異なるため、EC2 コンソールとの比較には AWS 公式の指紋手順を使います。秘密鍵を紛失した場合、EC2 から再ダウンロードできません。代替の身元情報を作り上げず、サポート対象の復旧経路へ進みます。
2. サーバーのホストキーを確認する
ホストキーはサーバーを認証するもので、利用者を認証するユーザー鍵とは別です。信頼できる AWS コントロールプレーン経路からインスタンス指紋を取得し、SSH の表示と比較します:
aws ec2 get-console-output
--instance-id i-REPLACE_WITH_INSTANCE_ID
--query Output
--output text
システムログの BEGIN SSH HOST KEY FINGERPRINTS を探します。コンソール出力にはホスト名、アドレス、起動メッセージ、user-data 出力が含まれることがあるため、共有前に編集します。ホストキーが予期せず変わった場合は停止し、DNS/IP がこのインスタンスを指していることを確認して、交換や再構築を調査します。厳格なホストキー検証を無効にしたり known-hosts 記録を捨てたりして警告を回避しないでください。
3. 最小限の詳細トレースを収集する
エージェントに読み込まれた多数の鍵で結果が曖昧にならないよう、対象の識別情報を強制します:
ssh -vvv
-o IdentitiesOnly=yes
-i /secure/path/to/private-key.pem
ubuntu@REPLACE_WITH_VERIFIED_HOSTNAME
トレースはローカルで読み取ります:
| 証拠 | 想定される分岐 |
|---|---|
| SSH 識別前の経路なし、タイムアウト、接続拒否 | アドレス、経路、セキュリティグループ、NACL、ローカル/ホストファイアウォール、または sshd の可用性 |
| ホストキー不一致 | 誤ったエンドポイント、再構築済みホスト、古い信頼記録、または傍受の可能性。続行前に検証 |
| 対象の鍵が提示されない | 誤った -i、読めない/非対応の鍵、SSH 設定、またはエージェント選択 |
| 対象の鍵が提示されるが拒否 | OS ユーザー違い、許可鍵の欠落/不一致、所有者/モード、有効な sshd ポリシー、外部鍵コマンド |
詳細ログと指紋出力にはユーザー名、ローカルパス、IP、ホストキーと公開鍵の指紋、鍵コメント、プロキシコマンド、設定が含まれ得ます。これらを伏せ、秘密鍵情報やパスフレーズは絶対に含めないでください。
4. ネットワーク経路を独立して証明する
まずインスタンスが running で、システムとインスタンスの両ステータスチェックが正常であることを確認します。次に、実際の経路を緩和せず検査します:
aws ec2 describe-instance-status
--instance-ids i-REPLACE_WITH_INSTANCE_ID
--include-all-instances
aws ec2 describe-security-groups
--group-ids sg-REPLACE_WITH_GROUP_ID
aws ec2 describe-network-acls
--filters Name=association.subnet-id,Values=subnet-REPLACE_WITH_SUBNET_ID
aws ec2 describe-route-tables
--filters Name=association.subnet-id,Values=subnet-REPLACE_WITH_SUBNET_ID
接続先アドレス、サブネット経路、インターネットゲートウェイ/NAT/VPN/踏み台または EC2 Instance Connect Endpoint の経路、セキュリティグループの送信元、NACL の戻り通信、企業/ローカルの送信、ホストファイアウォールを確認します。SSH の受信元は必要な送信元または AWS 管理プレフィックスリストに限定し、診断のためにポート 22 を全世界へ開かないでください。VPC 経路が正常でも sshd の待受は証明されず、公開鍵の拒否は通常ネットワーク経路が機能したことを示します。
5. AWS がサポートする復旧経路を優先する
前提条件がすでに整っている最初の経路を選びます。復旧経路を作るために SSH を弱めないでください。
| 経路 | 使用条件 | 重要な判断門 |
|---|---|---|
| EC2 Instance Connect | AMI/パッケージ、IAM 権限、ユーザー名、ネットワーク経路が対応 | インスタンス側のサービス/設定と、該当する SSH 経路またはエンドポイントに引き続き依存 |
| Systems Manager Session Manager | SSM Agent、適切なインスタンスプロファイル、サービス接続を備えた既存の管理対象ノード | 広範な IAM 権限を臨時付与せず、組織の Session Manager アクセスポリシーに従う |
| EC2 Serial Console | アカウント/リージョン、インスタンスタイプ、IAM、OS ログインの前提を満たす | VPC データ経路には依存しないが、Linux の対話的調査には通常、事前設定済みのパスワード付き OS ユーザーが必要 |
AWSSupport-TroubleshootSSH | Systems Manager Automation 権限があり、AWS EC2Rescue の検査を使う | デフォルトで読み取り専用の CheckAll から開始し、FixAll やオフライン修復前に範囲を確認 |
信頼できる経路で入ったら、変更前にサーバー側の証拠を収集します:
id ubuntu
namei -l /home/ubuntu/.ssh/authorized_keys
stat -c '%n owner=%U:%G uid=%u gid=%g mode=%a type=%F'
/home/ubuntu
/home/ubuntu/.ssh
/home/ubuntu/.ssh/authorized_keys
sudo -u ubuntu ssh-keygen -lf /home/ubuntu/.ssh/authorized_keys
sudo sshd -t
sudo sshd -T
-C user=ubuntu,host=REPLACE_WITH_INSTANCE_HOSTNAME,addr=REPLACE_WITH_CLIENT_IP
| grep -E '^(pubkeyauthentication|authorizedkeysfile|authorizedkeyscommand|strictmodes|allowusers|denyusers|allowgroups|denygroups) '
sudo systemctl status ssh --no-pager
対象試行に関する、編集済みの journalctl -u ssh 記録も確認します。有効なポリシーは sshd_config、include された断片、Match ブロック、EC2 Instance Connect のような AuthorizedKeysCommand から来ることがあります。一つのファイルだけが有効だと仮定しないでください。
6. 境界の明確な権限修復を一度だけ行う
home、.ssh、authorized_keys を他ユーザーが変更できる場合、OpenSSH StrictModes は鍵認証を拒否します。所有者は対象アカウントでなければなりません。前の namei と stat 出力を基準とし、getfacl がインストール済みなら ACL も取得します。以下のパスを使う一般的な Ubuntu アカウントでは、この三つのオブジェクトだけを修復します。home ツリー全体への再帰的な chmod や chown は行いません:
sudo getfacl -p
/home/ubuntu
/home/ubuntu/.ssh
/home/ubuntu/.ssh/authorized_keys
sudo chown ubuntu:ubuntu /home/ubuntu
sudo chmod go-w /home/ubuntu
sudo chown ubuntu:ubuntu
/home/ubuntu/.ssh
/home/ubuntu/.ssh/authorized_keys
sudo chmod 700 /home/ubuntu/.ssh
sudo chmod 600 /home/ubuntu/.ssh/authorized_keys
これは一般的な制限モードであり、すべての環境への一律の指示ではありません。有効な AuthorizedKeysFile、アカウントデータベース、ACL/SELinux/AppArmor ポリシー、NFS の ID マッピング、イメージ構成が異なる場合は停止して対応資料に従います。正しい公開鍵指紋がなければ、管理された鍵交換として扱います。現在のファイルを保持し、新しい公開鍵指紋を承認し、AWS 公式の鍵追加/交換手順に従い、古い行を削除する前に新しい鍵を検証します。
復旧セッションを維持したまま、別の端末から検証します:
sudo sshd -t
sudo systemctl is-active ssh
ssh -o IdentitiesOnly=yes
-i /secure/path/to/private-key.pem
ubuntu@REPLACE_WITH_VERIFIED_HOSTNAME
失敗した場合は記録した所有者/モード/ACL と比較し、変更したオブジェクトだけを戻します。ファイルメタデータだけを変更した場合、ssh の再読み込みや再起動は不要です。SSH 設定を変更した場合は、sshd -t で検証してから管理された再読み込みを行い、復旧経路を維持します。
7. ルートボリューム救援は最後の保守経路
ルートが EBS-backed で、サポートされるオンライン復旧経路がすべて使えない場合だけオフライン修復を行います。停止前に、停止承認、依存サービス、Auto Scaling の挙動、公開アドレスの挙動、全ボリュームマッピング、DeleteOnTermination、instance-store データを記録します。AWS によれば、stop/start では Elastic IP でない公開 IPv4 が変わる場合があり、instance-store データは消去されます。ルートボリュームをスナップショットし、補助インスタンスが同じ Availability Zone にあり、ボリュームの KMS キーを使用できることを確認します。
元のインスタンスを停止してルート EBS ボリュームを安全にデタッチした後、管理された補助インスタンスへデータボリュームとしてアタッチします。/dev/sda2 を推測してはいけません。Nitro インスタンスでは EBS デバイスが変動する NVMe 名で列挙されます。EC2 ボリューム ID とデバイスのシリアルを対応させ、ファイルシステムとパーティションを読み取り専用で識別します:
lsblk -o NAME,SERIAL,SIZE,FSTYPE,UUID,MOUNTPOINTS
sudo blkid
sudo file -s /dev/REPLACE_WITH_VERIFIED_DEVICE
mkfs、自動修復、強制ファイルシステム検査を実行しないでください。コンソールのボリューム ID、NVMe シリアル、パーティションテーブル、ファイルシステム、期待するルート内容が一致してから RESCUE_PARTITION を設定します。最初は読み取り専用でマウントします:
RESCUE_ROOT='/mnt/ec2-root'
RESCUE_PARTITION='/dev/REPLACE_WITH_VERIFIED_ROOT_PARTITION'
sudo install -d -m 700 "$RESCUE_ROOT"
sudo mount -o ro "$RESCUE_PARTITION" "$RESCUE_ROOT"
findmnt "$RESCUE_ROOT"
sudo test -f "$RESCUE_ROOT/etc/os-release"
sudo test -d "$RESCUE_ROOT/home/ubuntu/.ssh"
所有者は補助側の ubuntu ではなく、オフラインシステム自身のアカウントデータベースから解決し、書き込み前にメタデータを記録します:
TARGET_USER='ubuntu'
TARGET_UID="$(awk -F: -v u="$TARGET_USER" '$1==u {print $3}' "$RESCUE_ROOT/etc/passwd")"
TARGET_GID="$(awk -F: -v u="$TARGET_USER" '$1==u {print $4}' "$RESCUE_ROOT/etc/passwd")"
printf 'target uid=%s gid=%sn' "$TARGET_UID" "$TARGET_GID"
sudo stat -c '%n uid=%u gid=%g mode=%a type=%F'
"$RESCUE_ROOT/home/$TARGET_USER"
"$RESCUE_ROOT/home/$TARGET_USER/.ssh"
"$RESCUE_ROOT/home/$TARGET_USER/.ssh/authorized_keys"
sudo ssh-keygen -lf "$RESCUE_ROOT/home/$TARGET_USER/.ssh/authorized_keys"
想定ユーザー、UID/GID、指紋、パスが一致しなければ、読み書きで再マウントせずエスカレーションします。すべてが一致し、メタデータが原因と証明できた場合だけ、一度の境界が明確な書き込みを承認します:
sudo mount -o remount,rw "$RESCUE_ROOT"
sudo chown "$TARGET_UID:$TARGET_GID" "$RESCUE_ROOT/home/$TARGET_USER"
sudo chmod go-w "$RESCUE_ROOT/home/$TARGET_USER"
sudo chown "$TARGET_UID:$TARGET_GID"
"$RESCUE_ROOT/home/$TARGET_USER/.ssh"
"$RESCUE_ROOT/home/$TARGET_USER/.ssh/authorized_keys"
sudo chmod 700 "$RESCUE_ROOT/home/$TARGET_USER/.ssh"
sudo chmod 600 "$RESCUE_ROOT/home/$TARGET_USER/.ssh/authorized_keys"
sync
sudo mount -o remount,ro "$RESCUE_ROOT"
変更後の数値所有者、モード、指紋、マウント状態を確認します。正常にアンマウントし、補助インスタンスからデタッチして、メンテナンス前に記録した元のブロックデバイスマッピングで元のインスタンスへ再アタッチします。起動前にボリューム状態とアタッチ先を確認します。ステータスチェック、ホスト指紋、SSH ログイン、アプリケーション正常性、監視がすべて通るまでスナップショットとメタデータ記録を保持します。ロールバックは同じ変更管理の下で再停止し、既知の正常なボリューム/スナップショットを復元することです。
停止してエスカレーションする条件
- エラーの分岐が変わった、ホスト指紋を独立して検証できない、想定する秘密鍵/公開鍵の指紋が一致しない;
- EBS-backed でない、instance-store データに危険がある、対象/ルートデバイスが曖昧;
- 承認済み KMS 権限で暗号化ボリュームをアタッチできない;
- ファイルシステム破損が疑われる、ルートが予期せずマウントされた、承認済みアカウントパス以外へ書き込みが及ぶ;
- 管理ポリシー、集中 ID、構成管理、Auto Scaling が修復を上書きする。
公式資料
- AWS:EC2 Linux 接続エラーのトラブルシューティング
- AWS:一般的な接続前提条件とインスタンスのホスト指紋
- AWS:EC2 キーペア指紋の検証
- AWS:EC2 Instance Connect の前提条件
- AWS:EC2 Instance Connect で接続
- AWS:Systems Manager Session Manager で接続
- AWS:EC2 Serial Console アクセスの設定
- AWS:`AWSSupport-TroubleshootSSH`
- AWS:EC2 インスタンスの停止と起動
- AWS:EBS ボリュームのアタッチとデタッチ
- AWS:EBS ボリュームと NVMe デバイス名の対応
- AWS:EBS 暗号化と KMS の動作
- OpenSSH:`sshd` の許可鍵所有者とモード
- Ubuntu Server:OpenSSH サーバーと鍵認証
2017 年の原文資料(現行手順ではありません)
以下に source_export の可視本文を完全に保持し、行末空白だけを正規化しています。危険な再帰的権限変更コマンド一つだけを [REDACTED: unsafe recursive chmod command] に限定置換し、他の文言やコマンドは変更していません。この資料には推測されたデバイス名と広すぎる権限助言があり、現行手順として使用できません。
N.B. There are dozens of reasons to lead to this problem, for example, wrong permission of your pem file, incorrect username(e.g., ec2-user, ubuntu),wrong spelling in your command, etc..
The reason which causes my problem, if I am right, is that I run command `[REDACTED: unsafe recursive chmod command]` under the wrong directory, namely, my home folder.
The solution is just setting your home folder permissions back.
1. Stop your problematic instance.
2. Create a new instance and stop the new problem-free instance.
3. The newly created instance should be in the same `Availability Zone` like ‘us-west-2c’ which can be set on the ‘Network’ step under which the menu is ‘Subnet’.
4. Detach your ‘ebs volume’ from the problematic instances and attach it on your new problem-free instance.
5. Your need input your instance id as well as the mount point which looks like ‘/dev/sda2’.
6. Start your new instance and mount the second drive that you just attached.
[ubuntu ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvdf 202:80 0 100G 0 disk
xvda1 202:1 0 8G 0 disk /
[ubuntu ~]$ sudo mount /dev/xvdf/ /mnt
8. Change directory to your mounted point and restore the permission of your home directory with permission 755.
[ubuntu ~]$ cd /mnt/home/
[ubuntu ~]$ chmod 755 yourusername
9. Stop your new instance and detach the volume owned by the problematic instance.
10. Reattach the just detached volume to the default problematic instance.
