EbsEncryptionByDefault.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #! /usr/bin/env python3
  2. import boto3
  3. import json
  4. import logging
  5. import os
  6. import re
  7. logger = logging.getLogger('FCM')
  8. def determine_compliance(ec2client, detail):
  9. if ec2client.get_ebs_encryption_by_default().get('EbsEncryptionByDefault') is not True:
  10. logger.info('Determined not to be compliant')
  11. return False
  12. logger.debug('Determined to be compliant')
  13. return True
  14. def report(compliant, detail):
  15. return
  16. def remediate(detail):
  17. return
  18. def lambda_handler(event, context):
  19. init_logger()
  20. # Extract the useful stuff out of the input data
  21. if isinstance(event, (str, )):
  22. event = json.loads(event)
  23. body = json.loads(event['Records'][0]['body'])
  24. detail = body.get('detail', {})
  25. logger.debug(f'Inbound event: {json.dumps(event, default=str)}')
  26. logger.debug(f'Inbound body: {json.dumps(body, default=str)}')
  27. logger.debug(f'Inbound detail: {json.dumps(detail, default=str)}')
  28. if prevent_loop(detail):
  29. logger.info('Probable loop detected. Exiting.')
  30. return {}
  31. account = body['account']
  32. region = body['region']
  33. # Get a session on the destination account
  34. logger.info(f'Assuming role into account {account} in region {region}')
  35. client = boto3.client('sts')
  36. assumed_role_obj = client.assume_role(
  37. RoleArn=f'arn:aws:iam::{account}:role/fcm/fcm-analysis-EbsEncryptionByDefault',
  38. RoleSessionName='fcm-analysis-EbsEncryptionByDefault',
  39. DurationSeconds=900
  40. )
  41. credentials = assumed_role_obj['Credentials']
  42. logger.debug(f'Creating ec2client with credentials: {json.dumps(credentials, default=str)}')
  43. ec2client = boto3.client(
  44. 'ec2',
  45. aws_access_key_id = credentials['AccessKeyId'],
  46. aws_secret_access_key = credentials['SecretAccessKey'],
  47. aws_session_token = credentials['SessionToken'],
  48. region_name = region
  49. )
  50. compliant = determine_compliance(ec2client, detail)
  51. report(compliant, detail)
  52. if not compliant:
  53. remediate(detail)
  54. return True
  55. def init_logger():
  56. global logger
  57. try:
  58. logger.setLevel(os.environ['LOGLEVEL'])
  59. except:
  60. logger.setLevel('DEBUG')
  61. logger.warning('Logging level not set or set to invalid value.')
  62. def prevent_loop(detail):
  63. arn = r'^arn:aws:sts::\d{12}:assumed-role/fcm-'
  64. useragent = r'exec-env/AWS_Lambda'
  65. if re.search(arn, detail.get('userIdentity', {}).get('arn', '')):
  66. # We're in an fcm assumed role
  67. if re.search(useragent, detail.get('userAgent', '')):
  68. return True
  69. return False
  70. if __name__ == "__main__":
  71. # For testing only:
  72. handler = logging.StreamHandler()
  73. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  74. handler.setFormatter(formatter)
  75. logger.addHandler(handler)
  76. event = {
  77. "Records": [
  78. {
  79. "messageId": "39647048-eb52-4393-a39a-fda3a8d3fdfc",
  80. "receiptHandle": "AQEBXWJnH5nZjA5CYGceVCf/S8Rxy0MK0leslGeCZy5BNzejyqUNfmItzpc2D8AiapnByQk5AmR1UDMtfm6eptnEuKerBebtw0zJDXa/ed5joiWYKo8v2evl8Kun8dj77MRr70vsVqXenvSY5neNUSmtwKcnfNpsxL1qBYA7fatI/xLSOy08i4C8jsntJLA93Xag1IN0/+xiuzkYoBHm5oFf24Ed1EZ5izKJsWjKQc9bAzd4EKSuUXbNpFjW8WWDcr1c9Sdi6NS0F2P/qFRNinwCYRENicQZ5KSNISxqZgLe+nBfQRipn1kGMMNsgBfGgonOakkFB7KI1GGXFspxEYIPrIcUUJt7XwYKgvqUOF/gKezOdAPpVOSoAYkVdV4BjWxCTbw8L03wuDsqe0ihanB6oE/6GTachRsPg0WiSQcq2tw=",
  81. "body": "{\"version\":\"0\",\"id\":\"8e098047-456d-45b1-9ac4-2c2571bafcbd\",\"detail-type\":\"AWS API Call via CloudTrail\",\"source\":\"aws.ec2\",\"account\":\"082012130604\",\"time\":\"2019-09-26T19:37:50Z\",\"region\":\"us-east-2\",\"resources\":[],\"detail\":{\"eventVersion\":\"1.05\",\"userIdentity\":{\"type\":\"Root\",\"principalId\":\"082012130604\",\"arn\":\"arn:aws:iam::082012130604:root\",\"accountId\":\"082012130604\",\"accessKeyId\":\"ASIARGGCNZUWBA2LEEP3\",\"sessionContext\":{\"sessionIssuer\":{},\"webIdFederationData\":{},\"attributes\":{\"mfaAuthenticated\":\"true\",\"creationDate\":\"2019-09-26T13:53:54Z\"}}},\"eventTime\":\"2019-09-26T19:37:50Z\",\"eventSource\":\"ec2.amazonaws.com\",\"eventName\":\"DisableEbsEncryptionByDefault\",\"awsRegion\":\"us-east-2\",\"sourceIPAddress\":\"99.56.213.129\",\"userAgent\":\"console.ec2.amazonaws.com\",\"requestParameters\":{\"DisableEbsEncryptionByDefaultRequest\":{}},\"responseElements\":{\"DisableEbsEncryptionByDefaultResponse\":{\"xmlns\":\"http://ec2.amazonaws.com/doc/2016-11-15/\",\"ebsEncryptionByDefault\":false,\"requestId\":\"5e6d6a10-a7b9-4e55-9dd3-c04ec7db7198\"}},\"requestID\":\"5e6d6a10-a7b9-4e55-9dd3-c04ec7db7198\",\"eventID\":\"014d99f8-ac9b-41c6-8d8a-a7bb1dffd20a\",\"eventType\":\"AwsApiCall\"}}",
  82. "attributes": {
  83. "ApproximateReceiveCount": "1",
  84. "SentTimestamp": "1569526676382",
  85. "SenderId": "AIDAJQR6QDGQ7PATMSYEY",
  86. "ApproximateFirstReceiveTimestamp": "1569526676385"
  87. },
  88. "messageAttributes": {},
  89. "md5OfBody": "41bfacdf79a8139308b1790eac435955",
  90. "eventSource": "aws:sqs",
  91. "eventSourceARN": "arn:aws:sqs:us-east-2:082012130604:fcm-analysis-EbsEncryptionByDefault",
  92. "awsRegion": "us-east-2"
  93. }
  94. ]
  95. }
  96. lambda_handler(event = event, context={})