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

Как ввести код MFA при использовании интерфейса командной строки 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"
    }
]
}

18 ответов

Решение

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

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

Пошаговое ручное решение:

  1. Запросить токен сеанса с MFA
aws sts get-session-token --serial-number arn-of-the-mfa-device --token-code code-from-token

arn-of-the-mfa-device: отображается от вашего пользователя IAM

  • Вариант: используйте интерфейс командной строки для получения: aws iam list-mfa-devices --user-name ryan
  • Вариант: Просмотр в консоли IAM: IAM -> Пользователи -> -> Учетные данные безопасности

code-from-token: 6-значный код с настроенного устройства MFA

  1. Создайте профиль с возвращенными учетными данными
aws configure --profile cli

aws configure set --profile mfa aws_session_token <SESSION_TOKEN_HERE>

aws_session_tokenэто не включено вaws configure

  1. Тестовая команда
aws s3 ls --profile cli

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

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

aws-mfa действует как обертка вокруг sts и работает очень хорошо: https://github.com/broamski/aws-mfa

Написал инструмент для добавления поддержки MFA для стандартных профилей пользователей IAM, пока @outcoldman PR не будет объединен: https://github.com/tongueroo/aws-mfa-secure

Настройка для тех, кто спешит

  1. Установить драгоценный камень
gem install aws-mfa-secure
  1. Настройте свой ~/.aws/credentials с mfa_serial

~/.aws/ учетные данные:

[mfa]
aws_access_key_id = BKCAXZ6ODJLQ1EXAMPLE
aws_secret_access_key = ABCDl4hXikfOHTvNqFAnb2Ea62bUuu/eUEXAMPLE
mfa_serial = arn:aws:iam::112233445566:mfa/MFAUser
  1. Добавьте псевдоним в свой ~/.bash_profile
alias aws="aws-mfa-secure session"

Перезагрузите ваш терминал.

Пример с выводом

$ export AWS_PROFILE=mfa
$ aws s3 ls
Please provide your MFA code: 751888
2019-09-21 15:53:34 my-example-test-bucket
$ aws s3 ls
2019-09-21 15:53:34 my-example-test-bucket
$

Предполагайте ролевые профили

Предположим, что профили ролей уже работают с интерфейсом командной строки AWS, вот пример:

~/.aws/ учетные данные:

[mfa]
aws_access_key_id = BKCAXZ6ODJLQ1EXAMPLE
aws_secret_access_key = ABCDl4hXikfOHTvNqFAnb2Ea62bUuu/eUEXAMPLE
mfa_serial = arn:aws:iam::112233445566:mfa/MFAUser

[assumed-role]
role_arn = arn:aws:iam::112233445566:role/Admin
source_profile = mfa
role_session_name = MFAUser
mfa_serial = arn:aws:iam::112233445566:mfa/MFAUser

В Windows

Я работаю в Windows, и я создал командный файл, чтобы передать свой код 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 на вашем пути.

Использование 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

Запустите команду интерфейса командной строки AWS sts get-session-token, заменив переменные информацией из вашей учетной записи, ресурсов и устройства MFA:

$ aws sts get-session-token --serial-number arn-of-the-mfa-device --token-code code-from-token

https://aws.amazon.com/premiumsupport/knowledge-center/authenticate-mfa-cli/

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

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

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

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

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

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

Использование интерфейса командной строки 1Password с плагином AWS

Примечание. Для этого решения требуется 1Password, для которого требуется платная подписка.

1Password может безопасно хранить учетные данные и автоматически создавать краткосрочные учетные данные даже в тех случаях, когда вы работаете с базовой настройкой сAWS_ACCESS_KEY_IDиAWS_SECRET_ACCESS_KEYконфигурация.

MFA можно включить с помощью биометрии (например, faceid, touchid, Apple Watch в мире Apple и других) — 1Password автоматически предоставит необходимый токен MFA.

Настройте интерфейс командной строки 1Password (op), используя эти инструкции: https://developer.1password.com/docs/cli .

Настройте плагин AWS, включая шаги по включению MFA, используя эти инструкции: https://developer.1password.com/docs/cli/shell-plugins/aws .

Я думаю, что мой ответ будет полезен для людей, пытающихся следовать , которые, к сожалению, не учитывают много деталей. Я обнаружил несколько нюансов, пытаясь понять, как это сделать в соответствии с официальными документами, поэтому я написал это, чтобы помочь.

Изначально в моем файле ~/.aws/credentials был настроен пользователь CLI без MFA
(это будет важно позже).

Затем я создал второго пользователя «mfa-test», к которому я прикрепил пользовательскую политику с именем Force_MFA. Я взял политику из этого документа aws

      {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListActions",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:ListMFADevices",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ],
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "BlockMostAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ListMFADevices",
                "iam:ListUsers",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

