AWS 開発者ブログ

無詠唱魔術の正体(AWS EC2、CloudShell)

「亜弩民悪世須!!し、信じられん 最上位階魔法の詠唱がされてしまうなんて あの伝説が本当だっとは・・・!!」

「知っているのか雷電・・・!?」

無詠唱魔術

封印鍵・秘匿呪符を唱えることなく、電光雲海の門を開くことを言う。
黎明期、亜弩民悪世須(最上位階術式)のような強力な魔術を詠唱するものは多く存在したが、現在は禁術扱いとされ、無詠唱で電光雲海に接触するする近代魔術体系が確立されるに至る。

菊大書房「厨二風魔術異聞」より

男塾のネタが好きなWebアプリケーションエンジニアの菊池です。

クレデンシャルキーを設定しなくても動く「IAMロールアタッチしたEC2インスタンス」と「CloudShell」の仕組みを見てみたいと思います。

結論をいうと、どちらもIAMロールに基づいた一時的な認証キーが動的に発行されAWSサービスにアクセスできるようになっています。

では、順番に見ていきましょう。

EC2

AWS CLIの debug 実行が分かりやすいので、そのログを見ていきます。
以下は、AmazonS3FullAccessが含まれるIAMロール(TestEC2Role)がアタッチされているEC2インスタンスでaws s3 ls --debug を実行したログです。
(ログ行頭の日時は省略しています)

$ aws s3 ls --debug
.
.
.
botocore.utils - DEBUG - IMDS ENDPOINT: http://169.254.169.254/
urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): 169.254.169.254:80
urllib3.connectionpool - DEBUG - http://169.254.169.254:80 "PUT /latest/api/token HTTP/1.1" 200 56
urllib3.connectionpool - DEBUG - Resetting dropped connection: 169.254.169.254
urllib3.connectionpool - DEBUG - http://169.254.169.254:80 "GET /latest/meta-data/placement/availability-zone/ HTTP/1.1" 200 15
botocore.credentials - DEBUG - Looking for credentials via: env
botocore.credentials - DEBUG - Looking for credentials via: assume-role
botocore.credentials - DEBUG - Looking for credentials via: assume-role-with-web-identity
botocore.credentials - DEBUG - Looking for credentials via: sso
botocore.credentials - DEBUG - Looking for credentials via: shared-credentials-file
botocore.credentials - DEBUG - Looking for credentials via: custom-process
botocore.credentials - DEBUG - Looking for credentials via: config-file
botocore.credentials - DEBUG - Looking for credentials via: ec2-credentials-file
botocore.credentials - DEBUG - Looking for credentials via: boto-config
botocore.credentials - DEBUG - Looking for credentials via: container-role
botocore.credentials - DEBUG - Looking for credentials via: iam-role
urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): 169.254.169.254:80
urllib3.connectionpool - DEBUG - http://169.254.169.254:80 "PUT /latest/api/token HTTP/1.1" 200 56
urllib3.connectionpool - DEBUG - Resetting dropped connection: 169.254.169.254
urllib3.connectionpool - DEBUG - http://169.254.169.254:80 "GET /latest/meta-data/iam/security-credentials/ HTTP/1.1" 200 11
urllib3.connectionpool - DEBUG - Resetting dropped connection: 169.254.169.254
urllib3.connectionpool - DEBUG - http://169.254.169.254:80 "GET /latest/meta-data/iam/security-credentials/TestEC2Role HTTP/1.1" 200 1606
botocore.credentials - DEBUG - Found credentials from IAM Role: TestEC2Role
.
.
.

赤マーカーのログに注目です。
赤マーカーと同じAPIをaws s3 ls --debug実行したEC2インスタンスでアクセスしてみましょう。
(curl コマンドでヘッダーオプションを付けていますが、IMDSv2に基づいたヘッダーを送信しています)

$ curl \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 600" \
  -X PUT "http://169.254.169.254/latest/api/token"
AQAEAN5r5HZbc8o7YVnlOprGHbwXxVlJZ0d65J1YEf8n2gelKOziSQ==

$ curl \
  -H "X-aws-ec2-metadata-token: AQAEAN5r5HZbc8o7YVnlOprGHbwXxVlJZ0d65J1YEf8n2gelKOziSQ==" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials
