0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IMDSv2 で SSM が繋がらないときの確認と対策

0
Posted at

背景・目的

プライベートサブネット上の EC2(Amazon Linux 2)で、IMDSv2(HttpTokens: required)の状態で SSM Session Manager に接続できない事象が発生しました。

本記事では、この事象を再現し、原因を特定して解決するまでの流れをまとめます。

まとめ

項目 内容
事象 古い AMI の EC2 で IMDSv2 にすると Session Manager に接続できない
原因 AMI にプリインストールされた SSM Agent が IMDSv2 に非対応(2019年6月の AMI < IMDSv2 リリース 2019年11月)
対策 最新の Amazon Linux 2 AMI を使用する(UserData での更新は鶏と卵の問題で不可)

概要

IMDS とは

Instance Metadata Service(IMDS)は、EC2 インスタンスが自身のメタデータや IAM ロールの一時認証情報を取得するためのサービスです。169.254.169.254 にアクセスして利用します。

IMDSv1 IMDSv2
方式 GET リクエストのみ PUT でトークン取得 → GET にトークン付与
セキュリティ SSRF 攻撃に脆弱 トークンベースで SSRF 対策
AWS 推奨 非推奨 推奨

SSM Agent と IMDS の関係

SSM Agent は IMDS から以下を取得します:

  • インスタンス ID(自身の識別)
  • IAM ロールの一時認証情報(AWS API 呼び出し用)

これらが取得できないと、SSM Agent は AWS Systems Manager に登録できず、Session Manager も Run Command も動作しません。

実践

事前準備

前回の記事で構築した検証環境(Ec2VpcInternalStack)に、古い固定 AMI(ami-XXXXXXXXXXXXX)のインスタンスを追加しました。

  • VPC: インターネット疎通なし(IGW/NAT なし)
  • VPC Endpoints: ssm, ssmmessages, ec2messages, s3
  • EC2: Amazon Linux 2(固定 AMI), t3.micro, IMDSv2(required)
  • IAM ロール: AmazonSSMManagedInstanceCore

Phase 1: 事象の確認

1-1. SSM 接続を試行

EC2 コンソールから Session Manager で接続を試みます。

  • Ping status: オフライン
  • Session Manager connection status: Not connected
  • Agent version: (表示なし)

→ SSM Agent が Systems Manager に登録できていない状態です。

image.png

1-2. IMDS 設定を確認

aws ec2 describe-instances --instance-ids i-XXXXXXXXXXXX \
  --query "Reservations[0].Instances[0].MetadataOptions" \
  --region ap-northeast-1
{
  "HttpTokens": "required",
  "HttpPutResponseHopLimit": 2,
  "HttpEndpoint": "enabled"
}

IMDSv2(HttpTokens: required)になっています。

Phase 2: 切り分け

2-1. 最新 AMI のインスタンスとの比較

同じ VPC・同じ IAM ロール・同じ IMDSv2 設定で、最新 AMI(latestAmazonLinux2)のインスタンスは Session Manager で接続できています。

古い固定 AMI 最新 AMI
AMI ami-XXXXXXXXXXXXX 最新の Amazon Linux 2
IMDSv2 required required
VPC / Endpoints 同じ 同じ
IAM ロール 同じ 同じ
SSM 接続 ❌ オフライン ✅ 接続可能

AMI の違い(= プリインストールされた SSM Agent のバージョン)が原因と推測。

2-2. IMDSv1 への変更を試みる

念のため IMDSv1 に戻して切り分けを試みます。

aws ec2 modify-instance-metadata-options \
  --instance-id i-XXXXXXXXXXXX \
  --http-tokens optional \
  --region ap-northeast-1
An error occurred (UnsupportedOperation): You can't set httpTokens to 'optional'
because httpTokensEnforced is enabled for this account.

→ アカウントレベルで IMDSv2 が強制されているため、IMDSv1 に戻すことはできません。

Phase 3: 原因の調査

3-1. AMI の情報を確認

SSM で接続できないため、AMI のリリース日から SSM Agent のバージョンを推測します。

