Notification of Unencrypted AWS Resources

When operating in the cloud, it’s essential to ensure your resources are encrypted. This means that it’s usually a good idea to be informed if any of your resources have been intentionally or accidentally decrypted.

In this blog post, I’ll walk you through the process of setting up a Lambda function to detect your S3 bucket encryption on a 24-hour cycle. The subscriber would be informed if any buckets were discovered to be unencrypted.

Prerequisite

  1. Install AWS SAM – https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html

What is AWS SAM?

According to AWS:

“The AWS Serverless Application Model (SAM) is an open-source framework for building serverless applications. It provides shorthand syntax to express functions, APIs, databases, and event source mappings. With just a few lines per resource, you can define the application you want and model it using YAML. During deployment, SAM transforms and expands the SAM syntax into AWS CloudFormation syntax, enabling you to build serverless applications faster.”

At the root of the project folder, create a sam template file and name it template.yaml

AWSTemplateFormatVersion: ‘2010-09-09’
Transform: AWS::Serverless-2016-10-31
Description: >
  unencrypted-resources
Globals:
  Function:
    Timeout: 600

Resources:
  UnencryptedResourceFinderFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      FunctionName: UnencryptedResourceFinderFunction
      CodeUri: unencrypted_aws_resources/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        – “arm64”
      Policies:
        – Statement:
            – Effect: Allow
              Action:
                – s3:ListBucket
                – s3:ListAllMyBuckets
                – s3:GetEncryptionConfiguration
              Resource: arn:aws:s3:::*
        – Statement:
            – Effect: Allow
              Action:
                – sns:Publish
              Resource: !Ref UnencryptedResourceNotifierTopic
      Events:
        EveryDaySceduler:
          Type: Schedule
          Properties:
            Schedule: ‘rate(24 hours)’
            Name: ScheduleLambdaToFindUnencryptedResources
            Enabled: true
      Environment:
        Variables:
          SNSTopicArn: !Ref UnencryptedResourceNotifierTopic
 
  UnencryptedResourceNotifierTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: UnencryptedResourceNotifierTopic
      Subscription:
        – Endpoint: sampreeth.amithkumar@cevo.com.au
          Protocol: email

Create a folder in the same directory and name it unencrypted_aws_resources

As we are using Python as our runtime in sam template.yaml, let’s create app.py and requirements.txt files under unencrypted_aws_resources

app.py

import os
import boto3
from botocore.exceptions import ClientError

s3_client = boto3.client(‘s3’)

sns_client = boto3.client(‘sns’)

def sns_publish(message):
    sns_client.publish(
        TopicArn=os.environ[‘SNSTopicArn’],
        Message=message,
        Subject=’UnEncrypted Resource Notification’)

def get_not_encrypted_s3_bucket():
    try:
        response = s3_client.list_buckets()
        not_encrypted_bucket = []
        for bucket in response[‘Buckets’]:
            s3_client.get_bucket_encryption(Bucket=bucket[‘Name’])
       

    except ClientError as e:
        if e.response[‘Error’][‘Code’] == ‘ServerSideEncryptionConfigurationNotFoundError’:
            not_encrypted_bucket.append(bucket[‘Name’])
        else:
            print(“unexpected error: “, e)
   
    if len(not_encrypted_bucket) == 0:
        sns_publish(message=’All S3 Buckets are encrypted’)
    else:
        sns_publish(message=’ ‘.join(str(e) for e in not_encrypted_bucket))

           
def lambda_handler(event,context):
    get_not_encrypted_s3_bucket()  

if __name__ == “__main__”:
    lambda_handler(event={}, context={})

requirements.txt

boto3
botocore

Setup and Deployment Process

Step 1: Login to AWS Account

Get your AWS Credentials from your SSO Portal, then declare them in terminal.

export AWS_ACCESS_KEY_ID=

export AWS_SECRET_ACCESS_KEY=

export AWS_SESSION_TOKEN=

Or, if you have SSO configured (export your AWS profile with the right profile):

export AWS_PROFILE=

Step 2: Update the Subscriber Details

To subscribe to the SNS Topic, make sure to update the endpoint in the template.yaml file found in the root of the project folder.

Step 3: Build the Application

Once you have installed AWS SAM CLI, you can run the command in the root of the project folder.

sam build — use-container

Once the application is built, run the below command to deploy the application.

sam deploy — guided

Follow the instruction on the screen to deploy.

Enjoyed this blog?

Share it with your network!

Move faster with confidence