EC2 instance verifier
"""
ssh_key=$(cut -f2 -d\ /etc/ssh/ssh_host_ed25519_key.pub)
document=$(curl -s http://169.254.169.254:/latest/dynamic/instance-identity/document |base64 -w 0)
signature=$(curl -s http://169.254.169.254:/latest/dynamic/instance-identity/signature |tr -d '\n')
curl -s http://169.254.169.254/latest/dynamic/instance-identity/signature |base64 -d |openssl rsautl -verify -inkey AWS.rsa -certin
"""
import json
from os import environ
from base64 import b64decode
import boto3
import rsa
import six
BUCKET = environ.get('BUCKET', 'libnd-global')
ec2 = boto3.resource('ec2')
s3 = boto3.resource('s3')
key = rsa.PublicKey(
95318929170905151888329665240401444091282161020462124768285033014806370951275071516877911971246545424860101188830039891779094845649876855959262057141427470998542416206797397568522766060103937903652527298892685356856855778317104811739620406608569714766104002527470216783278061734986045788816288050922892785917,
65537)
def ec2_resource(id, region):
global ec2
if region not in ec2.meta.client._endpoint.host:
ec2 = boto3.resource('ec2', region_name=region)
instance = ec2.Instance(id)
return {
'vpcId': instance.vpc_id,
'subnetId': instance.subnet_id,
'tags':
{tag['Key']: tag['Value']
for tag in getattr(instance, 'tags', ())},
}
def resource(identity):
if isinstance(identity, six.string_types):
identity = json.loads(identity)
id, region = identity['instanceId'], identity['region']
data = ec2_resource(id, region)
data.update(identity)
return {k: v for k, v in six.iteritems(data) if v}
def save_host_data(identity, ssh_key):
path = '/'.join(identity[k]
for k in ('accountId', 'vpcId', 'availabilityZone',
'subnetId', 'privateIp'))
key = '/'.join((path, ssh_key))
identity_json = json.dumps(identity, separators=(',', ':'), sort_keys=True)
s3_obj = s3.Object(BUCKET, key).put(
Body=identity_json,
ContentType='application/json', )
return s3_obj
def handler(event=None, context=None):
data = event['data'].split('.')
ssh_key, document, signature = data[0], b64decode(data[1]), b64decode(
data[2])
if rsa.verify(document, signature, key):
host_data = resource(document)
return save_host_data(host_data, ssh_key)
if __name__ == '__main__':
event = {
'data':
('AAAAC3NzaC1lZDI1NTE5AAAAILMHqWpOWppfAQ6XI1xjcLhuVWUvV7OzbLjP5kfanQ6j'
'.'
'ewogICJwcml2YXRlSXAiIDogIjE3Mi4yMi4xMC4yNDEiLAogICJkZXZwYXlQcm9kdWN0Q29kZXMiIDogbnVsbCwKICAiYXZhaWxhYmlsaXR5Wm9uZSIgOiAidXMtZWFzdC0xZCIsCiAgInZlcnNpb24iIDogIjIwMTAtMDgtMzEiLAogICJpbnN0YW5jZUlkIiA6ICJpLTBmNGFlNmMzNmNlNmNjNzhhIiwKICAiYmlsbGluZ1Byb2R1Y3RzIiA6IG51bGwsCiAgInBlbmRpbmdUaW1lIiA6ICIyMDE3LTAzLTMwVDE4OjM2OjA3WiIsCiAgImluc3RhbmNlVHlwZSIgOiAicjQubGFyZ2UiLAogICJhY2NvdW50SWQiIDogIjIzMDM5MTg0MDEwMiIsCiAgImFyY2hpdGVjdHVyZSIgOiAieDg2XzY0IiwKICAia2VybmVsSWQiIDogbnVsbCwKICAicmFtZGlza0lkIiA6IG51bGwsCiAgImltYWdlSWQiIDogImFtaS0wYjMzZDkxZCIsCiAgInJlZ2lvbiIgOiAidXMtZWFzdC0xIgp9'
'.'
'VkNmisiw50bXAi2CczD1ROnfFvSR+QQbtwfa+Bm3hr9hNGsqazL9lP9CIHEVJOKDH+UTPSsYeGAfWbB8NAdy2f9BskIdW+rBYZgHEP39einhHnTj+C0TasGi1WcC5jR1EspJwpL+7FnFdZLaTYnIRDHJ+VOXSFd9JF9j9HRqkeM='
)
}
print(handler(event))