TestEC2Role

$ curl \
  -H "X-aws-ec2-metadata-token: AQAEAN5r5HZbc8o7YVnlOprGHbwXxVlJZ0d65J1YEf8n2gelKOziSQ==" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 600" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/TestEC2Role
{
  "Code" : "Success",
  "LastUpdated" : "2024-10-23T06:38:05Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIA...",
  "SecretAccessKey" : "7S2x...",
  "Token" : "IQoJb3JpZ2luX2VjEE4aDmFwLW5vcnRoZWFzd...",
  "Expiration" : "2024-10-23T13:07:43Z"
}

赤マーカーはレスポンスです。
なんと、クレデンシャルキーが取得できました!
もちろんこのクレデンシャルキーは、ローカルに環境変数などで設定することでS3アクセスが可能です。

AWSドキュメントでも /latest/meta-data/iam/security-credentialsからクレデンシャルを取得する方法が記載されています。

インスタンスメタデータからのセキュリティ認証情報の取得 - Amazon Elastic Compute Cloud

AWSドキュメントより

黄色マーカーのログについて

ここは認証の優先順になっていて、もし、EC2インスタンス上で環境変数にクレデンシャルキーを設定した場合、環境変数のクレデンシャルキーが優先され、EC2インスタンスにアタッチしたロールではないロール権限で実行できます。

認証とアクセス認証情報 - AWS Command Line Interface

参考AWSドキュメント

IMDSv2とは

IMDSv2は、AWSのEC2インスタンスメタデータサービスにアクセスするための強化されたセキュリティ機能を提供するバージョンで、特にセキュリティリスクを軽減するためのトークンベースのセッションを採用しています。これにより、IAMロールの認証情報などのメタデータアクセスがより安全になっています。

マネジメントコーンソールのインスタンス概要でも確認できます。

インスタンスメタデータサービスを使用してインスタンスメタデータにアクセスする - Amazon Elastic Compute Cloud

参考AWSドキュメント

もう少しこのメタ情報について確認します。

$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    56  100    56    0     0  33959      0 --:--:-- --:--:-- --:--:-- 56000
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hibernation/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/

ファイル、ディレクトリ構造のようなリストが表示されます。

これはクレデンシャルに限らないメタ情報がこれらから取得できることを意味しています。

インスタンスメタデータサービスを使用してインスタンスメタデータにアクセスする - Amazon Elastic Compute Cloud

AWSドキュメントより

では、次に参りましょう。

CloudShell

CloudShellでも aws s3 ls --debug を実行します。

$ aws s3 ls --debug
.
.
.
urllib3.connectionpool - DEBUG - http://localhost:1338 "GET /latest/meta-data/container/security-credentials HTTP/1.1" 200 1400
botocore.credentials - DEBUG - Retrieved credentials will expire at: 2024-10-22 09:32:02+00:00
botocore.auth - DEBUG - Calculating signature using v4 auth.
.
.
.

かなりログ省略していますが、ポイントはこのログです。
CloudShell上でこのAPIにアクセスしてみましょう。

$ curl -H "Authorization: $AWS_CONTAINER_AUTHORIZATION_TOKEN" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 600" \
  localhost:1338/latest/meta-data/container/security-credentials
{
        "Type": "",
        "AccessKeyId": "ASIA...",
        "SecretAccessKey": "HyKE...",
        "Token": "IQoJb3JpZ...",
        "Expiration": "2024-10-23T12:30:35Z",
        "Code": "Success"
}

クレデンシャルキーが取得できました!

EC2インスタンスのときと同様、このクレデンシャル情報は10分程度の期限付きで利用できるものになります。

まとめ

AWSにアクセスするには何かしら「IAMロールに基づいた一時的な認証キーを動的に発行して認証」をしていることが把握できたと思います。
これであなたも無詠唱を恐れることなく使いこなすことでしょう。


Recruit

ディーメイクでは各ポジションで一緒に働く仲間を募集中! エンジニア、デザイナー、ディレクターなど、多彩な職種があります。
一緒に成長していきましょう!

最新記事

おすすめ記事リンク

-AWS, 開発者ブログ