AWS EC2 metadata

The 169.254.169.254 address

The 169.254.169.254 endpoint can be reached by an EC2 instance locally during runtime. The address provides all sorts of meta data which helps to operate, audit, maintain an instance during its life time.

The pseudo address can be reached locally only (on the instance):

http://169.254.169.254/latest/meta-data/

Beside meta data information such like ami-id, hostname, instance-id, placement (so the AZ, availability zone) it also provides security related information.

Example:

curl http://169.254.169.254/latest/meta-data/instance-type

m5.xlarge

If utilized correctly the information provided through the 169.254.169.254 endpoint provides tremendous help to maintain code more effectively, get risk risks reduced where access keys may be leaked into code, code repositories (git, svn) or even may be posted in documentation. Depending to what policy would be attached to those keys it could open high security concerns.

Increased security and simplified code

As an IAM profile can be assigned to any EC2 instance (one at a time) it allows to increase security significantly and on top to let key handling become much easier. The need to share keys, the risk to have them embedded in code, the need to track keys to get them rotated and such can be eliminated in favor towards higher security.

Example:

#curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>

{
  “Code” : “Success”,
  “LastUpdated” : “2020-11-19T16:47:54Z”,
  “Type” : “AWS-HMAC”,
  “AccessKeyId” : “ABCDEFGHIJKLMNOPQRST”,
  “SecretAccessKey” : “1234567890ABCDEFGHIJKLMNOPQRST”,
  “Token” : “…”,
  “Expiration” : “2020-11-19T23:14:05Z”
}

The official documents are provided at AWS here.

Code samples

PHP

GetRegion reads the placement information from the pseudo address at http://169.254.169.254/latest/meta-data/placement. With the CredentialsProvider::instanceProfile() it allows to avoid configuration handling as described.

public function __construct()
{
    $provider = CredentialProvider::instanceProfile();
    $memoizedProvider = CredentialProvider::memoize($provider);

    $this->awsclient = new Client(
        array(
            'credentials' => $memoizedProvider,
            'region'  => $this->GetRegion();
            'version' => 'latest'
        )
    );
} 

Python

session = boto3.Session(region_name=Region)
credentials = session.get_credentials()
credentials = credentials.get_frozen_credentials()

Key = credentials.access_key
Secret = credentials.secret_key
Token = credentials.token

client = boto3.client('',
            aws_access_key_id=Key,
            aws_secret_access_key=Secret,
            aws_session_token=Token,
            region_name=Region
            )

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: