SGでアウトバウンドを制限したEC2（Windows）でsysprep(EC2Launch)してAWSマネジメントコンソール上の管理者パスワードが更新されるか確認してみる

EC2Launchでsysprepをする場合、randomを選択する事でsysprep実行時に管理者パスワードがランダムに設定され、そのパスワードはAWSマネジメントコンソール上で確認する事ができます。

既存で動作している環境の複製環境を作成する場合。

実際に稼働している環境で直接sysprepを実行できない場合がほとんどかと思います

このため、一旦、他サーバーと疎通しない隔離環境を用意して、そこに一度イメージバックアップからデプロイしてsysprepを実行するかと思いますが。

その際にSGを制限した状態でもマネジメントコンソールのパスワードが更新できるのか気になったのでメモ

## 今回実行する環境

- Windows Server 2022

## SGのアウトバウンドを制限してsysprepを実行

下記画像のようなSGをインスタンスにアタッチしてsysprepを実行していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/b62b9b3c-69b5-0d80-9c87-187cd6fc33b1.png)

EC2launchからsysprepを実行します。（`C:\Program Files\Amazon\EC2Launch.exe`)

Set administrator accountのAdministrator password settingsをRandom(retrive from console)を選択してShutdown with Sysprepを実行していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/d2d3bc61-2ef7-5dff-b631-0851d74015df.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/bc1a4fef-b711-352b-6c37-82c9aebbf0a2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/55619dd2-c682-1f54-06da-9c0f5d28a171.png)

しばらく待つとEC2インスタンスが停止します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/49b60337-d283-d641-77ed-9cbbae8361ca.png)

通常のsysprep後のイメージ作成でしたら、こので対象EC2のAMIを作成しますが。
今回は、AWSマネジメントコンソール上のAdministratorパスワードが更新されるか確認したいだけなので、このままEC2インスタンスを起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/90c1924d-9e1b-3352-5d96-35ee0a50c324.png)

しばらく待つと、AWSマネジメントコンソール上のパスワードが更新されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/fb5c7c62-cea8-f5d3-707f-06e0c75087bf.png)

プライベートサブネットなどにWindowsサーバーを構築する際にもパスワードが更新されるので、SGのアウトバウンドを制限しても問題ない気はしていましたが。

こちらも問題ないようです。

## 管理者パスワードのマネジメントコンソールへの反映はリンクローカルアドレスを利用してる?

[リンクローカルアドレス](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-instance-addressing.html#link-local-addresses)

メタデータは上記ドキュメントにあるようにリンクローカルアドレスを利用してやりとりされており、こちらのリンクローカルアドレスはSGで制御できない範囲になります。

このためWindows管理者パスワードは多分こちらのアドレスを利用してやりとりしていそうです。

SGが制限された状態でも下記のようにメタデータにアクセスできる事が確認できます。

```powershell:IMDSv2で確認
# メタデータ（IMDSv2)にアクセスしてインスタンスタイプ表示
$headers = @{ "X-aws-ec2-metadata-token-ttl-seconds" = 21600 }
$token = Invoke-RestMethod http://169.254.169.254/latest/api/token -Method Put -Headers $headers
$tokenHeader = @{ "X-aws-ec2-metadata-token" = $token }
irm http://169.254.169.254/latest/meta-data/instance-type -Headers $tokenHeader
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/7705d0ac-14f9-511d-c40f-8de3fafa1014.png)

### リンクローカルアドレスへのルーティングを破壊してsysprepしてみる※この検証は失敗となりできませんでした。

マネジメントコンソール上のパスワード更新はリンクローカルアドレスを利用しているのでは？　といった仮説を立て、ここではWindowsのルートテーブルでリンクローカルアドレス向けのルーティングを破壊したのちにsysprepを実行してどうなるか確認してみましたが。　後述する理由によりこの検証は失敗しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/06af14b5-a638-0463-df9a-fb7f645dc557.png)

PowerShellの`Get-NetRoute`コマンドで確認すると、画像のようにルーティングが設定されています。

今回はこの部分を破壊していきます。(InterfaceIndexは適宜変更してください）

```powershell
Get-NetRoute -DestinationPrefix "169.254.169.*" | Remove-NetRoute

New-NetRoute -DestinationPrefix "169.254.169.254/32" -InterfaceIndex 5 -NextHop 203.0.113.0
New-NetRoute -DestinationPrefix "169.254.169.253/32" -InterfaceIndex 5 -NextHop 203.0.113.0
New-NetRoute -DestinationPrefix "169.254.169.251/32" -InterfaceIndex 5 -NextHop 203.0.113.0
New-NetRoute -DestinationPrefix "169.254.169.250/32" -InterfaceIndex 5 -NextHop 203.0.113.0
New-NetRoute -DestinationPrefix "169.254.169.249/32" -InterfaceIndex 5 -NextHop 203.0.113.0
New-NetRoute -DestinationPrefix "169.254.169.123/32" -InterfaceIndex 5 -NextHop 203.0.113.0

Get-NetRoute -DestinationPrefix "169.254.169.*"
```

今回はNextHopをドキュメント用のIPアドレスに変更していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/466c747f-e778-c9fc-4511-7994cda002da.png)

ルーティングを破壊して、メタデータにアクセスできなくなった事を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/84963dcd-56bd-2613-16d2-2fc3306520e7.png)

ここまで設定して、再起動するとEC2Launchの仕様で再起動をするとメタデータへのアクセスが復元される事に気がつきました……

試しにこの時点で通常の再起動を実施すると、破壊したルーティングが復旧されている事が確認できます。

EC2Launchのログを確認すると下記のようにルーティングが再作成されているのが確認できます。

`"C:\ProgramData\Amazon\EC2Launch\log\agent.log"`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/45ad7495-1690-3ada-9066-80cf3347ba61.png)

EC2Launchサービスが自動起動になっているため、こちらが起動時に動作して初期処理としてルーティングが復旧されてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/2650a3bd-b0ca-bb3f-1041-2fc2b2f9c890.png)

サービスを無効化してOS再起動してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/a50b0e2b-6bfe-ef6f-0181-0218f9cd307b.png)

メタデータへのルーティングが破壊されたまま起動する状態を確認できます。

### sysprepを実行しようとするが、結局の所失敗

EC2Launch v2環境でメタデータへのアクセスを破壊したままOSを起動するには、EC2Launch v2のサービスを自動起動から停止に変更する必要があるようです。

ただ、このサービスを停止した状態でEC2Launchが提供するsysprepの動作が正常に完了するか不明です。

このため、ルーティングを破壊しつつsysprepを実行してみるのは難しい気がします。

ちなみにEC2Launchサービスを停止した状態でsysprep(Adminitratorのパスワードはrandom)を実行した所、実行後、AWSマネジメントコンソールのパスワードは更新されずに新しいパスワードが入手できずにアクセスできなくなりました。

## 総評

SGのアウトバウンドを制限するとどうなるかといった疑問が湧いたため。

設定して試してみましたが、よくよく考えると普段プライベートサブネットなどにデプロイしているEC2インスタンスのパスワードも取得できているため。

検証する前にSGでは制限されないといった予想が立ちましたが、念のため確認してみました。

これだけだと記事として寂しいのでメタデータへのルーティングを破壊してsysprepしてみようかと思いましたが、EC2launch v2の仕様に阻まれてこれは失敗しました。