[LINUX] Instance Metadata Service Version 2 (IMDSv2): Setting and behavior check of Instance Metadata Service v2

Instance Metadata Service Version 2 (IMDSv2): Work memo for setting and behavior confirmation of Instance Metadata Service v2

Contents of this article

  1. What is Instance Metadata?
  2. Reasons to use Instance Metadata Service Version 2
  3. AWS-CLI execution environment preparation
  4. IMDSv2 forced configuration of existing instance
  5. Behavior check when IMDSv2 is forcibly set

1. What is Instance Metadata?

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

Instance metadata is data about an instance and is used to configure or manage a running instance. Instance metadata is divided into categories such as host name, event, and security group.

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html

You can access the instance metadata from a running instance using one of the following methods:

--Instance Metadata Service Version 1 (IMDSv1) – Request / Response Method --Instance Metadata Service Version 2 (IMDSv2) – Session-Oriented Methods

How Instance Metadata Service Version 2 Works

IMDSv2 uses session-oriented requests. Use session-oriented requests to create a session token that defines the session duration (1 second to 6 hours). You can use the same session token for subsequent requests during the specified time period. After the specified time period expires, you need to create a new session token to use for future requests.

2. Reasons to use Instance Metadata Service Version 2

On July 29, 2019, personal information of more than 100 million people was leaked due to unauthorized access at Capital One, a major US financial company.

Information on the Capital One Cyber Incident https://www.capitalone.com/facts2019/

The causes of information leakage are as follows

--An attacker accesses EC2 instance metadata via WAF and obtains IAM Role credentials (access to S3). --IMDSv1 does not authenticate to connect to metadata. --Using the acquired IAM Role authentication information, access S3 of Capital One and acquire the information.

On the other hand, IMDSv2 requires a Token obtained in advance to access the metadata. The usage of IMDSv2 and the advantages in terms of security are as follows.

How to use

--Create a 6 hour (21,600 second) session token using a PUT request --Store the session token header in a variable named TOKEN --Request top-level metadata items using tokens

merit

--Since most WAFs do not allow PUT requests, it is unlikely that external access via the WAF will succeed. --The hop limit of the metadata response can be shortened to prevent acquisition via multiple hosts. (If set to 1, you can prevent the acquisition of metadata via WAF as it occurred in Capital One) --PUT request is rejected if it contains an X-Forwarded-For header. (On proxy servers, usually add an X-Forwarded-For header)

3. AWS-CLI execution environment preparation

Prepare an instance (cli_instance) for AWS-CLI execution to issue an instance build / configuration change command

cli_instance environment(AWS-CLI publisher environmental information)


[root@ip-10-0-0-74 ~]# cat /etc/system-release
Amazon Linux release 2 (Karoo)
[root@ip-10-0-0-74 ~]# 
[root@ip-10-0-0-74 ~]# uname -a
Linux ip-10-0-0-74.ap-northeast-1.compute.internal 4.14.193-149.317.amzn2.x86_64 #1 SMP Thu Sep 3 19:04:44 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[root@ip-10-0-0-74 ~]# 
[root@ip-10-0-0-74 ~]# aws --version 
aws-cli/1.18.107 Python/2.7.18 Linux/4.14.193-149.317.amzn2.x86_64 botocore/1.17.31
[root@ip-10-0-0-74 ~]# 
[root@ip-10-0-0-74 ~]# curl http://169.254.169.254/latest/meta-data/instance-type/
t3.small
[root@ip-10-0-0-74 ~]# 

IMDSv2 operation confirmation instance "test_instance" construction

cli_instance environment(run-Instance execution)


[root@ip-10-0-0-74 ~]# aws ec2 run-instances \
> --image-id ami-0ce107ae7af2e92b5 \
> --instance-type t2.nano \
> --key-name key_file \
> --monitoring Enabled=false \
> --placement AvailabilityZone=ap-northeast-1a \
> --subnet-id subnet-03d74b8d6ab6c39f2 \
> --associate-public-ip-address \
> --security-group-ids sg-0a00ecb871bb15fb3 \
> --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=test_instance}]'

Constructed instance (test_instance) Check default instance metadata settings

cli_instance environment(describe-Instance execution)


[root@ip-10-0-0-74 ~]# aws ec2 describe-instances \
> --filters "Name=tag:Name,Values=test_instance" \
> --query Reservations[*].Instances[*].[MetadataOptions]
[
    [
        [
            {
                "State": "applied", 
                "HttpEndpoint": "enabled", 
                "HttpTokens": "optional", 
                "HttpPutResponseHopLimit": 1
            }
        ]
    ]
]
[root@ip-10-0-0-74 ~]# 

