AWS: How to get notified on IAM user logins

Knowing when a user is accessing your account can help detect intrusions. Learn how to set up a notification

5 mins
I have a lot of challenges when it comes to AWS, but I bet your pain points are entirely different than mine. I'd love to hear what keeps you up at night. It would be great to hear from you by filling out this form. Thanks in advance!

Background

The approach with the Event Rule, described in the previous post, works only for the root user. If you try to remove the criterion, you’ll get the impression that it is working, but contrary to the root user, IAM users can choose the region they use to log in. That means an Event Rule defined in the us-east-1 region will only notify you about logins in that region.

One approach to solve this is to define a rule in every region. But then you need to be careful to cover future regions as well, which is hard to automate. As a side note, if you ever find yourself wanting to get into an account silently, make sure to specify the newest region to do so. Maybe the account owner forgot to cover that.

A more robust approach is to use CloudTrail with CloudWatch. CloudTrail can deliver all the API events into a single CloudWatch logs stream, and you can set up a Metric filter and an Alarm that will, in turn, notify you of any future logins.

Let’s see how it works, step by step!

Step 1: Set up CloudTrail

First, go to the CloudTrail console, and set up a new Trail if you haven’t done so already. Make sure to configure the CloudWatch log delivery along the way and also check the Apply trail to all regions.

See here for a detailed tutorial.

Step 2: Set up an SNS topic

You can have the same one you’ve set up for the root login notifications, but don’t forget to update the topic policy. If you use a new topic, you don’t have to do anything. But for an existing topic, make sure that the default statement is included:

{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:Publish",
        "SNS:RemovePermission",
        "SNS:SetTopicAttributes",
        "SNS:DeleteTopic",
        "SNS:ListSubscriptionsByTopic",
        "SNS:GetTopicAttributes",
        "SNS:Receive",
        "SNS:AddPermission",
        "SNS:Subscribe"
      ],
      "Resource": "<arn of the topic>",
      "Condition": {
        "StringEquals": {
          "AWS:SourceOwner": "<account id>"
        }
      }
    }
  ]
}

Adding a new policy overwrites the default one, so you need to manually add it back.

Also, make sure to subscribe to the topic and confirm your subscription after that.

Shortcut: use a CloudFormation template

If you have CloudTrail and an SNS topic set up, you can use this CloudFormation template to set up everything else automatically.

In this case, skip Steps 3 and 4.

Step 3: Add a Metric Filter

Now that CloudTrail events are delivered to CloudWatch logs, the next step is to set up a Metric filter. This is an expression that creates a numeric metric in CloudWatch. To do it, go to the CloudWatch Logs console, find the logs group CloudTrail is using, and on the Metric Filter column, click on the 0 filters.

Then add a new filter, for the Filter Pattern use {$.eventName = "ConsoleLogin"}, then in the Metric Details, assign a Namespace and a Metric Name.

Step 4: Add an Alarm

Now that you have a metric that tracks whenever a ConsoleLogin event appears in the CloudTrail logs, you need to add an Alarm to notify the SNS topic. In the Metric Filter card, click on the Create Alarm link that brings you down directly to the CloudWatch Alarms console, prefilling almost everything in the process.

For the Details, use > 0 for 1 out of 1 datapoints, and Treat missing data as: good.

Finally, in the Actions, add the SNS topic for the ALARM state.

Step 5: Test

Now that you have everything set up, take it for a spin! Log out, then log in, get a coffee, then after 15-20 minutes, you’ll get an email saying the Alarm is in ALARM state.

Also go ahead and try to log in in different regions, the alarm will be set off.

Problems with this solution

Delay

Why this delay when the root login notification was instantaneous? CloudTrail is a near-realtime service, which is a fancy name for non-realtime. It delivers events with a delay of ~15 minutes.

Numerical information

The other problem is that the Metric Filter delivers a numerical value, which is suboptimal for a point-in-time event like a console login. In effect, if there are no logins for a while then there is one, it detects it. But if multiple logins are happening close to each other you’ll only get one notification instead of one for every occasion.

One way to handle this is to filter on the users. You might want to monitor only a privileged user’s sign-ins, and not everyone’s. This should help cut the noise, especially when several people are using the same account.

Conclusion

Detecting intrusions is an important security measure, and logins to the console are one of the most serious ones. While the above solution is not optimal in several ways, especially due to the long delay between the action and the notification, it does provide some insight into what is happening in your account.

References

05 February 2019