Last active
May 23, 2017 12:27
-
-
Save seansummers/88e27c026e5f63e1399ca6f2a5eed15a to your computer and use it in GitHub Desktop.
EC2 instance verifier
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| 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)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment