DEV Community

Montaigu
Montaigu

Posted on

How to monitor all AWS Console logins and failed attempts with CloudTrail and CloudWatch - Terraform automation

You never know when a bad guy wants to send birthdays alerts with Lambda.. just joking :D He probably will want to use your AWS account for his purposes and you'll end up with xxxx bill at the end of the month.

In the following article it will be explained how to monitor all the AWS Console login events and also the monitoring of the failed attempts.

I suggest to open the CloudTrail in eu-east-1 to also monitor all console login events.

You need to create a trail which sends the logs into S3 just optional, and very important in this case to send them to a CloudWatch group.

Image description

And the event history will look like this:

Image description

When all is set you need to go to the CloudWatch group to see if there are some streams:

Image description

And need to create two metrics in this group:

Image description

One which will be for all ConsoleLogin events with a filter on: { $.eventName = "ConsoleLogin" }

And the other on failed console login attempts: { ($.eventName = "ConsoleLogin") && ($.errorMessage = "Failed authentication") }

If everything goes well just do some console logins as a test, also fail some of those. The result in these two metrics should be:

Image description

Afterwards you can set some alarms. For All logins:

Image description

And for failed ones:

Image description

And both to send emails or sms through and SNS topic.

Some Terraform code to automate a bit the entire process:
The cloudtrail logic and the role link:

provider "aws" {
  region = "us-west-1"
}

resource "aws_sns_topic" "cloudtrail_alerts" {
  name = "cloudtrail-alerts"
}

resource "aws_cloudwatch_log_group" "cloudtrail_log_group" {
  name = "cloudtrail-log-group"
}

resource "aws_cloudtrail" "main" {
  name                          = "cloudtrail-example"
  s3_bucket_name                = aws_s3_bucket.cloudtrail_bucket.bucket
  cloud_watch_logs_group_arn    = aws_cloudwatch_log_group.cloudtrail_log_group.arn
  cloud_watch_logs_role_arn     = aws_iam_role.cloud_watch_logs_role.arn
  enable_logging                = true
}

resource "aws_s3_bucket" "cloudtrail_bucket" {
  bucket = "my-cloudtrail-bucket"
}

resource "aws_iam_role" "cloud_watch_logs_role" {
  name = "CloudWatchLogsRole"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "cloudtrail.amazonaws.com"
        }
      }
    ]
  })
}
Enter fullscreen mode Exit fullscreen mode

The filter on metrics for logins:

resource "aws_cloudwatch_metric_filter" "console_login" {
  name           = "ConsoleLogin"
  pattern        = "{ $.eventName = \"ConsoleLogin\" }"
  log_group_name = aws_cloudwatch_log_group.cloudtrail_log_group.name
}

resource "aws_cloudwatch_metric_filter" "failed_console_login" {
  name           = "FailedConsoleLogin"
  pattern        = "{ ($.eventName = \"ConsoleLogin\") && ($.errorMessage = \"Failed authentication\") }"
  log_group_name = aws_cloudwatch_log_group.cloudtrail_log_group.name
}
Enter fullscreen mode Exit fullscreen mode

And the alarms linked to the metrics:

resource "aws_cloudwatch_metric_alarm" "console_login_alarm" {
  alarm_name          = "ConsoleLoginAlarm"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = "ConsoleLogin"
  namespace           = "CloudTrailMetrics"
  period              = "300"
  statistic           = "SampleCount"
  threshold           = "5"
  alarm_description   = "This metric checks for console logins"
  alarm_actions       = [aws_sns_topic.cloudtrail_alerts.arn]
}

resource "aws_cloudwatch_metric_alarm" "failed_console_login_alarm" {
  alarm_name          = "FailedConsoleLoginAlarm"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = "FailedConsoleLogin"
  namespace           = "CloudTrailMetrics"
  period              = "300"
  statistic           = "SampleCount"
  threshold           = "5"
  alarm_description   = "This metric checks for failed console logins"
  alarm_actions       = [aws_sns_topic.cloudtrail_alerts.arn]
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)