Enforcing IMDSv2 Across AWS Infrastructure
Implement IMDSv2 enforcement to protect EC2 instances from SSRF attacks and credential theft with mandatory session tokens.
The Instance Metadata Service v2 (IMDSv2) protects EC2 instances from SSRF attacks by requiring session-oriented requests. This guide covers enforcement strategies at scale.
Understanding IMDSv1 Risks
SSRF Attack Vector
IMDSv1 vulnerabilities allow attackers to steal credentials:
# Attacker exploiting SSRF to get credentials (IMDSv1)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2Role
IMDSv2 Protection
IMDSv2 requires a session token:
# IMDSv2 requires token-based requests
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" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2Role
Enforcing IMDSv2 on Launch
Launch Template Configuration
SecureLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: IMDSv2Required
LaunchTemplateData:
MetadataOptions:
HttpEndpoint: enabled
HttpTokens: required # Enforce IMDSv2
HttpPutResponseHopLimit: 1
InstanceMetadataTags: enabled
Terraform Configuration
resource "aws_launch_template" "secure" {
name = "imdsv2-required"
metadata_options {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 1
instance_metadata_tags = "enabled"
}
# Other configuration...
}
Organization-Wide Enforcement
Service Control Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequireIMDSv2",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
},
{
"Sid": "PreventIMDSv2Disable",
"Effect": "Deny",
"Action": "ec2:ModifyInstanceMetadataOptions",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:MetadataHttpTokens": "optional"
}
}
}
]
}
AWS Config Rule
IMDSv2ComplianceRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: ec2-imdsv2-check
Description: Checks whether IMDSv2 is required
Source:
Owner: AWS
SourceIdentifier: EC2_IMDSV2_CHECK
Scope:
ComplianceResourceTypes:
- AWS::EC2::Instance
Updating Existing Instances
Bulk Update Script
import boto3
ec2 = boto3.client('ec2')
def enforce_imdsv2_all_instances():
paginator = ec2.get_paginator('describe_instances')
for page in paginator.paginate():
for reservation in page['Reservations']:
for instance in reservation['Instances']:
instance_id = instance['InstanceId']
metadata = instance.get('MetadataOptions', {})
if metadata.get('HttpTokens') != 'required':
print(f"Updating {instance_id} to require IMDSv2")
try:
ec2.modify_instance_metadata_options(
InstanceId=instance_id,
HttpTokens='required',
HttpPutResponseHopLimit=1,
HttpEndpoint='enabled'
)
print(f"Successfully updated {instance_id}")
except Exception as e:
print(f"Failed to update {instance_id}: {e}")
def get_imdsv1_instances():
"""Find instances still using IMDSv1"""
imdsv1_instances = []
paginator = ec2.get_paginator('describe_instances')
for page in paginator.paginate():
for reservation in page['Reservations']:
for instance in reservation['Instances']:
metadata = instance.get('MetadataOptions', {})
if metadata.get('HttpTokens') == 'optional':
imdsv1_instances.append({
'instance_id': instance['InstanceId'],
'name': get_instance_name(instance),
'state': instance['State']['Name']
})
return imdsv1_instances
Application Compatibility
SDK Updates
Ensure applications use IMDSv2-compatible SDK versions:
# Python - boto3 automatically uses IMDSv2 in recent versions
import boto3
from botocore.config import Config
# Configure retry for metadata service
config = Config(
retries = {
'max_attempts': 3,
'mode': 'adaptive'
}
)
session = boto3.Session()
credentials = session.get_credentials()
Container Configuration
# ECS Task Definition with IMDSv2
{
"containerDefinitions": [
{
"name": "app",
"image": "my-app:latest",
"environment": [
{
"name": "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE",
"value": "IPv4"
}
]
}
],
"requiresCompatibilities": ["EC2"]
}
Monitoring IMDSv1 Usage
# CloudWatch metric for IMDSv1 usage
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name MetadataNoToken \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-02T00:00:00Z \
--period 3600 \
--statistics Sum
Working with Warqline
We are a cloud engineering consultancy and an official AWS and Google Cloud partner. If you are running this in production and want a second pair of eyes, we scope work in a free 45-minute technical call: you describe what you are running and what worries you, and we tell you what we would look at first.
Conclusion
IMDSv2 enforcement is critical for EC2 security. Use SCPs for prevention, Config rules for compliance, and monitoring to track adoption across your infrastructure.