Networking and DNS Required
Require tokens for the metadata service
Make every cloud server's metadata service answer only requests that carry a session token. Allow the token to travel one network hop, or two when containers on the host need it.
How to do it
The metadata address hands out the machine's credentials. A server-side request forgery hole can read it with a plain GET. On AWS, require IMDSv2 with http_tokens = "required" and a hop limit of 1. Use 2 when containers on the host need it. Google Cloud and Azure already require a special header, Metadata-Flavor: Google or Metadata: true. Set the account default in every region too, so new servers start safe.
Example
resource "aws_instance" "web" {
ami = data.aws_ami.web.id
instance_type = "t4g.small"
metadata_options {
http_tokens = "required"
http_put_response_hop_limit = 1
}
}
# The default for every new server in this region
resource "aws_ec2_instance_metadata_defaults" "baseline" {
http_tokens = "required"
http_put_response_hop_limit = 1
}
aws ec2 describe-instances --query 'Reservations[].Instances[?MetadataOptions.HttpTokens==`optional`].InstanceId' --output text # empty
curl -s -o /dev/null -w '%{http_code}\n' http://169.254.169.254/latest/meta-data/ # 401
How to check
The query below lists no instance with tokens optional. No instance has a hop limit above 2. From the server, a GET to 169.254.169.254 without a token gets 401.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers infrastructure playbook: https://agentwranglers.se/playbook/infrastructure/networking-and-dns/metadata-service-tokens.