通过角色配置根账户与子账户S3访问权限遇权限拒绝问题
问题:如何为IAM用户授予AWS根账户与prod子账户的所有S3桶完全访问权限?
现有配置情况
prod账户侧配置
- 创建角色
ProdS3FullAccessRole,附加两个策略:- AWS托管策略
AmazonS3FullAccess - 内联策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": "*" } ] }
- AWS托管策略
- 角色信任关系配置(允许根账户用户扮演该角色,要求MFA):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<root_account_id>:root" }, "Action": "sts:AssumeRole", "Condition": { "Bool": { "aws:MultiFactorAuthPresent": "true" } } } ] }
根账户侧配置
- 通过用户组为IAM用户附加两个策略:
- 允许扮演prod账户角色的策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sts:AssumeRole" ], "Resource": [ "arn:aws:iam::<prod_account_id>:role/ProdS3FullAccessRole" ] } ] } - AWS托管策略
AmazonS3FullAccess(用于访问根账户S3桶)
- 允许扮演prod账户角色的策略:
- 尝试添加根账户桶策略(为prod角色授权):
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AddPerm", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<prod_account_id>:role/ProdS3FullAccessRole" }, "Action": "s3:*", "Resource": "arn:aws:s3:::<bucket-name>" } ] }
问题现象
用户直接使用根账户IAM用户的Access Key/Secret Access Key执行S3操作时(未扮演prod账户角色),出现AccessDenied错误:
s3 = boto3.client('s3', aws_access_key_id='<access_key_id>', aws_secret_access_key='<secret_access_key>', region_name='<reg>') # List objects in the S3 bucket with the specified prefix response = s3.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
已确认无其他拒绝策略或桶策略阻止访问,但问题依旧。
关键发现(编辑补充)
存在一个强制MFA的策略,移除后根账户访问密钥及角色扮演均正常;附加该策略后,操作立即触发AccessDenied。策略内容如下:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowViewAccountInfo", "Effect": "Allow", "Action": [ "iam:GetAccountPasswordPolicy", "iam:ListVirtualMFADevices" ], "Resource": "*" }, { "Sid": "AllowManageOwnPasswords", "Effect": "Allow", "Action": [ "iam:ChangePassword", "iam:GetUser" ], "Resource": "arn:aws:iam::*:user/${aws:username}" }, { "Sid": "AllowManageOwnAccessKeys", "Effect": "Allow", "Action": [ "iam:CreateAccessKey", "iam:DeleteAccessKey", "iam:ListAccessKeys", "iam:UpdateAccessKey", "iam:GetAccessKeyLastUsed" ], "Resource": "arn:aws:iam::*:user/${aws:username}" }, { "Sid": "AllowManageOwnSigningCertificates", "Effect": "Allow", "Action": [ "iam:DeleteSigningCertificate", "iam:ListSigningCertificates", "iam:UpdateSigningCertificate", "iam:UploadSigningCertificate" ], "Resource": "arn:aws:iam::*:user/${aws:username}" }, { "Sid": "AllowManageOwnSSHPublicKeys", "Effect": "Allow", "Action": [ "iam:DeleteSSHPublicKey", "iam:GetSSHPublicKey", "iam:ListSSHPublicKeys", "iam:UpdateSSHPublicKey", "iam:UploadSSHPublicKey" ], "Resource": "arn:aws:iam::*:user/${aws:username}" }, { "Sid": "AllowManageOwnGitCredentials", "Effect": "Allow", "Action": [ "iam:CreateServiceSpecificCredential", "iam:DeleteServiceSpecificCredential", "iam:ListServiceSpecificCredentials", "iam:ResetServiceSpecificCredential", "iam:UpdateServiceSpecificCredential" ], "Resource": "arn:aws:iam::*:user/${aws:username}" }, { "Sid": "AllowManageOwnVirtualMFADevice", "Effect": "Allow", "Action": [ "iam:CreateVirtualMFADevice" ], "Resource": "arn:aws:iam::*:mfa/*" }, { "Sid": "AllowManageOwnUserMFA", "Effect": "Allow", "Action": [ "iam:DeactivateMFADevice", "iam:EnableMFADevice", "iam:ListMFADevices", "iam:ResyncMFADevice" ], "Resource": "arn:aws:iam::*:user/${aws:username}" }, { "Sid": "DenyAllExceptListedIfNoMFA", "Effect": "Deny", "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:GetUser", "iam:GetMFADevice", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "sts:GetSessionToken" ], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": false } } } ] }
解决方案
问题根源在于强制MFA策略的拒绝语句覆盖了根账户S3的访问权限:
策略中的DenyAllExceptListedIfNoMFA语句,当用户未使用MFA时,会拒绝所有未在NotAction中列出的操作,而S3相关操作不在允许的列表内。用户直接使用Access Key/Secret Access Key调用S3时,未提供MFA认证,触发该拒绝语句,导致AccessDenied。
修复步骤
方案1:调整MFA策略,允许未MFA时访问根账户S3
修改DenyAllExceptListedIfNoMFA语句的NotAction,添加S3相关操作:
{ "Sid": "DenyAllExceptListedIfNoMFA", "Effect": "Deny", "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:GetUser", "iam:GetMFADevice", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "sts:GetSessionToken", "s3:*" // 添加S3所有操作到允许列表 ], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": false } } }
或者更精细地仅允许根账户S3访问:
{ "Sid": "DenyAllExceptListedIfNoMFA", "Effect": "Deny", "Action": "*", "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": false }, "NotResource": [ "arn:aws:s3:::*", // 排除根账户所有S3资源 "arn:aws:s3:::*/*" ] }, "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:GetUser", "iam:GetMFADevice", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "sts:GetSessionToken" ] }
方案2:要求用户使用MFA获取临时凭证访问根账户S3
如果不想放宽MFA要求,可让用户通过MFA获取临时会话令牌,再执行S3操作:
- 用户先调用
sts:GetSessionToken并提供MFA代码,获取临时凭证:sts_client = boto3.client('sts') response = sts_client.get_session_token( DurationSeconds=3600, SerialNumber='arn:aws:iam::<root_account_id>:mfa/<username>', TokenCode='<mfa_code>' ) - 使用临时凭证创建S3客户端:
s3 = boto3.client( 's3', aws_access_key_id=response['Credentials']['AccessKeyId'], aws_secret_access_key=response['Credentials']['SecretAccessKey'], aws_session_token=response['Credentials']['SessionToken'], region_name='<reg>' )
方案3:分离prod账户与根账户的MFA要求
将强制MFA的策略仅应用于prod账户相关的操作,而非全局拒绝。例如,修改策略的Resource为prod账户的资源,或者添加条件仅当访问prod账户资源时触发MFA检查。
验证
修复后,用户直接使用根账户Access Key执行S3操作(或通过MFA临时凭证),应能正常访问根账户S3桶;同时,扮演prod账户角色时仍需满足MFA要求,符合安全策略。
内容的提问来源于stack exchange,提问作者ShwetaJ
相关产品推荐
相关产品推荐

