Understanding 169.254.169.254: Link-Local Address and AWS EC2 Metadata Service Explained


2 views

When examining network configurations, you might encounter the IP range 169.254.0.0/16 appearing in your routing tables. This range is reserved for link-local addressing as defined in RFC 3927. These addresses are automatically assigned when a device fails to obtain an IP address via DHCP (Automatic Private IP Addressing or APIPA).

# Typical Linux routing table entry
$ ip route show
169.254.0.0/16 dev eth0 scope link metric 1000

In cloud environments, particularly AWS EC2, this address takes on special significance. AWS reserves 169.254.169.254 for its Instance Metadata Service (IMDS), which provides vital information about the running instance:

# Retrieving EC2 instance metadata
$ curl http://169.254.169.254/latest/meta-data/
ami-id
instance-type
local-ipv4
public-keys/

The metadata service is crucial for:

  • Cloud-init configurations
  • IAM role credentials
  • Instance identity verification
  • Dynamic configuration management

Here's a practical Python example to access metadata:

import requests

def get_ec2_metadata(path=''):
    base_url = "http://169.254.169.254/latest/meta-data/"
    try:
        response = requests.get(base_url + path, timeout=2)
        return response.text
    except requests.exceptions.RequestException:
        return None

# Get instance ID
print(get_ec2_metadata('instance-id'))

While convenient, the metadata service presents security considerations:

  • Always use IMDSv2 which requires session tokens
  • Restrict access through security groups and IAM policies
  • Never expose metadata service to external networks

Example of secure IMDSv2 request:

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/instance-id

Other cloud platforms implement similar services:

  • Azure: 169.254.169.254 (Azure Instance Metadata Service)
  • Google Cloud: 169.254.169.254 (GCE Metadata Server)
  • Alibaba Cloud: 100.100.100.200

When examining routing tables across different operating systems, you'll often encounter this curious entry:

169.254.0.0/16 dev eth0 scope link metric 1000

The 169.254.0.0/16 range is reserved for link-local addresses as defined in RFC 3927. These addresses are:

  • Automatically assigned when DHCP fails (APIPA in Windows)
  • Only valid within a single network segment
  • Never routed beyond the local link

Major cloud providers (AWS, Azure, GCP) leverage this address space for instance metadata services:

# AWS EC2 metadata example
curl http://169.254.169.254/latest/meta-data/

The magic happens because:

  1. Cloud hypervisors intercept traffic to 169.254.169.254
  2. Requests never actually hit the link-local network
  3. Responses contain instance-specific metadata

Retrieving AWS metadata:

# Get instance ID
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

# Get availability zone
AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)

Azure example:

# Get Azure VM tags
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"

While convenient, metadata services require proper hardening:

  • Use IMDSv2 (AWS) with session tokens
  • Restrict metadata access in IAM policies
  • Disable metadata service when not needed

Example IMDSv2 request:

TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 3600")

curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/