When MFA (multi factor authentication) is enabled on your IAM user in AWS, the login in the browser asks for an additional input after the username/password credentials:
The MFA code is a temporary combination or number, also called a "token". This token can be retrieved from the device or software, such as Google Authenticator.
In the browser, logging into the "AWS Console", it is pretty much self explaining where to enter the current MFA token. Once the token is verified, the user is logged in and that's it.
But how does that apply when using the aws command line (cli)?
Note: See this article how to configure and use the aws cli using an AWS Access Key ID and Secret Access Key.
When using your AWS API credentials and your IAM user has MFA enabled, the following error message will appear when using the aws command:
ck@mintp ~ $ aws ec2 describe-instances
An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
Obviously AWS has detected that MFA has been enabled for this IAM user and rejects access.
To use aws cli with multi factor authentication enabled, a new "temporary login" must be created. This login includes the MFA device (Google Authenticator in my case) and the current token from it.
The command to create the temporary login is the following:
aws sts get-session-token --serial-number <DEVICE-ID> --token-code <MFA TOKEN>
Obviously the <DEVICE-ID> and <MFA TOKEN> placeholders must be replaced with the real data. To find the device ID of the MFA device assigned to your own user, log into AWS Console -> go to IAM -> select your user -> switch to the "Security credentials" tab. You should find the device ID in the row "Assigned MFA device".
The device ID is basically arn:aws:iam::AWS-USER-ID:mfa/AWS-USER.
Copy this part as this is your MFA device ID.
Now that the MFA device ID of the virtual device (Google Authenticator) is known, a new AWS session can be launched. Use the current code which is shown in Google Authenticator as token code.
If the login was successful, the response shows a JSON output with a set of credentials:
ck@mintp ~ $ aws sts get-session-token --serial-number arn:aws:iam::440XXXXXXXXX:email@example.com --token-code 976154
The output also shows the expiration of this session, which by defaults is set to 12 hours.
The credentials from the output must now be used (exported) as environment variables. On a Linux machine:
ck@mintp ~ $ export AWS_ACCESS_KEY_ID=ASIXXXXXXXXXXXXO2WUU
ck@mintp ~ $ export AWS_SECRET_ACCESS_KEY=cRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX3wR
ck@mintp ~ $ export AWS_SESSION_TOKEN=FwoGZXIvYXdzEHAaDBZ2SekE/BrZbtxgZSKGAYVebDRsr9BEx1KI565HlkCxyJt0oMPwcoxo88L2MQeavSjwnmgpM/ksNVl/P6ycn3SICL/rSSaoEnuE6CWy2SRB0fcO/5dN+eIt2+AcBuI7Puu6pW5LVPrRQHgAMNOrJ2KggOoAj/6dm2Ix71w1hnVpYfSNeNyjL/TzvIba639wHWsWKD3KKIbv7IwGMihcI+/Cc2V9JDx8Kra9ZWFfkxFVWmealZAJ6CISCrbK63eQsKU5cIrq
With these environment variables defined, the aws command line can now be used:
ck@mintp ~ $ aws ec2 describe-instances | head
No authentication error this time. The aws command line works again - at least until the MFA session expires in 12 hours.
No comments yet.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Icingaweb Icingaweb2 Influx Internet Java KVM Kibana Kodi Kubernetes LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder