Amazon Lightsail でインスタンスメタデータオプションが制御出来るようになりました

2022.09.27

いわさです。

EC2 にはインスタンスメタデータサービス (IMDS) というものがあります。

こちらの機能は Lightsail でも利用することが出来ます。

上記記事でも紹介されているように IMDS には V1 と V2 があります。(この記事では IMDSv1, IMDSv2 と表記します)
Lightsail で IMDSv2 がいつから利用出来るようになったのか履歴が確認出来ていないのですが、本日時点で利用可能になっています。
また、IMDSv1 については数年前に利用しているブログ記事がいくつかあります。

これまで、EC2 では IMDSv2 の強制化やエンドポイントの無効化などを行うことが出来ましたが、Lightsail でも出来るようになりました。

デフォルト状態を確認する

まずは制御しない状態がどのようになっているのかを確認してみます。
Lightsail で適当なブループリントでインスタンスを作成します。

作成後にaws lightsail get-instanceでインスタンス情報を取得してみましょう。

AWS CLI では v1.25.81 以降から利用出来ます。本日時点で v2 はまだ利用出来ませんでした。

% aws-v1 lightsail get-instance --instance-name WordPress-1 --profile hoge
{
:
        "username": "bitnami",
        "sshKeyName": "LightsailDefaultKeyPair",
        "metadataOptions": {
            "state": "applied",
            "httpTokens": "optional",
            "httpEndpoint": "enabled",
            "httpPutResponseHopLimit": 1,
            "httpProtocolIpv6": "disabled"
        }
    }
}

このようにmetadataOptionsという新しい情報が取得出来るようになっています。
トークンの任意・必須、エンドポイントの有効無効など設定可能な項目は EC2 と同じ感じですね。

デフォルトではトークンは任意(つまり IMDSv1 でも IMDSv2 でもアクセス出来る)でエンドポイントは有効な状態です。
インスタンスへ SSH リモート接続し確認してみます。

IMDSv1

Linux ip-172-26-3-160 4.19.0-20-cloud-amd64 #1 SMP Debian 4.19.235-1 (2022-03-17) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
       ___ _ _                   _
      | _ |_) |_ _ _  __ _ _ __ (_)
      | _ \ |  _| ' \/ _` | '  \| |
      |___/_|\__|_|_|\__,_|_|_|_|_|

  *** Welcome to the WordPress packaged by Bitnami 5.9.3-8         ***
  *** Documentation:  https://docs.bitnami.com/aws/apps/wordpress/ ***
  ***                 https://docs.bitnami.com/aws/                ***
  *** Bitnami Forums: https://community.bitnami.com/               ***
bitnami@ip-172-26-3-160:~$ curl http://169.254.169.254/latest/meta-data/placement/availability-zone
ap-northeast-1a

トークンなしでインスタンスメタデータへアクセス出来ました。

IMDSv2

Linux ip-172-26-3-160 4.19.0-20-cloud-amd64 #1 SMP Debian 4.19.235-1 (2022-03-17) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
       ___ _ _                   _
      | _ |_) |_ _ _  __ _ _ __ (_)
      | _ \ |  _| ' \/ _` | '  \| |
      |___/_|\__|_|_|\__,_|_|_|_|_|

  *** Welcome to the WordPress packaged by Bitnami 5.9.3-8         ***
  *** Documentation:  https://docs.bitnami.com/aws/apps/wordpress/ ***
  ***                 https://docs.bitnami.com/aws/                ***
  *** Bitnami Forums: https://community.bitnami.com/               ***
Last login: Tue Sep 27 00:29:29 2022 from 54.240.200.8
bitnami@ip-172-26-3-160:~$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    56  100    56    0     0   8000      0 --:--:-- --:--:-- --:--:--  8000

bitnami@ip-172-26-3-160:~$ curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone
ap-northeast-1a

こちらはトークンありでもアクセス出来たことを確認したものになります。

