MFA for AWS CLI

In the course “Security Engineering on AWS” there is slide on MFA for AWS CLI.

The scenario is that you are using CLI, your long term credentials allow certain actions, but for more destructive actions like StopInstance, MFA is required.

For example, the user may have a policy like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:TerminateInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        }
    ]
}

A user with this policy can Describeinstances with their long term credentials, but Stop or Terminate require the use of MFA.

To test this, create a user with CLI access and attach the above policy. Use aws configure to configure the long term credentials as normal for CLI access.

To test the scenario, check the users permissions before we set up MFA

aws ec2 describe-instances

It should succeed.

Try to stop an instance. It should fail:

aws ec2 stop-instances –instance-ids i-006564f1892d9be34

An error occurred (UnauthorizedOperation) when calling the StopInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: TWOM9LYAGS…

Associate an MFA device such as Google Authenticator for iPhone with the user. The steps to do this are easy to follow in the management console.

The sts command in the slide requires the arn of the MFA device. This can be found on the Security Credentials tab for the user:

arn:aws:iam::1234567890:mfa/UserMFA
The command also requires the token that is displayed in the authenticator app.
The command will output the temporary credentials as in the slide above.

One way to supply the credentials to the CLI command is to use a profile.

Edit the .aws/credentials file and copy and paste the temporary credentials into a new profile.

[mfa]

output = json

region = eu-west-1

aws_access_key_id = ASIA26NEMI3H7NH3LCNB aws_

secret_access_key = g4nixFvyjO/13xF6qLLVnw7hmiSZFKYCBTKMCDt8

aws_session_token = FQoGZ…

Now try the CLI command again, supplying the profile name.

aws ec2 stop-instances –instance-ids i-006564f1892d9be34 –profile mfa

It should work.

The credentials last an hour by default. As you can see above, the process is cumbersome. Some people have written scripts to automate the update of the credentials file. The script typically prompts for the MFA token. I leave that for your own research.

IAM Policies with MFA Conditions

For certain actions like stop or terminate an instance, you might require MFA, while for less potentially destructive actions like describe-instance, you might not require MFA.

For a simple test of this, I used this policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:TerminateInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        }
    ]
}

I made 2 users, UserMFA and UserNoMFA, both with console access.

For UserMFA, I enabled MFA using Google Authenticator for iPhone. If you havn’t done this before, create a user, then go to the  Security Credentials tab and you are guided through the process, which involves pointing the iPhone camera at a QR code and entering the two 6-digit codes which appear on the iPhone app.

Attach the policy to the two users.

Log in as UserMFA. The user can see the EC2 instances because they have describe-instance permission, and can stop an instance because they are logged in using MFA.

Log in as UserNoMFA. The user can see the EC2 instances because they have describe-instance permission, but cannot stop an instance because they are not logged in using MFA. They receive the following error:

The same concept can apply to use of CLI and APIs, rather than the console, but that’s another story.