EC2インスタンスのメタデータ（IMDSv2）をPowerShellで一括出力してみる

以前、[EC2インスタンスのメタデータ（IMDSv1）をPowerShellで一括出力してみる](https://qiita.com/SAITO_Keita/items/bbfae778f9d075d01da5)の記事にて、`IMDCSv1`からメタデータを一括出力する方法を紹介しました。

本記事では、`IMDSv2`で同様にメタデータを一括出力する方法を説明します。

## そもそもIMDSv2って？

[IMDSv2 の使用](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)

`IMDS`は`Instance Metadata Service`の略称となり。
EC2インスタンスのメタデータサービスを取り扱うサービスとなり、このv2が`IMDSv2`となります。

`IMDSv2`が出てきた経緯については、下記AWSブログに記載があります。

[Add defense in depth against open firewalls, reverse proxies, and SSRF vulnerabilities with enhancements to the EC2 Instance Metadata Service](https://aws.amazon.com/jp/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/)

AWSジャパンのブログにも日本語訳での投稿があります。

[EC2 インスタンスメタデータサービスの拡張により、オープンなファイアウォール、リバースプロキシ、SSRFの脆弱性に対する防御を強化しました](https://aws.amazon.com/jp/blogs/news/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/)

ざっくりまとめると`IMDSv1`については引き続きセキュアではありますが、それに比べて更に4種類の脆弱性に対して新しい保護を追加したのが`IMDSv2`のようです。

## 環境の準備

EC2インスタンスについて、`IMDS`に関するパラメータを指定してないで構築すると2023年2月現在。
`IMDSv1`と`IMDSv2`に両方アクセスできる状態で構築されます。

今回は折角なので、`IMDSv2`だけ有効にしたWindows Serverで動作確認してみます。

対象のEC2インスタンスがどのバージョンの`IMDS`が実行できるか確認するには、現在の所マネジメントコンソールでは確認するすべはなく、`aws-cli`の`describe-instances`コマンドで確認するしかないようです。

[describe-instances](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/describe-instances.html#output)

outputの`HttpTokens`の所に下記のように記述があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/ef349848-9910-aa4d-cd00-852365ba45c6.png)

なお下記`aws-cli`を実行すると`InstanceId`と`HttpTokens`の一覧を取得できます。

```bash
aws ec2 describe-instances --query "Reservations[].Instances[].{InstanceId:InstanceId,HttpTokens:MetadataOptions.HttpTokens}"
```

今回、下記のように`HttpTokens`が`required`となるインスタンスを構築してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/6d19b25e-098d-90d3-0476-042bfde40e89.png)

## IMDSv2しか許可されていない環境でIMDSv1にアクセスするとどうなるか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/54b7f6c6-a2aa-9fe0-63f8-f0fc6178b2b9.png)

許可されていませんとエラーになりました。

## 実行環境

- WindowsServer 2019 1809
- PowerShell 5.1.17763.1490

## IMDSv2を一括出力してみる

```PowerShell
function expand-awsmeta([string]$base , [string]$leaf , $tokenHeader ) {
    if ($leaf.EndsWith("/")) {
   (Invoke-RestMethod "$base$leaf" -Headers $tokenHeader ) -split "`n" | ForEach-Object { expand-awsmeta "$base$leaf" $_ $tokenHeader}
    }
    else {
        try {
            $value = Invoke-RestMethod "$base$leaf" -Headers $tokenHeader
            Select-Object @{n = 'uri'; e = { "$base$leaf" } }, @{n = 'value'; e = { $value } } -InputObject ""
        }
        catch {
            # public-keysだけ
            # 169.254.169.254/latest/meta-data/public-keys/0/openssh-key といった形なので妥協
            Select-Object @{n = 'uri'; e = { "$base" } }, @{n = 'value'; e = { $leaf } } -InputObject ""
        }
    }
}

$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 }


expand-awsmeta "169.254.169.254/latest/" "meta-data/" $tokenHeader
expand-awsmeta "169.254.169.254/latest/" "dynamic/" $tokenHeader
```

`IMDSv2`と特に代わり映えなく一括出力されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/cd54bee5-ebbe-2545-c85c-a76c71823039.png)

## 総評

`IMDSv2`のPowerShellでメタデータを一括取得する際の参考になれば幸いです。