IMDS Version 2 を強制する

インスタンスメタデータオプションを更新する API も提供されていますのでこちらを使って IMDSv2 を強制してみます。
以下のupdate-instance-metadata-optionsを使います。

% aws-v1 lightsail update-instance-metadata-options --instance-name WordPress-1 --http-token required --profile hoge
{
    "operation": {
        "id": "d2f5bfdc-7e78-4ef0-a055-670dcec3b946",
        "resourceName": "WordPress-1",
        "resourceType": "Instance",
        "createdAt": 1664240025.217,
        "location": {
            "availabilityZone": "ap-northeast-1a",
            "regionName": "ap-northeast-1"
        },
        "isTerminal": true,
        "operationDetails": "",
        "operationType": "UpdateInstanceMetadataOptions",
        "status": "Succeeded",
        "statusChangedAt": 1664240025.217
    }
}

更新に成功しました。
先程と同じく SSH でアクセスして動作を確認してみます。

IMDSv1

bitnami@ip-172-26-3-160:~$ curl http://169.254.169.254/latest/meta-data/placement/availability-zone
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>401 - Unauthorized</title>
 </head>
 <body>
  <h1>401 - Unauthorized</h1>
 </body>
</html>

おお、トークンなしでアクセスしてみたところ 401 となりました。
トークンありでも確認してみましょう。

IMDSv2

bitnami@ip-172-26-3-160:~$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    56  100    56    0     0   9333      0 --:--:-- --:--:-- --:--:--  9333
bitnami@ip-172-26-3-160:~$ curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone
ap-northeast-1a

トークンありの場合は成功しました。必須設定が有効になっていますね。
ちなみに、私が確認した際には設定変更にはインスタンスの再起動なども発生せず即時反映されていました。

エンドポイント無効化

エンドポイントの無効化も行ってみましょう。
169.254.169.254自体にアクセス出来なくする設定です。

% aws-v1 lightsail update-instance-metadata-options --instance-name WordPress-1 --http-endpoint disabled --profile hoge 
{
    "operation": {
        "id": "8cd7f05f-654d-4d42-bf3b-d41f8779c9ee",
        "resourceName": "WordPress-1",
        "resourceType": "Instance",
        "createdAt": 1664240382.211,
        "location": {
            "availabilityZone": "ap-northeast-1a",
            "regionName": "ap-northeast-1"
        },
        "isTerminal": true,
        "operationDetails": "",
        "operationType": "UpdateInstanceMetadataOptions",
        "status": "Succeeded",
        "statusChangedAt": 1664240382.211
    }
}

IMDSv2

bitnami@ip-172-26-3-160:~$ curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>403 - Forbidden</title>
 </head>
 <body>
  <h1>403 - Forbidden</h1>
 </body>
</html>

トークンの取得に失敗しましたね。
401 ではなく 403 ステータスとなりました。

メトリクス

IMDSv2 を強制化する場合、IMDSv1 が利用されていないことを確認する必要があります。
IMDSv1 を前提としたツールやサードパーティエージェントなどをもし利用していた場合は動作しなくなってしまいます。

Lightsail コンソールのメトリクス画面ではトークンなしのメタデータアクセス状況をメトリクスで確認することが出来ます。
Lightsail ドキュメントでは IMDSv2 への移行にあたっては移行前にこのメトリクスで呼び出し数が​になっていることを確認することを推奨しています。

メトリクスタブのドロップダウンに「トークンメタデータリクエストなし」が追加されています。

こちらは直近の検証で IMDSv1 のリクエストを数回利用しているのでメトリクスとしてカウントされていることが確認出来ますね。

さいごに

本日は Amazon Lightsail でインスタンスメタデータオプションが制御出来るようになったので確認してみました。

セキュリティの観点で Lightsail に対しても IMDSv2 への移行を検討していた方はぜひ今回アップデートされた各種 API を使ってみてください。