Improve AWS CLI security with MFA
Overview
What is MFA? MFA adds extra security because it requires users to provide unique authentication from an AWS supported MFA mechanism in addition to their regular sign-in credentials when they access AWS websites or services: * Virtual MFA devices * U2F security key * Hardware MFA device * SMS text message-based MFA
What is AWS CLI? The AWS Command Line Interface (AWS CLI) is an open-source tool that enables you to interact with AWS services using commands in your command-line shell. With minimal configuration, you can start using functionality equivalent to that provided by the browser-based AWS Management Console from the command prompt in your favorite terminal program.
Scenario
The AWS CLI allows you to use commands in the command line shell to interact with AWS services, so we can use the command code to automatically the service through the command code, but how can you make sure that using the AWS CLI to interact with AWS services is secure? Are settings in the AWS CLI risky if they are permanently authorized? So we want to use temporary certificates and MFA to improve our security.
Step by Step
- Before you can use the AWS CLI to interact with AWS services, you must have AccessKeyID、SecretAccessKey, If you use root account in the AWS CLI, we strongly recommend IAM, add a User and give the necessary authority,so you can Use User instead of root account for added security.
2. Add user -> in User name : type TEST-CLI then check Programmatic access -> Next: Permissions.
3. You can add this user to the group you want to apply, or copy permissions from other users that already exist, or you can choose to directly Attach Policy to User, in this case, Attach AmazonS3ReadOnlyAccess -> Next: Tags.
You just need to give this user the appropriate permissions.
4. Next: Review -> Create user -> Download.csv, after adding a User, select the User you just added.
5. Assigned MFA device -> Manage -> Select Virtual MFA device -> Continue.
6. You can download this kit on your mobile device Authenticator -> Show QR code -> Then use the mobile device to open Authenticator scan QRCode – > enter MFA Code. > In this tutorial, we use google authenticator app to scan the QR Code.
7. Enter MFA code, MFA code regenerates a set every 30 seconds. Here you need to type two groups in a row -> Assign.
8. Upon success Assigned MFA device will appear arn as shown below.
9. Set the AccessKeyID, secret access key to the .AWS/Credential description file, open Terminal, enter the command: aws configure, type in order like the following:
$ aws configure Aws Access Key ID: Aws Secret Access Key: Default region name[us-east-1]: Default output format[None]:
10. After setting, you can use get-session-token with MFA to obtain the temporary credential, and you can set the validity time of the temporary credential.get-session-token.(For more details, please refer to the link)
$ aws sts get-session-token --duration-seconds XXX --serial-number <your mfa arn> --token-code YYYYYY</your>
11. The credential is valid in seconds, at least 900 seconds (15 minutes) and is set to 12 hours, the time is Greenwich Mean Time.
12. If you are using an MFA hardware device, the ARN value is similar to GAHT12345678. If you are using virtual MFA, the value is similar to arn: aws: iam:: 123456789012: mfa/user.
13. You will get a reply as the following:
{ "Credentials": { "AccessKeyId": "XXXXXXXXXXXXXXXXX", "SecretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXX", "SessionToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "Expiration": "2019-01-29T07:43:51Z" } }
14. This temporary credential has the same permissions as User.
15. In the folder, ~/.aws/credentials
and ~/.aws/config
record the relevant information of AWS, example: AccessKey, SecretAccessKey and Region. Here, you will get the temporary license certificate, then type into the .aws/credential profile in the following format:
[profilename]
aws_access_key_id = your-AccessKeyId
aws_secret_access_key = your-SecretAccessKey
aws_session_token = your-SessionToken
1. In credential, you could have many Profile, [Your-Profile-Name] could name by yourself. When using the CLI operation, you can specify Profile at the end of the command by adding —-profile Your-profile-name
, otherwise will execute this command with [default]. The following is the actual use:
$ aws s3 ls --profile your-profile-name
2. And you can use MFA to provide an extra layer of protection for some important, sensitive APIs -> Configuring MFA-Protected API Access.
3. We can also set temporary authorization credentials as an environment variable so that operations on AWS resources in the CLI are performed with the description of the environment variable and, of course, overwrite, replace, or remove the original environment variable. Before that, please cancel the original environment variable setting:
$ unset aws_access_key_id
$ unset aws_secret_access_key
$ unset aws_session_token
18. Setting the environment variable:
$ export aws_access_key_id = your-AccessKeyId
$ export aws_secret_access_key = your-SecretAccessKey
$ export aws_session_token = your-SessionToken
$ export aws_profile = your-profilename
1. After the temporary certificate expires, we must reset the environment variable or change the profile in ~ / .aws/credential
2. Access the aws service with temporary credentials, for example:
$ aws sts get-session-token --duration-seconds XXX --serial-number <your mfa arn> --token-code YYYYYY</your>
An error occurred (ExpiredToken) when calling the ListBuckets operation: The provided token has expired.
3. The message that the temporary credential expires is as follows:
$ aws s3 ls --profile MFA
An error occurred (ExpiredToken) when calling the ListBuckets operation:
The provided token has expired.
```
21. If the temporary credential expires, re-order:
$ aws sts get-session-token --duration-seconds XXX --serial-number <your mfa arn> --token-code YYYYYY
Binding MFA for a specific API
22. When we have not added MFA to the AWS CLI, we can order it in Terminal. Since we have not added the restrictions on operating AWS services, this allows us to directly through the CLI, using AWS resources, such as entering the following commands:
$ aws s3 ls
23. will list all of the Bucket in S3 directly.
24. In some cases, we want our specific API operations to be certified by MFA. In this case, we can add Condition restrictions, for example: I mount some services on EC2, and I don’t want the technician who manages these services to be able to call the API directly terminates the EC2 running the service, so we set TerminateInstances operations plus MFA to protect my EC2 from being terminated.
25. Here, using S3 Bucket as a demonstration, add a Policy to AWS IAM, as follows, and then Attach this Policy to User, as a result, the User in executing ListBucket or GetObject API operations must be verified by MFA.
```
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
26. Then we run the following Python code. Successfully executed and entered the correct MFA Code, listing the objects in the Bucket you specified:
import boto from boto.s3.connection import S3Connection from boto.sts import STSConnection
# Prompt for MFA time-based one-time password (TOTP)
mfa_TOTP = input("Enter the MFA code: ")
# The calls to AWS STS GetSessionToken must be signed with the access key ID and secret
# access key of an IAM user. The credentials can be in environment variables or in
# a configuration file and will be discovered automatically
# by the STSConnection() function. For more information, see the Python SDK
# documentation: http://boto.readthedocs.org/en/latest/boto_config_tut.html
sts_connection = STSConnection()
# Use the appropriate device ID (serial number for a hardware device or ARN for virtual device).
# Replace ACCOUNT-NUMBER-WITHOUT-HYPHENS and MFA-DEVICE-ID with appropriate values.
tempCredentials = sts_connection.get_session_token(
duration=3600,
mfa_serial_number="<YOUR-MFA-ARN",
mfa_token=mfa_TOTP
)
# Use the temporary credentials to list the contents of an S3 bucket
s3_connection = S3Connection(
aws_access_key_id=tempCredentials.access_key,
aws_secret_access_key=tempCredentials.secret_key,
security_token=tempCredentials.session_token
)
# Replace BUCKET-NAME with an appropriate value.
bucket = s3_connection.get_bucket(bucket_name="<your -BUCKET-NAME>")
objectlist = bucket.list()
for obj in objectlist: print (obj.name)
Remember to replace the “< YOUR-MFA-ARN >”, “< YOUR-BUCKET-Name> “
27. When you run this code(Reference from the AWS official website), you will be asked to give MFA Code, which must be entered correctly to perform the API operation. Otherwise, an error message appears.
28. The actual run of this piece of code results as shown below:
1. After entering the right MFA Code, we will list all the objects in this Bucket.
1. If enter the wrong MFA Code, the result as shown below:
Conclusion
Now you can use IAM to create users instead of the root account, give the user the appropriate permissions to interact with specific AWS services, and set Virtual MFA to protect your users. You can also pass MFA authentication when you use the AWS CLI to interact with AWS services, and replace permanent authorization with temporary credential authorization, and set a valid time period, periodically change the temporary credential to improve security when using the AWS CLI. Also learned to set MFA protection on the more sensitive and important APIS.