Нюансы, которые я узнал об этой команде:

  1. Перед выполнением команды следует обновить интерфейс командной строки AWS до последней версии.
    официальным документамВ документах упоминается, что это может привести к сбою, если ваш aws cli не обновлен, но это предложение легко пропустить.

  2. Код токена TOTP(одноразовый пароль на основе времени)630011поступает с вашего виртуального устройства MFA

  3. arn:aws:iam::853680132675:mfa/mfa-testможно найти, просмотрев вкладку «Учетные данные безопасности» пользователя IAM.

  4. Команда завершится ошибкой (без полезного сообщения об ошибке), если ~/.aws/credentials соответствует другой учетной записи (например, пользователю CLI без MFA).

            [default]
    aws_access_key_id = lalala
    aws_secret_access_key = lalala
    

    Другими словами, существует жесткое требование, чтобы учетные данные, используемые при запускеaws sts get-session-token --serial-number arn:aws:iam::853680132675:mfa/mfa-test --token-code 630011команда, сопоставьте пользователя, на которого ссылается эта команда (имя пользователя =mfa-test). (Единственное исключение — если у вас есть дополнительные профили, определенные в ~/.aws/credentials и ~/.aws/config, и вы ссылаетесь на них с помощью )

  5. Так что я бы рекомендовал запуститьaws sts get-caller-identityи убедиться, что пользователь (mfa-test) в результатах (.../user/mfa-test) соответствует пользователю, указанному в ARN устройства mfa (.../mfa/mfa-test)

            "Arn": "arn:aws:iam::853680132675:user/mfa-test"
    
  6. Кроме того, если вы установите инструмент jq (json query) cli, пользователи Unix могут использовать следующий трюк, чтобы упростить обмен кредитов CLI без MFA на кредиты CLI MFA, срок действия которых по умолчанию истекает через 12 часов (обратите внимание на| tr -d '"'в команде читается какtranslate delete ", он удаляет двойные кавычки)

export MFA_CLI_SESSION=$(aws sts get-session-token --serial-number arn:aws:iam::853680132675:mfa/mfa-test --token-code 630011)

      export AWS_ACCESS_KEY_ID=$( echo $MFA_CLI_SESSION  | jq .Credentials.AccessKeyId | tr -d '"' )
export AWS_SECRET_ACCESS_KEY=$( echo $MFA_CLI_SESSION  | jq .Credentials.SecretAccessKey | tr -d '"' )
export AWS_SESSION_TOKEN=$( echo $MFA_CLI_SESSION  | jq .Credentials.SessionToken | tr -d '"' )

Вы можете запустить эти команды в качестве дымового теста, чтобы убедиться, что переменные не пусты.

      echo $MFA_CLI_SESSION 
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
echo $AWS_SESSION_TOKEN

С этого момента ваши команды AWS CLI будут работать в течение следующих 12 часов в рамках этого терминального сеанса (поскольку они реализованы как env vars). Также они будут работать без добавления--profile additional_profileфлаг для ваших команд.

Фрагмент легко скопировать и вставить.

      cat <<EOF >aws-credentials.sh
export AWS_ACCESS_KEY_ID=<key>
export AWS_SECRET_ACCESS_KEY=<secret>
export AWS_DEFAULT_REGION=us-east-1
export AWS_USER=<aws_user>
export AWS_ACCOUNT=<aws_account>
EOF

# Almost one liner:
source aws-credentials.sh
source <(paste -d= <(echo -ne "export AWS_ACCESS_KEY_ID\nexport AWS_SECRET_ACCESS_KEY\nexport AWS_SESSION_TOKEN\nexport EXPIRATION\n") <(aws sts get-session-token  --duration-seconds 129600 --serial-number arn:aws:iam::$AWS_ACCOUNT:mfa/$AWS_USER --token-code $(read -p "Token:" TOKEN; echo $TOKEN)  | jq  '.Credentials | .[]'))

# Example
aws s3 ls s3://my-bucket/

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

Я раздвоил суть Чинмая и обновил его, чтобы вытащить серийный номер устройства из 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

Краткое содержание

Аутентификация с помощью MFA выполняется с помощью команды. Основной процесс:

  1. Настройте «постоянный» профиль в формате .
  2. Позвонитеaws stsкоманда с «постоянным» профилем.
  3. Создайте «временный» профиль в~/.aws/credentialsс результатом №2
  4. Используйте «временный» профиль с вашимawsкоманды.

Подробности

№1:

      [myaccountPerm]
aws_access_key_id = REDACTED
aws_secret_access_key = REDACTED

№2:

      $ aws sts get-session-token --token-code 123456 --profile myaccountPerm --serial-number arn:aws:iam::REDACTED:mfa/REDACTED
{
    "Credentials": {
        "AccessKeyId": "REDACTED",
        "SecretAccessKey": "REDACTED",
        "SessionToken": "REDACTED",
        "Expiration": "2021-03-13T09:37:10Z"
    }
}

№3:

      [myaccount]
aws_access_key_id = REDACTED
aws_secret_access_key = REDACTED
aws_session_token = REDACTED

Решение

Вы заметите, что это чрезмерный процесс входа в систему. Я рекомендую использовать утилиту/скрипт для этой цели. Существует несколько, в том числе некоторые из упомянутых в других ответах.

Я также написал такую ​​утилиту, а также подробную статью о том, как пройти аутентификацию с помощью MFA с помощью интерфейса командной строки AWS (включает в себя несколько других деталей, например, как требовать MFA).

Моя утилита представляет собой всего лишь короткий сценарий и не использует установщик pip, что упрощает проверку.

Обзор процесса

Утилита для автоматизации

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

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

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

Однострочник для авторизации и добавления пользователя MFA в ваш файл учетных данных с помощью jq:

      SERIAL_NUMBER=arn:aws:iam::000000000000:mfa/john TOKEN_CODE=123123 PROFILE_NAME=my_aws_2fa; \
aws sts get-session-token --serial-number $SERIAL_NUMBER --token-code $TOKEN_CODE \
   | jq -r '.Credentials | ("aws_access_key_id = " + .AccessKeyId), ("aws_secret_access_key = " + .SecretAccessKey), ("aws_session_token = " + .SessionToken)' \
   | (echo "\n[$PROFILE_NAME]" && cat) >> ~/.aws/credentials
Другие вопросы по тегам