先日、AWS EC2 Windowsを扱っている際に、思わぬ問題に直面しました。
Windows EC2インスタンスから暗号化されたAmazon Machine Image(AMI)を作成したのですが、その暗号化AMIから起動したインスタンスのAdministratorパスワードが取得できないという壁にぶつかりました。
暗号化していないAMIではこうした事態は起きなかったため、これは想定外でした。最終的には、リカバリー用のEC2インスタンスからパスワードをリセットすることで解決できました。
本記事では、この問題をどのように解決したのか、その手順をご紹介します。
暗号化インスタンスの作成
先日、AWS上で扱っていたWindowsインスタンスをセキュアにする必要が生じました。そこで選んだのが、インスタンスから暗号化されたAmazon Machine Image(AMI)を作成する方法です。
まずWindowsインスタンスのAMIを作成しました。AMIを暗号化するため、コピー時に暗号化設定を適用しました。


暗号化したAMIから新しいWindowsインスタンスを起動しました。

インスタンスがRunning状態になり、両方のステータスチェックが通るのを待ってから接続を試みました。

EC2 Windowsへの接続
WindowsのAdministratorパスワードを取得しようとしましたが、できませんでした。エラーメッセージから、原因はカスタムAMIにあると判明しました。

EC2の get-password-data コマンドで暗号化されたパスワードデータの取得を試みたところ、PasswordDataフィールドは空でした。AWSのドキュメントによれば、パスワードの生成と暗号化には数分かかることがあり、利用可能になる前に取得しようとすると、出力は空文字列になるとのことです。
aws ec2 get-password-data --instance-id i-0ece1184ee316f9f2
--priv-launch-key ~/.ssh/windows.pem --region eu-west-1 --profile ciara
{
"InstanceId": "i-0ece1184ee316f9f2",
"PasswordData": "",
"Timestamp": "2023-11-02T17:34:27+00:00"
}
しかし、しばらく待ってもこのインスタンスにはAdministratorパスワードが含まれていないことが明らかになりました。

なぜパスワードが存在しないのか?
Windowsインスタンスを起動すると、Administratorアカウント用に一意のパスワードが生成されます。このパスワードはインスタンス起動時に指定したキーペアで暗号化されており、復号には対応するキーペアファイルが必要です。
インスタンスからAMIを作成すると、EBSボリューム上のデータは新しいEBSスナップショットに保存されます。ただし、Administratorアカウントのパスワードはこれらのスナップショットに含まれません。各インスタンスが固有のパスワードを持つようにするためのセキュリティ上の仕様です。
EC2Configサービス、または EC2Launch スクリプト(Windows Server 2016以降が対象)が、起動時にWindowsのパスワードを生成します。これはインスタンスの初回起動時にのみ実行されます。
再バンドルされたAMIでパスワードが生成されない場合、それを取得することはできません。AMIをバンドルする前にEC2SetPasswordが有効化されていなかった場合に、こうした状況が発生します。
そのため、私の暗号化インスタンスではAdministratorパスワードを取得できなかったわけです。
AWSのドキュメントには次のように記載されています。
パスワード生成が無効化されており、元のインスタンスのパスワードを覚えていない場合は、このインスタンスのパスワードをリセットできます。
パスワードのリセット
パスワードをリセットするには、Windowsインスタンスからルートボリュームをデタッチし、一時インスタンスにセカンダリボリュームとしてアタッチする必要があります。
以降、パスワードリセットの対象インスタンスを Broken Instance、一時インスタンスを Recovery Instance と呼びます。
注意:この2つのインスタンスは同一のアベイラビリティゾーンに存在する必要があります。
- Broken Instanceを選択し、Actions、Instance state、Stop instance の順に選びます。ステータスが Stopped に変わったら、次のステップへ進みます。
- Broken Instanceのルートボリュームのデバイスマッピング(/dev/sda1)を控えておきます。
- Broken Instanceからルートボリュームをデタッチします。Actions、Detach Volume を選択します。ボリュームのステータスが available に変わったら、次のステップへ進みます。
- Broken Instanceと同じAZに一時インスタンスを起動します。
- Launch an instance ページのNetwork settingsで、Broken Instanceが配置されているサブネットを選択します。

- Configure storage で Advanced を選択します。

- Encrypted フィールドで「Not encrypted」を「Encrypted」に変更します。
- ボリュームを暗号化するKMSキーを選択します。

- AdvancedでIAMインスタンスプロファイルをアタッチします。インスタンスプロファイルに必要なKMS権限が付与されているか確認してください。

インスタンスプロファイルには IAM ロールが含まれます。インスタンスはこのロールの権限を使って、アタッチされた暗号化ボリュームにアクセスします。
5. Recovery InstanceがRunning状態になり、両方のステータスチェックが通るまで待ちます。

6. ナビゲーションペインで Volumes を選び、Broken Instanceからデタッチしたボリュームを選択して、Actions、Attach Volume の順に選択します。

- Attach Volume ダイアログの Instances 一覧から、Recovery Instanceを選択します。
- Device には(未入力の場合)
xvdfと入力し、Attach を選択します。
**Administratorパスワードのリセット**
RDPでRecovery Instanceに接続します。
ブラウザを開き、以下のリンクからEC2Rescue for Windows Serverツールをダウンロードします。
https://s3.amazonaws.com/ec2rescue/windows/EC2Rescue\_latest.zip
ZIPを展開し、EC2Rescue.exe を実行します。

- ライセンス契約を読み、I Agree ボタンをクリックして条項に同意します。
Welcome to EC2Rescue 画面で Next を選択します。

Select mode 画面で Offline instance を選択します。

Select a disk 画面で xvdf デバイスを選び、Next を選択します。


「The media is write protected」というエラーが表示された場合は、ディスク側でこの設定を解除する必要があります。

このエラーは、Windowsがディスクへの変更をブロックしていることを意味します。Diskpartユーティリティを使ってディスクの読み取り専用属性を解除します。手順は次の通りです。
- コマンドプロンプトを管理者として開きます。
diskpartと入力してEnterキーを押します。list diskと入力してEnterキーを押します。システム上のすべてのディスクが一覧表示されます。select disk Xと入力します(Xは対象ディスクの番号に置き換えてください)。Enterキーを押します。attributes disk clear readonlyと入力してEnterキーを押します。これでディスクの読み取り専用属性が解除されます。


ボリュームの読み込みが完了したら OK を選択します。
Select Offline Instance Option 画面で Diagnose and Rescue を選び、Summary 画面で内容を確認して Next を選択します。

Detected possible issues 画面で Reset Administrator Password を選び、Next を選択します。

Confirm 画面で Rescue、OK の順に選択します。


Done 画面で Finish を選択します。

EC2 Rescueログを確認し、エラーや警告メッセージが出ていないことをチェックします。

EC2Rescue for Windows Serverツールを閉じ、一時インスタンスとの接続を切断して、Amazon EC2コンソールに戻ります。
インスタンスの再起動
Recovery Instanceからセカンダリ(xvdf)ボリュームをデタッチし、元のインスタンスにルートボリューム(/dev/sda1)として再アタッチします。

接続前に、インスタンスがRunning状態でステータスチェックが通っていることを確認します。

これでAdministratorパスワードを取得し、暗号化インスタンスにRDPで接続できるようになりました。EC2の get-password-data コマンドからも同じパスワードを取得できます。

使い終わったRecovery Instanceや、その他不要なインスタンスは必ず終了し、忘れずにクリーンアップしてください。