How to use MFA with AWS CLI?

How do I enter an MFA when using AWS CLI? I checked the IAM documentation page http://docs.aws.amazon.com/cli/latest/reference/iam/index.html .

I already have MFA devices installed under my username.

aws iam list-mfa-devices --user-name X 

returns

 { "MFADevices": [ { "UserName": "X", "SerialNumber": "arn:aws:iam::+++:mfa/X", "EnableDate": "2016-01-13T23:15:43Z" } ] } 
+17
amazon-web-services
source share
11 answers

Call aws sts get-session-token --token-code <value> registered here . This will give you a temporary security token. The documentation for using the temporary security token can be found here .

+6
source share

The CLI can manage this a lot if you use roles. Described here: http://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html

In my credentials file, I have:

 [my_iam_user] aws_access_key_id = AKIABLAHBLAHBLAHBLAH aws_secret_access_key = <blah> region = us-east-1 [my_admin_role] role_arn = arn:aws:iam::123456789123:role/my_admin_role source_profile = my_iam_user mfa_serial = arn:aws:iam::123456789123:mfa/my_iam_user region = us-east-1 

Pay attention to the mfa_serial entry. You can get this value from your user data in the AWS IAM console. This entry tells the CLI that an MFA is required for this role.

When I call aws s3 ls --profile my_admin_role , it says Enter MFA code: after I paste the code, it returns a list.

Note. I did not find a way to force the CLI to request MFA when invoking the user profile ( --profile my_iam_user ), only --profile my_iam_user role profile launches the MFA request.

Then the MFA token is pushed forward, and the user profile can also be used:

 aws sts get-caller-identity --profile my_iam_user # { # "Account": "123456789123", # "UserId": "AIDABLAHBLAHBLAHBLAH", # "Arn": "arn:aws:iam::123456789123:user/my_iam_user" # } aws sts get-caller-identity --profile my_admin_role # { # "Account": "123456789123", # "UserId": "AROABLAHBLAHBLAHBLAH:AWS-CLI-session-1234567890", # "Arn": "arn:aws:sts::123456789123:assumed-role/my_admin_role/AWS-CLI-session-1234567890" # } 
+31
source share

I published a PR for aws-cli that will allow mfa_serial to be used in credentials, which will force you to enter a token before making an AWS request (and it will be cached while the token is valid)

Feel free to vote if you want to receive it.

+3
source share

Using AWS MFA on the command line can be quite annoying and cumbersome, especially if you have multiple profiles and roles.

I have released an awscli-mfa.sh script that greatly simplifies command line MFA session management / role. The companion enable-disable-vmfa-device.sh script also makes it easy to enable or disable the MFA virtual device in the IAM user account.

awscli-mfa.sh saves the running session in ~/.aws/credentials (with some information in ~/.aws/config ) or allows you to run only the in-env session so that its details are not saved. When executed on a Windows subsystem for Linux, the script also provides session activation strings for PowerShell and the Windows command line. However, the script itself runs only in bash (written for macOS, Linux, and WSL bash with Ubuntu).

Scripts and examples of MFA policies can be found in my GitHub repository at https://github.com/vwal/awscli-mfa.

+1
source share

I wrote a little bash script to overcome this nasty problem. You can find it here: https://gist.github.com/geekgunda/db4c9c8d850c08a48d1d60f119628032

Assumptions:

  1. Your original AWS-Creds should be stored in ~ / .aws / credentials
  2. You have adjusted the ARN for the MFA device (find FIXME)
  3. You gave the correct MFA code as cli argument
  4. You have jq installed. Link: https://stedolan.imtqy.com/jq/
0
source share

In my use case, I have a root account where all IAM users are created and assigned to IAM groups, which, in turn, have the ability to take roles in another account with different degrees of access depending on the group in which they are located. I have a few rules at home;

  1. No one can do anything in the root account except to manage their own IAM user account.
  2. Password reset required.
  3. Foreign Ministry required.
  4. You cannot switch accounts without logging in to MFA.

This has been configured using common AWS organizations.

I used to use a python script that I wrote to allow my users to log in via cli with MFA and switch with accounts. This is done by manipulating the ~ / .aws / credentials parameters.

Since then, I switched to using this project https://gitlab.com/severity1/aws-auth , which is written in Go and allows me to do the same without much configuration, and it works on windows, macosx and linux.

This effectively gives all my users the ability to conduct local testing when developing applications for AWS without having to hardcode AWS Credentials in their code.

0
source share

We described several considerations for the AWS API multifactor in general (where to add conditions, what values, etc.) in the documentation for some user tools ( https://github.com/kreuzwerker/awsu ) that we developed for using Yubikeys as source of TOTP tokens. This simplifies working with roles and long-term credentials + session tokens.

0
source share

I forked a Chinmay gist and updated it to get the device serial number from aws, rather than hard-coded it. I also updated the exits to return status 1 instead of just exiting.

Available here: https://gist.github.com/jpribyl/e44021ae5cbf7fd1b4549598e85b5341

I use it in deployment scripts like this (I renamed the script to awsMfaCli.sh):

 . awsMfaCli.sh script_status=$? if [[ $script_status -ne 1 ]]; then echo "Building production" if npm run build ; then echo "Build Successful" else echo "Error building, exiting.." return 1 fi echo "Removing all files on bucket.." aws s3 rm --recursive s3://mybucket echo "Uploading site.." aws s3 sync build/ s3://mybucket echo "S3 Upload complete.." echo "Deployment complete." else return 1 fi 
0
source share

aws-mfa acts like a wrapper around sts and works very well: https://github.com/broamski/aws-mfa

0
source share

On Windows

I am on the windows and I created a batch file to transfer my MFA code and automatically set my credentials. First, you need to set up your production credentials in AWS:

 aws configure --profile prod 

Answer the questions accordingly by indicating your key and secret. Then I run my script like this:

 C:\> mfa-getCreds.bat 229168 Your credentials are set up, and will expire on 2019-05-12T04:04:13Z Now you should be able to run aws commands like this: aws s3 ls 

Here is the contents of my mfa-getCreds.bat :

 @echo off set TOKEN=%1 if not defined TOKEN goto showUsage @call aws sts get-session-token --profile prod --serial-number "arn:aws:iam::109627855994:mfa/ryan.shillington" --token-code %* > c:\temp\mfa-getCreds.json FOR /F "tokens=* USEBACKQ" %%g IN ('jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json') do (SET AWS_ACCESS_KEY=%%g) FOR /F "tokens=*" %%g IN ('jq -r ".Credentials.SecretAccessKey" c:\temp\mfa-getCreds.json') do (SET "AWS_SECRET_KEY=%%g") FOR /F "tokens=*" %%g IN ('jq -r ".Credentials.SessionToken" c:\temp\mfa-getCreds.json') do (SET "AWS_SESSION_TOKEN=%%g") FOR /F "tokens=*" %%g IN ('jq -r ".Credentials.Expiration" c:\temp\mfa-getCreds.json') do (SET "EXPIRATION=%%g") set AWS_ACCESS_KEY_ID=%AWS_ACCESS_KEY% set "AWS_SECRET_ACCESS_KEY=%AWS_SECRET_KEY%" echo. echo Your credentials are set up, but will expire on %EXPIRATION% echo. echo Now you should be able to run aws commands like this: aws s3 ls goto :EOF :showUsage echo Usage: %0 [MFA Token] goto :EOF 

To do this, you will need a great jq package in your way.

0
source share

I wrote a simple script to install an AWS credential file for a profile named mfa. Then, for all the bash scripts you wrote, you need to add "--profile mfa" so that they just work. It also allows you to use multiple AWS accounts, as many of us do today. I am sure that this can be improved - but it was quick and dirty and does what you want and all that I need.

You will need to change the facts in the script to fit the details of your account - I clearly marked them with chevrons <>. NB Obviously, after you fill out the script with all your data, you do not need to copy it - unless you want unforeseen consequences. This uses recursion in the credential file - as standard access keys are called every time to create mfa security tokens.

 #!/bin/bash # Change for your username - would be /home/username on Linux/BSD dir='/Users/<your-user-name>' region=us-east-1 function usage { echo "Must enter mfa token and then either dev/qa/prod" echo "ie mfa-set-aws-profile.sh 123456 qa" exit 2 } if [[ $1 == "" ]] then echo "Must give me a token - how do you expect this to work - DOH :-)" usage exit 2 fi # Write the output from sts command to a json file for parsing # Just add accounts below as required case $2 in dev) aws sts get-session-token --profile dev --serial-number arn:aws:iam::<123456789>:mfa/<john.doe> --token-code $1 > $dir/mfa-json;; qa) aws sts get-session-token --profile qa --serial-number arn:aws:iam::<123456789>:mfa/<john.doe> --token-code $1 > $dir/mfa-json;; -h) usage ;; *) usage ;; esac # Remove quotes and comma to make the file easier to parse - # NB gsed is for OSX - on Linux/BSD etc sed should be just fine. /usr/local/bin/gsed -i 's/\"//g;s/\,//g' $dir/mfa-json # Parse the mfa info into vars for use in aws credentials file seckey='cat $dir/mfa-json | grep SecretAccessKey | gsed -E 's/[[:space:]]+SecretAccessKey\: //g'' acckey='cat $dir/mfa-json | grep AccessKeyId | gsed 's/[[:space:]]+AccessKeyId\: //g'' sesstok='cat $dir/mfa-json | grep SessionToken | gsed 's/[[:space:]]+SessionToken\: //g'' # output all the gathered info into your aws credentials file. cat << EOF > $dir/.aws/credentials [default] aws_access_key_id = <your normal keys here if required> aws_secret_access_key = <your normal keys here if required> [dev] aws_access_key_id = <your normal keys here > aws_secret_access_key = <your normal keys here > [qa] aws_access_key_id = <your normal keys here > aws_secret_access_key = <your normal keys here > [mfa] output = json region = $region aws_access_key_id = $acckey aws_secret_access_key = $seckey aws_session_token = $sesstok EOF 
0
source share

All Articles