" HttpTokens ":" optional "-> IMDSv1 / IMDSv2 are both available " HttpTokens ":" required "-> IMDSv2 only available (IMDSv2 enforcement)

"HttpTokens": Behavior check in "optional" state (both IMDSv1 / IMDSv2 can be used)

The following is executed on the newly constructed" test_instance "environment

test_instance environment (IMDSv1 execution)


[root@ip-10-0-0-68 ~]# curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
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/
[root@ip-10-0-0-68 ~]# 

test_instance environment (IMDSv2 execution)


[root@ip-10-0-0-68 ~]# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v 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   9333      0 --:--:-- --:--:-- --:--:-- 11200
*   Trying 169.254.169.254...
* TCP_NODELAY set
* Connected to 169.254.169.254 (169.254.169.254) port 80 (#0)
> GET /latest/meta-data/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/7.61.1
> Accept: */*
> X-aws-ec2-metadata-token: AQAAAO6n081baEIWdrfpILhc9Egt4kTm0HSpUftcYqvJSR-NKewL6A==
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Accept-Ranges: bytes
< Content-Length: 313
< Content-Type: text/plain
< Date: Sat, 26 Sep 2020 14:45:29 GMT
< Last-Modified: Sat, 26 Sep 2020 14:28:58 GMT
< X-Aws-Ec2-Metadata-Token-Ttl-Seconds: 21600
< Connection: close
< Server: EC2ws
< 
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
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
* Closing connection 0
services/
[root@ip-10-0-0-68 ~]#

4. Forced IMDSv2 configuration for existing instances

The following is executed on the AWS-CLI execution environment" cli_instance "environment

cli_instance environment


[root@ip-10-0-0-74 ~]# # test_Get instance ID of instance
[root@ip-10-0-0-74 ~]# aws ec2 describe-instances \
> --filters "Name=tag:Name,Values=test_instance" \
> --query Reservations[*].Instances[*].[InstanceId]
[
    [
        [
            "i-034109c70aaa4b055"
        ]
    ]
]
[root@ip-10-0-0-74 ~]# 
[root@ip-10-0-0-74 ~]# #Execution of IMDSv2 forced setting("HttpTokens": "required")
[root@ip-10-0-0-74 ~]# aws ec2 modify-instance-metadata-options \
> --instance-id i-034109c70aaa4b055 \
> --http-tokens required \
> --http-put-response-hop-limit 1 \
> --http-endpoint enabled
{
    "InstanceId": "i-034109c70aaa4b055", 
    "InstanceMetadataOptions": {
        "State": "pending", 
        "HttpEndpoint": "enabled", 
        "HttpTokens": "required", 
        "HttpPutResponseHopLimit": 1
    }
}
[root@ip-10-0-0-74 ~]#

5. Behavior check at the time of IMDSv2 forced setting

"HttpTokens": Behavior check in "required" state (only IMDSv2 available (IMDSv2 forced))

The following is executed on the newly constructed" test_instance "environment

test_instance environment (IMDSv1 execution)


[root@ip-10-0-0-68 ~]# curl http://169.254.169.254/latest/meta-data/
<?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>
[root@ip-10-0-0-68 ~]#

ʻIMDSv2 is forced and cannot be obtained by the IMDSv1 method`

test_instance environment (IMDSv2 execution)


[root@ip-10-0-0-68 ~]# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v 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   9333      0 --:--:-- --:--:-- --:--:-- 11200
*   Trying 169.254.169.254...
* TCP_NODELAY set
* Connected to 169.254.169.254 (169.254.169.254) port 80 (#0)
> GET /latest/meta-data/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/7.61.1
> Accept: */*
> X-aws-ec2-metadata-token: AQAAAO6n081aj7u-yzdFHoD8zll2ZKiNfVS79OXp1qJDwgzw7-96gA==
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Accept-Ranges: bytes
< Content-Length: 313
< Content-Type: text/plain
< Date: Sat, 26 Sep 2020 15:01:45 GMT
< Last-Modified: Sat, 26 Sep 2020 14:28:58 GMT
< X-Aws-Ec2-Metadata-Token-Ttl-Seconds: 21600
< Connection: close
< Server: EC2ws
< 
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
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
* Closing connection 0
services/
[root@ip-10-0-0-68 ~]#

Recommended Posts

Instance Metadata Service Version 2 (IMDSv2): Setting and behavior check of Instance Metadata Service v2
Check the type and version of your Linux distribution
Commands and files to check the version of CentOS Linux
Check OpenSSL version of python 2.6