如何安全地访问AWS
推荐超级课程:
@TOC
在AWS上进行开发时,尽管是必备的,但通过CLI或SDK访问AWS账户的设置确实相当复杂。
我自己也经常混淆,需要重新查找,所以这次我整理并汇总了最佳实践。
当可以使用AWS Organizations & IAM Identity Center时
如果没有特殊理由,建议采用这种方式。即使是个人验证用的AWS账户,也可以根据用途随时发行账户并一次性使用,既安全又方便。
理想的访问方式
个人用IAM IIC用户(仅具有Assume Role权限) -> 执行Assume Role(必须进行MFA认证) -> 工作目标AWS账户(使用工作所需的IAM角色)
补充:什么是IAM IIC?
除了IAM用户之外,还可以在IIC本身创建用户账户。这个IIC用户可以设置IIC的“权限集”来代替IAM策略,从而授予对Organization内其他AWS账户的访问权限。
可以将这个IIC用户用作在同一个Organization下的各AWS账户中执行Assume Role的切换源账户。
设置步骤
在管理用AWS账户中设置AWS Organizations
- 启用AWS Organizations
- 将作业用AWS账户添加到组织中
在管理用AWS账户中设置IAM IIC
- 启用IAM IIC
- 创建IAM IIC用户
- 为IIC用户设置权限集
为IIC用户设置MFA
- 在AWS访问门户为IIC用户设置MFA设备
在作业用PC上设置认证信息
- 安装AWS CLI v2
- 使用aws configure sso设置SSO认证信息
~/.aws/config(自动创建)
[sso-session my-sso]
sso_start_url = https://xxxxxx.awsapps.com/start
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access
[profile admin]
sso_session = my-sso
sso_account_id = XXXXXXXXXX
sso_role_name = AdministratorAccess
region = ap-northeast-1
每次访问步骤
使用GUI(管理控制台)的情况
- 访问AWS访问门户
- 选择作业用AWS账户的所需权限集进行访问
使用AWS CLI的情况
- 使用
aws sso login --profile <配置文件名>
获取作业用AWS账户的临时权限 - 在要执行的命令中附加
--profile <配置文件名>
进行执行
列出S3桶的命令示例
aws s3 ls --profile admin
使用AWS SDK的情况(以Boto3为例)
- 在执行Boto3的
client
方法之前,指定配置文件名进行AssumeRole
test.py
import boto3
# 执行AssumeRole
session = boto3.Session(profile_name="admin")
# 执行目标处理
s3 = session.client("s3")
response = s3.list_buckets()
print(response)
当无法使用AWS Organizations & IAM Identity Center时
例如,在工作中有时候需要在经销商约束下的AWS账户中操作,这时无法使用IAM IIC,接下来介绍这种情况下最佳实践。
理想的访问方式
个人用IAM用户(仅具有Assume Role权限) -> 执行Assume Role(必须进行MFA认证) -> 工作目标AWS账户(使用工作所需的IAM角色)
※分开AWS账户的目的是为了将个人用IAM用户统一到一个地方,以便不需要为每个作业账户创建多个个人用IAM用户。
设置步骤
在管理用AWS账户中创建个人用IAM用户
- 创建个人用IAM用户(应用以下两个策略)
AllowAssumeRole
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<账户ID>:role/<目标角色名>",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
AllowManageOwnMFA
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListActions",
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowUserToCreateVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice"
],
"Resource": "arn:aws:iam::*:mfa/*"
},
{
"Sid": "AllowUserToManageTheirOwnMFA",
"Effect": "Allow",
"Action": [
"iam:EnableMFADevice",
"iam:GetMFADevice",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowUserToDeactivateTheirOwnMFAOnlyWhenUsingMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice"
],
"Resource": [
"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"
}
}
}
]
}
在作业用AWS账户中创建IAM角色
(注:由于原文在此处中断,后续内容未提供,因此翻译也在此处中断。)* 创建作业用IAM角色
信任策略示例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<源账户ID>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
为IAM用户设置MFA
- 使用个人用IAM用户登录到管理用AWS账户的管理控制台,设置MFA设备
在作业用PC上设置认证信息
- 安装AWS CLI v2
- 使用
aws configure --profile <配置文件名>
设置IAM认证信息
~/.aws/credentials示例(自动生成)
[profile assume-only]
aws_access_key_id = <访问密钥ID>
aws_secret_access_key = <秘密访问密钥>
- 在config文件中追加作业用IAM角色的信息
~/.aws/config示例(自动生成+手动追加)
[profile assume-only]
region = ap-northeast-1
[profile admin-role]
role_arn = arn:aws:iam::<账户ID>:role/<目标角色名>
mfa_serial = arn:aws:iam::<账户ID>:mfa/<MFA设备名>
source_profile = assume-only
region = ap-northeast-1
每次访问步骤
使用GUI(管理控制台)的情况
- 使用个人用IAM用户登录到管理用AWS账户
- 切换到作业用AWS账户的IAM角色
使用AWS CLI的情况
- 在执行作业命令时,通过
--profile
选项指定作业用IAM角色的配置文件名即可
※由于切换源的认证信息也记录在credentials文件中,因此在使用CLI时无需手动进行两阶段的认证命令。
使用AWS SDK的情况(以Boto3为例)
- 在执行Boto3的
client
方法之前,指定配置文件名进行AssumeRole
test.py
import boto3
# 执行AssumeRole
session = boto3.Session(profile_name="admin-role")
# 执行目标处理
s3 = session.client("s3")
response = s3.list_buckets()
print(response)
※如果需要MFA认证,终端会提示输入MFA代码。