Logging account activity within your AWS infrastructure is paramount to your security posture and could even be required by compliance standards such as PCI-DSS (Payment Card Industry Security Standard). Organizations often analyze these logs to adapt to changes and respond quickly to security events. For example, if users are reporting that their resources are unable to communicate with the public internet, it would be beneficial to know if a network access list had been changed just prior to the incident. Many of our customers ship AWS CloudTrail event logs to an Amazon Elasticsearch Service cluster for this type of analysis. However, security best practices and compliance standards could require additional considerations. Common concerns include how to analyze log data without the data leaving the security constraints of your private VPC.
In this post, I’ll show you not only how to store your logs, but how to put them to work to help you meet your compliance goals. This implementation deploys an Amazon Elasticsearch Service domain with Amazon Virtual Private Cloud (Amazon VPC) support by utilizing VPC endpoints. A VPC endpoint enables you to privately connect your VPC to Amazon Elasticsearch without requiring an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. An AWS Lambda function is used to ship AWS CloudTrail event logs to the Elasticsearch cluster. A separate AWS Lambda function performs scheduled queries on log sets to look for patterns of concern. Amazon Simple Notification Service (SNS) generates automated reports based on a sample set of PCI guidelines discussed further in this post and notifies stakeholders when specific events occur. Kibana serves as the command center, providing visualizations of CloudTrail events that need to be logged based on the provided sample set of PCI-DSS compliance guidelines. The automated report and dashboard that are constructed around the sample PCI-DSS guidelines assist in event awareness regarding your security posture and should not be viewed as a de facto means of achieving certification. This solution serves as an additional tool to provide visibility in to the actions and events within your environment. Deployment is made simple with a provided AWS CloudFormation template.
The figure above depicts the architecture discussed in this post. An Elasticsearch cluster with VPC support is deployed within an AWS Region and Availability Zone. This creates a VPC endpoint in a private subnet within a VPC. Kibana is an Elasticsearch plugin that resides within the Elasticsearch cluster, it is accessed through a provided endpoint in the output section of the CloudFormation template. CloudTrail is enabled in the VPC and ships CloudTrail events to both an S3 bucket and CloudWatch Log Group. The CloudWatch Log Group triggers a custom Lambda function that ships the CloudTrail Event logs to the Elasticsearch domain through the VPC endpoint. An additional Lambda function is created that performs a periodic set of Elasticsearch queries and produces a report that is sent to an SNS Topic. A Windows-based EC2 instance is deployed in a public subnet so users will have the ability to view and interact with a Kibana dashboard. Access to the EC2 instance can be restricted to an allowed CIDR range through a parameter set in the CloudFormation deployment. Access to the Elasticsearch cluster and Kibana is restricted to a Security Group that is created and is associated with the EC2 instance and custom Lambda functions.
Sample PCI-DSS Guidelines
This solution provides a sample set of (10) PCI-DSS guidelines for events that need to be logged.
- All Commands, API action taken by AWS root user
- All failed logins at the AWS platform level
- Action related to RDS (configuration changes)
- Action related to enabling/disabling/changing of CloudTrail, CloudWatch logs
- All access to S3 bucket that stores the AWS logs
- Action related to VPCs (creation, deletion and changes)
- Action related to changes to SGs/NACLs (creation, deletion and changes)
- Action related to IAM users, roles, and groups (creation, deletion and changes)
- Action related to route tables (creation, deletion and changes)
- Action related to subnets (creation, deletion and changes)
In this walkthrough, you’ll create an Elasticsearch cluster within an Amazon VPC environment. You’ll ship AWS CloudTrail logs to both an Amazon S3 Bucket (to maintain an immutable copy of the logs) and to a custom AWS Lambda function that will stream the logs to the Elasticsearch cluster. You’ll also create an additional Lambda function that will run once a day and build a report of the number of CloudTrail events that occurred based on the example set of 10 PCI-DSS guidelines and then notify stakeholders via SNS. Here’s what you’ll need for this solution:
- An AWS account
- An Amazon Elastic Cloud Compute (EC2) key pair
To make it easier to get started, I’ve included an AWS CloudFormation template that will automatically deploy the solution. The CloudFormation template along with additional files can be downloaded from this link. You’ll need the following resources to set it up:
- An S3 bucket to upload and store the sample AWS Lambda code and sample Kibana dashboards. This bucket name will be requested during the CloudFormation template deployment.
- An Amazon Virtual Private Cloud (Amazon VPC).
If you’re unfamiliar with how CloudFormation templates work, you can find more info in the CloudFormation Getting Started guide.
AWS CloudFormation deployment
The following parameters are available in this template.
|Elasticsearch Domain Name||Name of the Amazon Elasticsearch Service domain.|
|Elasticsearch Version||6.2||Version of Elasticsearch to deploy.|
|Elasticsearch Instance Count||3||The number of data nodes to deploy in to the Elasticsearch cluster.|
|Elasticsearch Instance Class||The instance class to deploy for the Elasticsearch data nodes.|
|Elasticsearch Instance Volume Size||10||The size of the volume for each Elasticsearch data node in GB.|
|VPC to launch into||The VPC to launch the Amazon Elasticsearch Service cluster into.|
|Availability Zone to launch into||The Availability Zone to launch the Amazon Elasticsearch Service cluster into.|
|Private Subnet ID||The subnet to launch the Amazon Elasticsearch Service cluster into.|
|Elasticsearch Security Group||A new Security Group is created that will be associated with the Amazon Elasticsearch Service cluster.|
|Security Group Description||A description for the above created Security Group.|
|Windows EC2 Instance Class||m5.large||Windows instance for interaction with Kibana.|
|EC2 Key Pair||EC2 Key Pair to associate with the Windows EC2 instance.|
|Public Subnet||Public subnet to associate with the Windows EC2 instance for access.|
|Remote Access Allowed CIDR||0.0.0.0/0||The CIDR range to allow remote access (port 3389) to the EC2 instance.|
|S3 Bucket Name—Lambda Functions||S3 Bucket that contains custom AWS Lambda functions.|
|Private Subnet||Private subnet to associate with AWS Lambda functions that are deployed within a VPC.|
|CloudWatch Log Group Name||This will create a CloudWatch Log Group for the AWS CloudTrail event logs.|
|S3 Bucket Name—CloudTrail logging||This will create a new Amazon S3 Bucket for logging CloudTrail events. Name must be a globally unique value.|
|Date range to perform queries||now-1d||(examples: now-1d, now-7d, now-90d)|
|Lambda Subnet CIDR||Create a Subnet CIDR to deploy AWS Lambda Elasticsearch query function in to|
|Availability Zone—Lambda||The availability zone to associate with the preceding AWS Lambda Subnet|
|Email Address||[email protected]||Email address for reporting to notify stakeholders via SNS. You must accept the subscription by selecting the link sent to this address before alerts will arrive.|
It takes 30-45 minutes for this stack to be created. When it’s complete, the CloudFormation console will display the following resource values in the Outputs tab. These values can be referenced at any time and will be needed in the following sections.
|oElasticsearchDomainEndpoint||Elasticsearch Domain Endpoint Hostname|
|oKibanaEndpoint||Kibana Endpoint Hostname|
|oEC2Instance||Windows EC2 Instance Name used for Kibana access|
|oSNSSubscriber||SNS Subscriber Email Address|
|oElasticsearchDomainArn||Arn of the Elasticsearch Domain|
|oEC2InstancePublicIp||Public IP address of the Windows EC2 instance|
Managing and testing the solution
Now that you’ve set up the environment, it’s time to configure the Kibana dashboard.
From the AWS CloudFormation output, gather information related to the Windows-based EC2 instance. Once you have retrieved that information, move on to the next steps.
Initial configuration and index pattern
- Log into the Windows EC2 instance via Remote Desktop Protocol (RDP) from a resource that is within the allowed CIDR range for remote access to the instance.
- Open a browser window and navigate to the Kibana endpoint hostname URL from the output of the AWS CloudFormation stack. Access to the Elasticsearch cluster and Kibana is restricted to the security group that is associated with the EC2 instance and custom Lambda functions during deployment.
- In the Kibana dashboard, select Management from the left panel and choose the link for Index Patterns.
- Add one index pattern containing the following: cwl-*
- Select Next Step.
- Select the Time Filter Field named @timestamp.
- Select Create index pattern.
At this point we’ve launched our environment and have accessed the Kibana console. Within the Kibana console, we’ve configured the index pattern for the CloudWatch logs that will contain the CloudTrail events. Next, we’ll configure visualizations and a dashboard.
Importing sample PCI DSS queries and Kibana dashboard
- Copy the export.json from the location you extracted the downloaded zip file to the EC2 Kibana bastion.
- Select Management on the left panel and choose the link for Saved Objects.
- Select Import in upper right corner and navigate to export.json.
- Select Yes, overwrite all saved objects, then select Index Pattern cwl-* and confirm all changes.
- Once the import completes, select PCI DSS Dashboard to see the sample dashboard and queries.
Note: You might encounter an error during the import that looks like this:
This simply means that your streamed logs do not have login-type events in the time period since your deployment. To correct this, you can add a field with a null event.
- From the left panel, select Dev Tools and copy the following JSON into the left panel of the console:
- Select the green Play triangle to execute the POST of a document with the missing field.
- Now reimport the dashboard using the steps in Importing Sample PCI DSS Queries and Kibana Dashboard. You should be able to complete the import with no errors.
At this point, you should have CloudTrail events that have been streamed to the Elasticsearch cluster, with a configured Kibana dashboard that looks similar to the following graphic:
A custom AWS Lambda function was created during the deployment of the Amazon CloudFormation stack. This function uses the sample PCI-DSS guidelines from the Kibana dashboard to build a daily report. The Lambda function is triggered every 24 hours and performs a series of Elasticsearch time-based queries of now-1day (the last 24 hours) on the sample guidelines. The results are compiled into a message that is forwarded to Amazon Simple Notification Service (SNS), which sends a report to stakeholders based on the email address you provided in the CloudFormation deployment.
The Lambda function will be named <CloudFormation Stack Name>-ES-Query-LambdaFunction. The Lambda Function enables environment variables such as your query time window to be adjusted or additional functionality like additional Elasticsearch queries to be added to the code. The below sample report allows you to monitor any events against the sample PCI-DSS guidelines. These reports can then be further analyzed in the Kibana dashboard.
At this point, you have now created a private Elasticsearch cluster with Kibana dashboards that monitors AWS CloudTrail events on a sample set of PCI-DSS guidelines and uses Amazon SNS to send a daily report providing awareness in to your environment—all isolated securely within a VPC. In addition to CloudTrail events streaming to the Elasticsearch cluster, events are also shipped to an Amazon S3 bucket to maintain an immutable source of your log files. The provided Lambda functions can be further modified to add additional or more complex search queries and to create more customized reports for your organization. With minimal effort, you could begin sending additional log data from your instances or containers to gain even more insight as to the security state of your environment. The more data you retain, the more visibility you have into your resources and the closer you are to achieving Compliance-on-Demand.
Want more AWS Security how-to content, news, and feature announcements? Follow us on Twitter.