DEV Community

Mehmet Ayberk
Mehmet Ayberk

Posted on • Originally published at ayberk.ninja

Managing Security Alarms with Automation in AWS

TLDR;

Automated detection of security threats and taking necessary actions are among the most important aspects. As the attack surface expands daily, the number of topics requiring regular monitoring also increases. At this point, it is critical to build, design, and maintain automated systems as well as manual controls and human power. AWS has various security services that allow us to perform some security checks on a regular basis. Using these services more efficiently depends on the architecture we will design depending on the structure of our organization. In this blog post, I will take some security alarms that we think may be harmful in AWS by using AWS's security services and take automatic actions thanks to Lambda.

What Will We Automate?

  • Detection and Automated Action of AWS CloudTrail Deactivation

What Else Can You Automate?

  • Abnormal Pod Incidents to the EKS
  • Unexpected Traffic Increase on EC2
  • Detection of Abnormal Activity of an IAM User
  • Disabling Encryption Settings on RDS
  • Automatic Check and Correction of S3 Bucket Encryption Status
  • Detect IAM Root User Usage and Send Alarm
  • Controlling EC2 Instance Security Groups
  • IAM High Authority Role Monitoring
  • And much more

Detecting and Automating Responses to AWS CloudTrail Deactivation

When attackers gain unauthorized access through the interface or CLI, there are some steps they will take. One of them will be to erase the traces they have left behind. The first method they will try for this will be to deactivate CloudTrail if it is active. In this example, we will check whether CloudTrail is active or not in an automated way and reactivate it if it is deactivated. Of course, the task of activating CloudTrail also falls to our automation.

My goal here is to give you an overview of how you can build mini security automations in AWS, rather than having you do these examples in person.

At the end of the day, our architecture will look like this:

Image description

Enable cloudtrail-enabled Rule in AWS Config

First of all, we need to activate the AWS Config service. I skip the part on how to activate AWS Config and continue my article in the scenario where it is already active. We need to check whether CloudTrail is active on AWS Config. For that from the left menu we have to go to Rules and Add Rule. By selecting AWS Managed Rule, we select cloudtrail-enabled or multi-region-cloudtrail-enabled and create our rule.

We could have created the automation for this scenario by listening to CloudTrail calls directly on EventBridge without using AWS Config. I added this step so that you can see different scenarios.

Image description

Automatic Response with Lambda Function

We need the Lambda function to take the automatic action if CloudTrail is deactivated. The code we will write here will be quite simple. Of course, you may need to improve your code depending on the needs of the organization. For this, we will of course create an IAM role, create our Lambda function, and add the IAM code to this Lambda function. (Spoiler: Yes! We will then use EventBridge to trigger the Lambda function).

Before we start creating the Lambda function, we will need to create an IAM role to give the Lambda function the authorizations it needs to make the necessary changes to CloudTrail. You can also use AWS's IAM Role Generator to create an IAM role.

For this, you must follow these steps on the IAM screen:

  • Go to IAM > Policies > Create Policy

Make sure to comply with the least privilege policy when creating a new IAM role. This could prevent further security problems. Here, we will create our authorization instead of authorizing our role such as AdministratorAccess.

  • Here is what our policy looks like:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudtrail:UpdateTrail",
                "cloudtrail:StartLogging",
                "cloudtrail:DescribeTrails",
                "lambda:InvokeFunction",
                "cloudtrail:GetTrailStatus"
            ],
            "Resource": "*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

You can customize the Policy according to your needs.

  • Create the policy.
  • Go to IAM > Roles.
  • Select AWS Service as Trusted entity type and proceed by selecting Lambda in the Use case field just below.
  • In the Permission policy tab, let's assign the role by selecting the Policy we just created and complete the new role creation step.

Finally we can create our Lambda function. I will create the Lambda function in Python 3.x. You can of course use any other programming language that suits you or that you are comfortable with. Anyway, it is up to you to improve and extend the code here according to your needs. Here is my PoC code:

# Import the required libs
import json
import boto3
import logging
from botocore.exceptions import ClientError

# Making logging settings
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    # Create a client to access the AWS CloudTrail service
    cloudtrail = boto3.client('cloudtrail')

    try:
        # Log the incoming event
        logger.info(f"Received event: {json.dumps(event)}")
        # List all CloudTrails in the account
        response = cloudtrail.describe_trails()

        # If there is no trail, return an error
        if not response['trailList']:
            logger.warning("No CloudTrail trails found in the account")
            return {
                'statusCode': 404,
                'body': 'No CloudTrail trails found'
            }

        # Perform operations for each trail
        for trail in response['trailList']:
            trail_name = trail['Name']

            try:
                # Checking the current status of the trail
                status = cloudtrail.get_trail_status(Name=trail_name)

                # If logging is closed then do them
                if not status['IsLogging']:
                    logger.info(f"Trail {trail_name} is disabled. Enabling it...")

                    # Activate the Trail
                    cloudtrail.start_logging(Name=trail_name)

                    logger.info(f"Successfully enabled trail: {trail_name}")
                else:
                    logger.info(f"Trail {trail_name} is already enabled")

            except ClientError as e:
                # If an error occurs while activating a trail, we continue with other trails
                logger.error(f"Error processing trail {trail_name}: {str(e)}")
                continue

        return {
            'statusCode': 200,
            'body': 'Successfully processed all trails'
        }

    except ClientError as e:
        logger.error(f"Error: {str(e)}")
        return {
            'statusCode': 500,
            'body': f"Error: {str(e)}"
        }
Enter fullscreen mode Exit fullscreen mode

Event Triggering with EventBridge

We need to connect the Lambda function to an Event via EventBridge to automatically take action when the case we expect occurs. For this let's create a new event. While creating our rule, we select the Config Rules Compliance Change option in the Sample event section. As the creation method, we will write our own rule by selecting Custom pattern again. Our rule will be as follows:

For this scenario, we want to trigger the Lambda function we wrote to recognize when a Trail is stopped. We need to create our EventBridge rule as follows:

  • You can fill in the Event name field as you wish.
  • In our scenario here, the Rule Type field should be Rule with an event pattern.
  • On the next page we must select Other in the Event Source field.
  • On the Build event pattern page, we can go down to the bottom and write our rule in the Event pattern field just below by making the Creation method Custom pattern without changing any other settings.
  • You can write the following code in the event pattern field:
{
  "source": ["aws.config"],
  "detail-type": ["Config Rules Compliance Change"],
  "detail": {
    "configRuleName": ["cloudtrail-enabled"],
    "newEvaluationResult": {
      "complianceType": ["NON_COMPLIANT"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

I can say that the writing format of Event Patterns is very clear and simple. If you have more questions about writing Custom Event Patterns, you can check AWS's official documentation..

  • Select the AWS service radio button as the target and then select the Lambda function in the Select a target section and the Lambda function we have prepared in the Function section.
  • Create the rule.

The EventBridge Rule summary we created should look like this:
Image description

That's all. Now we have a mini automation that will reactivate any of the CloudTrail Trails in case any of them is deactivated. Of course, you can also develop different solutions specific to your organization. For example:

  • If you have Trails that should not be included in this automation, you can create an Exception list and develop your code accordingly.
  • When the automation runs, you can send an e-mail containing information such as the Trail name, the user who deactivated the Trail, the time when the Lambda function was triggered.
  • You can visualize the logs of all these operations by sending them to ELK.

Test

Just deactivate an existing Trail. After a short time, you will see that the Trail has been reactivated. You can also observe your test by following these metrics after deactivating your Trail:

  • You can observe whether your Lambda code is triggered or not from CloudWatch Log groups.
  • You can observe your EventBridge metrics.

Also after a while you have to see Noncompliant Warning on the AWS Config.

Image description

In fact, we could have triggered our Lambda function by selecting the Create custom Lambda rule option while creating our Config Rule without using EventBridge. I would like to state again that my goal here is to provide you with different perspectives. There are many different ways to create such mini security automations on AWS. Of course, you can create the most suitable architecture according to your needs and by getting to know AWS services.

Last Word

In this blog post, my goal was to give you a perspective on how you can set up mini automations to make your AWS environment more secure. I strongly encourage you to try building the other automations in the "What Else Can You Automate?" section or develop the automations mentioned in this blog post.

Depending on your business needs, the automations you can build will vary and change. The code you write may change and the AWS services you use may change.

If you have any suggestions for the article, please feel free to contact me through any communication channel (Linkedin, Twitter, Threema, etc.). I am constantly updating the articles in line with your feedback.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay