如何使用 AWS cli 在 MFA 上下文中获取访问密钥?
How to use AWS cli to get access keys in an MFA context?
我正在开发一个简单的应用程序,它将 运行 在现有的 EC2 实例上。 AWS 账户受 MFA 保护。我们使用一个主帐户并在我们的目标帐户中扮演一个角色以供个人访问。
当我在本地开发时,该应用程序只处理 MFA。我想避免在目标帐户中创建用户只是为了开发,并将我的本地开发包装在 --profile 之类的功能中。
我的想法是使用 aws sts
生成访问密钥和秘密密钥,但是使用我在凭据文件中的相同设置执行承担角色会给我一个访问被拒绝的错误。
我的凭据文件遵循以下模式:
[main-profile]
aws_access_key_id={access-key}
aws_secret_access_key={secret-key}
[target-profile]
mfa_serial=arn:blah
role_arn=arn:blah2
source_profile=main-profile
我尝试使用 aws sts --role-name arn:blah2 --role-session-name test --profile main-profile
。似乎我也需要参考 MFA 设备,但我不认为这是一个选项。
有什么方法可以做我想做的事吗?
好的,所以我能够成功检索并缓存凭据,但返回的访问密钥似乎对于设置到环境变量中无效。想法?
#!/bin/bash
#set -x
###
# Note: This uses jq (sudo apt-get install jq -y)
targetProfile="target-profile"
sessionFile="/tmp/session-$targetProfile.txt"
sessionFile=$(echo $sessionFile)
echo "Looking for $sessionFile"
if [[ -f "$sessionFile" ]]; then
echo "Found $sessionFile"
sessionInfo="$(cat $sessionFile)"
else
echo "Building $sessionFile"
roleArn="$(aws configure get role_arn --profile $targetProfile)"
mfaArn="$(aws configure get mfa_serial --profile $targetProfile)"
mainProfile="$(aws configure get source_profile --profile $targetProfile)"
echo MFA Token:
read mfaToken
echo "aws sts get-session-token --serial-number $mfaArn --token-code $mfaToken --profile $mainProfile"
sessionInfo="$(aws sts get-session-token --serial-number $mfaArn --token-code $mfaToken --profile $mainProfile)"
fi
echo "Current session info: $sessionInfo"
expirationDateValue="$(echo $sessionInfo | jq '.Credentials.Expiration' | tr -d '"')"
echo "Expiration value: $expirationDateValue"
expirationDate=$(date -d $expirationDateValue +%s)
echo "Expiration date: $expirationDate"
currentDate=$(date +%s)
echo "Current date: $currentDate"
if [[ $currentDate -ge $expirationDate ]]; then
rm $sessionFile
/bin/bash [=11=]
exit
fi
echo "$sessionInfo" > $sessionFile
export AWS_ACCESS_KEY_ID=$(echo $sessionInfo | jq '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $sessionInfo | jq '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $sessionInfo | jq '.Credentials.SessionToken')
#dotnet run
aws s3 ls
当我 运行 这样做时,我收到以下错误消息:
An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: The AWS Access Key Id you provided does not exist in our records.
原来我无法在会话 JSON 返回的值中重新使用引号。我不得不删除引号并添加新引号,这实际上是有道理的。请参阅下面的答案以了解我的解决方案。
AWS CLI 可以使用两个不同的文件来处理 config
和 credentials
.
- AWS CLI 配置文件(
~/.aws/config
)
- AWS 共享凭证文件(
~/.aws/credentials
)
关于共享凭证文件,让我引用文档:
With each section, the three configuration variables shown above can be specified: aws_access_key_id
, aws_secret_access_key
, aws_session_token
. These are the only supported values in the shared credential file.
参考:https://docs.aws.amazon.com/cli/latest/topic/config-vars.html
所以基本上你可以把你的主配置文件放在 credentials
文件上,但是需要把你的目标配置文件放在 config
文件上。
参见下面的示例:
# In ~/.aws/credentials:
[development]
aws_access_key_id=foo
aws_secret_access_key=bar
# In ~/.aws/config
[profile crossaccount]
role_arn=arn:aws:iam:...
source_profile=development
另请注意,部分名称与 AWS CLI 配置文件 (~/.aws/config
) 不同。在 AWS CLI 配置文件中,您通过创建 [profile profile-name]
的部分来创建新的配置文件。在共享凭据文件中,配置文件没有前缀 profile
.
知道了!我终于找到了正确的 Bash 拼写:o)
#!/bin/bash
#set -x
###
# Note: This uses jq (sudo apt-get install jq -y)
targetProfile="target-profile"
sessionFile="/tmp/session-$targetProfile.txt"
sessionFile=$(echo $sessionFile)
echo "Looking for $sessionFile"
if [[ -f "$sessionFile" ]]; then
echo "Found $sessionFile"
sessionInfo="$(cat $sessionFile)"
else
echo "Building $sessionFile"
roleArn="$(aws configure get role_arn --profile $targetProfile)"
mfaArn="$(aws configure get mfa_serial --profile $targetProfile)"
mainProfile="$(aws configure get source_profile --profile $targetProfile)"
echo MFA Token:
read mfaToken
sessionInfo="$(aws sts get-session-token --serial-number $mfaArn --token-code $mfaToken --profile $mainProfile)"
fi
expirationDateValue="$(echo $sessionInfo | jq '.Credentials.Expiration' | tr -d '"')"
expirationDate=$(date -d $expirationDateValue +%s)
currentDate=$(date +%s)
if [[ $currentDate -ge $expirationDate ]]; then
echo "Session expired"
rm $sessionFile
/bin/bash [=10=]
exit
fi
echo "$sessionInfo" > $sessionFile
export AWS_ACCESS_KEY_ID="$(echo $sessionInfo | jq '.Credentials.AccessKeyId' | tr -d '"')"
export AWS_SECRET_ACCESS_KEY="$(echo $sessionInfo | jq '.Credentials.SecretAccessKey' | tr -d '"')"
export AWS_SESSION_TOKEN="$(echo $sessionInfo | jq '.Credentials.SessionToken' | tr -d '"')"
#dotnet run
aws s3 ls
我正在开发一个简单的应用程序,它将 运行 在现有的 EC2 实例上。 AWS 账户受 MFA 保护。我们使用一个主帐户并在我们的目标帐户中扮演一个角色以供个人访问。
当我在本地开发时,该应用程序只处理 MFA。我想避免在目标帐户中创建用户只是为了开发,并将我的本地开发包装在 --profile 之类的功能中。
我的想法是使用 aws sts
生成访问密钥和秘密密钥,但是使用我在凭据文件中的相同设置执行承担角色会给我一个访问被拒绝的错误。
我的凭据文件遵循以下模式:
[main-profile]
aws_access_key_id={access-key}
aws_secret_access_key={secret-key}
[target-profile]
mfa_serial=arn:blah
role_arn=arn:blah2
source_profile=main-profile
我尝试使用 aws sts --role-name arn:blah2 --role-session-name test --profile main-profile
。似乎我也需要参考 MFA 设备,但我不认为这是一个选项。
有什么方法可以做我想做的事吗?
好的,所以我能够成功检索并缓存凭据,但返回的访问密钥似乎对于设置到环境变量中无效。想法?
#!/bin/bash
#set -x
###
# Note: This uses jq (sudo apt-get install jq -y)
targetProfile="target-profile"
sessionFile="/tmp/session-$targetProfile.txt"
sessionFile=$(echo $sessionFile)
echo "Looking for $sessionFile"
if [[ -f "$sessionFile" ]]; then
echo "Found $sessionFile"
sessionInfo="$(cat $sessionFile)"
else
echo "Building $sessionFile"
roleArn="$(aws configure get role_arn --profile $targetProfile)"
mfaArn="$(aws configure get mfa_serial --profile $targetProfile)"
mainProfile="$(aws configure get source_profile --profile $targetProfile)"
echo MFA Token:
read mfaToken
echo "aws sts get-session-token --serial-number $mfaArn --token-code $mfaToken --profile $mainProfile"
sessionInfo="$(aws sts get-session-token --serial-number $mfaArn --token-code $mfaToken --profile $mainProfile)"
fi
echo "Current session info: $sessionInfo"
expirationDateValue="$(echo $sessionInfo | jq '.Credentials.Expiration' | tr -d '"')"
echo "Expiration value: $expirationDateValue"
expirationDate=$(date -d $expirationDateValue +%s)
echo "Expiration date: $expirationDate"
currentDate=$(date +%s)
echo "Current date: $currentDate"
if [[ $currentDate -ge $expirationDate ]]; then
rm $sessionFile
/bin/bash [=11=]
exit
fi
echo "$sessionInfo" > $sessionFile
export AWS_ACCESS_KEY_ID=$(echo $sessionInfo | jq '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $sessionInfo | jq '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $sessionInfo | jq '.Credentials.SessionToken')
#dotnet run
aws s3 ls
当我 运行 这样做时,我收到以下错误消息:
An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: The AWS Access Key Id you provided does not exist in our records.
原来我无法在会话 JSON 返回的值中重新使用引号。我不得不删除引号并添加新引号,这实际上是有道理的。请参阅下面的答案以了解我的解决方案。
AWS CLI 可以使用两个不同的文件来处理 config
和 credentials
.
- AWS CLI 配置文件(
~/.aws/config
) - AWS 共享凭证文件(
~/.aws/credentials
)
关于共享凭证文件,让我引用文档:
With each section, the three configuration variables shown above can be specified:
aws_access_key_id
,aws_secret_access_key
,aws_session_token
. These are the only supported values in the shared credential file.
参考:https://docs.aws.amazon.com/cli/latest/topic/config-vars.html
所以基本上你可以把你的主配置文件放在 credentials
文件上,但是需要把你的目标配置文件放在 config
文件上。
参见下面的示例:
# In ~/.aws/credentials:
[development]
aws_access_key_id=foo
aws_secret_access_key=bar
# In ~/.aws/config
[profile crossaccount]
role_arn=arn:aws:iam:...
source_profile=development
另请注意,部分名称与 AWS CLI 配置文件 (~/.aws/config
) 不同。在 AWS CLI 配置文件中,您通过创建 [profile profile-name]
的部分来创建新的配置文件。在共享凭据文件中,配置文件没有前缀 profile
.
知道了!我终于找到了正确的 Bash 拼写:o)
#!/bin/bash
#set -x
###
# Note: This uses jq (sudo apt-get install jq -y)
targetProfile="target-profile"
sessionFile="/tmp/session-$targetProfile.txt"
sessionFile=$(echo $sessionFile)
echo "Looking for $sessionFile"
if [[ -f "$sessionFile" ]]; then
echo "Found $sessionFile"
sessionInfo="$(cat $sessionFile)"
else
echo "Building $sessionFile"
roleArn="$(aws configure get role_arn --profile $targetProfile)"
mfaArn="$(aws configure get mfa_serial --profile $targetProfile)"
mainProfile="$(aws configure get source_profile --profile $targetProfile)"
echo MFA Token:
read mfaToken
sessionInfo="$(aws sts get-session-token --serial-number $mfaArn --token-code $mfaToken --profile $mainProfile)"
fi
expirationDateValue="$(echo $sessionInfo | jq '.Credentials.Expiration' | tr -d '"')"
expirationDate=$(date -d $expirationDateValue +%s)
currentDate=$(date +%s)
if [[ $currentDate -ge $expirationDate ]]; then
echo "Session expired"
rm $sessionFile
/bin/bash [=10=]
exit
fi
echo "$sessionInfo" > $sessionFile
export AWS_ACCESS_KEY_ID="$(echo $sessionInfo | jq '.Credentials.AccessKeyId' | tr -d '"')"
export AWS_SECRET_ACCESS_KEY="$(echo $sessionInfo | jq '.Credentials.SecretAccessKey' | tr -d '"')"
export AWS_SESSION_TOKEN="$(echo $sessionInfo | jq '.Credentials.SessionToken' | tr -d '"')"
#dotnet run
aws s3 ls