Как использовать MFA с AWS CLI?

Как мне ввести код MFA при использовании CLI AWS? Я проверил страницу документации IAM http://docs.aws.amazon.com/cli/latest/reference/iam/index.html.

У меня уже установлены MFA-устройства под моим именем пользователя.

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

возвращает

{
"MFADevices": [
    {
        "UserName": "X", 
        "SerialNumber": "arn:aws:iam::+++:mfa/X", 
        "EnableDate": "2016-01-13T23:15:43Z"
    }
]
}

Ответ 1

Вызовите aws sts get-session-token --token-code <value> зарегистрированный здесь. Это даст вам временный токен безопасности. Документацию по использованию временного токена безопасности можно найти здесь.

Ответ 2

CLI может управлять этим много, если вы используете роли. Описан здесь: http://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html

В моем файле учетных данных у меня есть:

[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

Обратите внимание на запись mfa_serial. Вы можете получить это значение из своих данных пользователя в консоли AWS IAM. Эта запись сообщает CLI, что для этой роли требуется MFA.

Когда я вызываю aws s3 ls --profile my_admin_role, он говорит Enter MFA code:, после того, как я вставляю код, он возвращает список.

Примечание. Я не нашел способ заставить CLI запрашивать MFA при вызове профиля пользователя (--profile my_iam_user), только вызов профиля роли запускает запрос MFA.

Затем токен MFA переносится вперед, и пользовательский профиль также может быть использован:

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"
 # }

Ответ 3

Я опубликовал PR для aws-cli, который позволит использовать mfa_serial в учетных данных, что заставит вас ввести токен перед тем, как сделать запрос AWS (и он будет кэшироваться, пока токен действителен)

Не стесняйтесь голосовать, если вы хотите его получить.

Ответ 4

Использование AWS MFA в командной строке может быть довольно неприятным и громоздким, особенно если у вас несколько профилей и ролей.

Я выпустил скрипт awscli-mfa.sh который значительно упрощает управление сессиями MFA/роль в командной строке. Сопутствующий скрипт enable-disable-vmfa-device.sh также позволяет легко включать или отключать виртуальное устройство MFA в учетной записи пользователя IAM.

awscli-mfa.sh сохраняет запущенный сеанс в ~/.aws/credentials (с некоторой информацией в ~/.aws/config) или позволяет вам запускать только сеанс in-env, чтобы его детали не сохранялись. При выполнении в подсистеме Windows для Linux сценарий также предоставляет строки активации сеанса для PowerShell и командной строки Windows. Однако сам скрипт запускается только в bash (написано для macOS, Linux и WSL bash с Ubuntu).

Сценарии и примеры политик MFA можно найти в моем репозитории GitHub по адресу https://github.com/vwal/awscli-mfa.

Ответ 5

Я написал небольшой скрипт bash, чтобы преодолеть эту неприятную проблему. Вы можете найти его здесь: https://gist.github.com/geekgunda/db4c9c8d850c08a48d1d60f119628032

Предположения:

  1. Ваши оригинальные AWS-Creds должны храниться в ~/.aws/credentials
  2. Вы скорректировали ARN для устройства MFA (найдите FIXME)
  3. Вы дали правильный код MFA в качестве аргумента cli
  4. У вас установлен jq. Ссылка: https://stedolan.github.io/jq/

Ответ 6

В моем случае использования у меня есть учетная запись root, где все пользователи IAM создаются и назначаются группам IAM, которые, в свою очередь, имеют возможность брать роли в другой учетной записи с различной степенью доступа в зависимости от группы, в которой они находятся. У меня есть несколько правил дома;

  1. Никто не может ничего делать в учетной записи root, кроме как управлять собственной учетной записью пользователей IAM.
  2. Требуется сброс пароля.
  3. Требуется МИД.
  4. Вы не можете переключать учетные записи без входа в MFA.

Это было настроено с использованием общих организаций AWS.

Раньше я использовал сценарий python, который я написал, чтобы позволить моим пользователям входить в систему через cli с MFA и переключаться с учетными записями. Это делается путем манипулирования параметрами ~/.aws/credentials.

С тех пор я перешел на использование этого проекта https://gitlab.com/severity1/aws-auth, который написан на Go и позволяет мне делать то же самое без большой настройки, и он работает на windows, macosx и linux.

Это эффективно дает всем моим пользователям возможность проводить локальное тестирование при разработке приложений для AWS без необходимости жесткого кодирования AWS Credentials в их коде.

Ответ 7

Мы описали несколько соображений для мультифактора AWS API в целом (где добавить условия, какие значения и т.д.) В документации для некоторых пользовательских инструментов (https://github.com/kreuzwerker/awsu), которые мы разработали для использования Yubikeys как источник токенов ТОТП. Это упрощает работу с ролями и долгосрочными учетными данными + токены сеанса.

Ответ 8

Я разветкил Chinmay gist и обновил его, чтобы вытащить серийный номер устройства из aws, а не жестко кодировать его. Я также обновил выходы, чтобы вернуть статус 1 вместо того, чтобы просто выйти.

Доступно здесь: https://gist.github.com/jpribyl/e44021ae5cbf7fd1b4549598e85b5341

Я использую его в сценариях развертывания, подобных этому (я переименовал скрипт в 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

Ответ 10

На винде

Я нахожусь на окнах, и я создал командный файл, чтобы передать мой код MFA и автоматически установить мои учетные данные. Во-первых, вам нужно настроить свои производственные учетные данные в AWS:

aws configure --profile prod

Ответьте на вопросы соответствующим образом, указав свой ключ и секрет. Затем я запускаю свой скрипт так:

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

Вот содержимое моего 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

Для этого вам понадобится отличный пакет jq на вашем пути.

Ответ 11

Я написал простой скрипт для установки файла учетных данных AWS для профиля с именем mfa. Затем для всех написанных вами сценариев bash нужно добавить "--profile mfa", чтобы они просто работали. Это также позволяет использовать несколько учетных записей AWS, как это делают многие из нас в наши дни. Я уверен, что это можно улучшить - но это было быстро и грязно и делает то, что вы хотите, и все, что мне нужно.

Вам нужно будет изменить факты в сценарии, чтобы они соответствовали деталям вашего аккаунта - я четко обозначил их шевронами <>. NB Очевидно, что после того, как вы заполнили сценарий всеми вашими данными, его копировать не нужно - если только вы не хотите непредвиденных последствий. Это использует рекурсию в файле учетных данных - поскольку стандартные ключи доступа вызываются каждый раз для создания токенов безопасности mfa.

#!/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 "i.e. 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 -
# N.B. 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