sobota, 9 listopada 2024

YubiKey and AWS CLI

First you have to install YubiKey Manager CLI. For me on macOS:
brew install ykman

Add a virtual device for your IAM user:


In the next wizard window click on "Show secret key":


Copy the QR code and don't close the card in your browser.

Put your YubiKey in your hardware and:
ykman oath accounts add -t YOUR_LABEL YOUR_QR_CODE

Now ask the YubiKey twice to get a code:
ykman oath accounts code YOUR_LABEL

Put the codes in the right fields and finish the configuration.

Now we can configure our terminal to communicate with AWS. Set your AWS profile before ("AWS_PROFILE" variable).

For example a "~/.aws/config":
[profile yubikey-test]
region = eu-central-1

"~/.aws/credentials":
[yubikey-test]
aws_access_key_id = YOUR_IAM_USER_SECRET_KEY
aws_secret_access_key = YOUR_IAM_USER_ACCESS_KEY

The following command will give your a set of needed variables to get control on your IAM user:
aws sts get-session-token --serial-number ARN_OF_THE_DEVICE --token-code ASK_YUBIKEY_TOKEN --output json

Write down the values and export these environment variables:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_SESSION_TOKEN
  • AWS_DEFAULT_REGION
To make it easier add at your home directory in ".bash_profile" file (or in ".zshrc" depending on your shell)
function aws-get-yubikey-mfa-code {
    ykman oath accounts code YOUR_LABEL 2>/dev/null | sed -E 's/(None:)?AWS[[:space:]]+([[:digit:]]+)/\2/'
}

Close the editor and put
source ~/.bash_profile

Now using aws-get-yubikey-mfa-code command you can get a code using YubiKey.

We don't want to set manually every time all needed variables so let's create another function in "~/.zshrc" file (my case):
AWS_MFA_SERIAL="YOUR_VIRTUAL_DEVICE_ARN"

function aws-yubikey-mfa-session {
    STS_CREDENTIALS=$(aws sts get-session-token --serial-number "$AWS_MFA_SERIAL" --token-code "$1" --output json)

   if [ "$?" -eq "0" ]
    then
        export AWS_ACCESS_KEY_ID=$(echo $STS_CREDENTIALS | jq -r '.Credentials.AccessKeyId')
        export AWS_SECRET_ACCESS_KEY=$(echo $STS_CREDENTIALS | jq -r '.Credentials.SecretAccessKey')
        export AWS_SECURITY_TOKEN=$(echo $STS_CREDENTIALS | jq -r '.Credentials.SessionToken')
        export AWS_SESSION_TOKEN=$(echo $STS_CREDENTIALS | jq -r '.Credentials.SessionToken')
        export AWS_SESSION_EXPIRY=$(echo $STS_CREDENTIALS | jq -r '.Credentials.Expiration')

        echo "[*] Session credentials set. Expires at $AWS_SESSION_EXPIRY."
    else
        echo "[!] Failed to obtain temporary credentials."
    fi
}

Now put
source ~/.zshrc

Install jq command. On macOS it will be:
brew install jq

Now you're ready:
aws-yubikey-mfa-session GET_A_YUBIKEY_TOKEN