aws ec2 describe-images --image-ids ami-XXXXXXXXXXXXX \
  --query "Images[0].{Name:Name,CreationDate:CreationDate,Description:Description}" \
  --region ap-northeast-1
{
  "Name": "amzn2-ami-hvm-2.0.20190618-x86_64-gp2",
  "CreationDate": "2019-06-19T21:59:16.000Z",
  "Description": "Amazon Linux 2 AMI 2.0.20190618 x86_64 HVM gp2"
}

2019年6月 の AMI です。

3-2. 原因の特定

IMDSv2 は 2019年11月 にリリースされました。この AMI は 2019年6月のため、プリインストールされた SSM Agent は IMDSv2 リリースより前のバージョンであり、IMDSv2 に対応していません。

古い固定 AMI 最新 AMI
AMI リリース日 2019年6月(IMDSv2 リリース前) 最新(IMDSv2 対応済み)
IMDSv2 環境での動作 ❌ 認証情報取得不可 ✅ 正常動作

結論: AMI にプリインストールされた SSM Agent が IMDSv2 に非対応のため、トークンベースのメタデータ取得ができず、IAM ロールの認証情報を取得できず SSM に登録できない。

Phase 4: 対策の実施(SSM Agent の更新)

4-1. UserData で SSM Agent を更新する(失敗)

CDK を修正し、UserData で最新の SSM Agent をインストールするようにします。

yum install -y https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm
systemctl enable amazon-ssm-agent
systemctl restart amazon-ssm-agent
  1. UserData は初回起動時のみ動作するため、既存の EC2 を terminate します
  2. CDK を再デプロイします
  3. 接続できません

image.png

UserData 実行時に yum install が S3 からパッケージを取得するには IAM 認証情報が必要です。その認証情報は IMDS から取得しますが、古い AWS CLI(AMI にプリインストールされたもの)が IMDSv2 に対応していないため、認証情報が取れず S3 アクセスが失敗します。

鶏と卵の問題: SSM Agent を更新するために S3 にアクセスしたいが、S3 にアクセスするための認証情報を取得するには IMDSv2 対応が必要。

Phase 5: 動作確認

CDK の AMI を最新の Amazon Linux 2 に変更してデプロイします。

  1. Session Manager で接続できることを確認します

  2. SSM Agent のバージョンを確認します

sh-4.2$ amazon-ssm-agent --version
SSM Agent version: 3.3.4108.0
  1. IMDSv2 でメタデータが取得できることを確認します
sh-4.2$ TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
sh-4.2$ curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id
i-XXXXXXXXXXX

→ 最新 AMI であれば IMDSv2 環境でも SSM Agent が正常に動作し、Session Manager で接続できることを確認しました。

考察

なぜ古い AMI で問題が起きるのか

IMDSv2 はセキュリティ強化のためにトークンベースの認証を導入しました。しかし、IMDSv2 リリース前の SSM Agent は GET リクエストのみでメタデータを取得する設計のため、トークン取得(PUT リクエスト)ができず認証情報を取得できません。

UserData での更新が不可能な理由

通常、古いソフトウェアは UserData で更新できますが、今回は以下の循環依存が発生します:

SSM Agent を更新したい
  → S3 からパッケージを取得する必要がある
    → S3 アクセスには IAM 認証情報が必要
      → IAM 認証情報は IMDS から取得する
        → IMDS は IMDSv2(トークンベース)
          → 古い AWS CLI/yum は IMDSv2 に非対応
            → 認証情報が取れない → S3 アクセス失敗

教訓

  • AMI は定期的に更新する: 古い AMI を固定で使い続けると、アカウントレベルのセキュリティ強化(IMDSv2 強制等)に追従できなくなる
  • AMI ID のハードコードを避ける: SSM Parameter Store の最新 AMI パスや CDK の latestAmazonLinux2() を使うことで、常に最新の AMI を参照できる
  • IMDSv2 強制前にテストする: アカウントレベルで IMDSv2 を強制する前に、既存インスタンスの SSM Agent バージョンを確認すべき

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?