如何创建可访问带拒绝策略S3桶的IAM角色并解决访问拒绝问题
问题:S3桶访问被拒绝,配置IAM角色后无法执行列出/上传/获取对象操作
我有一个配置了Bucket Policy的S3桶,该策略拒绝所有非HTTPS传输的S3操作。我创建了包含S3全操作和iam:PassRole权限的IAM策略,但访问时仍出现“access denied”错误。以下是现有配置及Terraform代码,求修改策略实现所需操作。
现有S3桶策略
{ "Version": "2012-10-17", "Statement": [ { "Sid": "denyInsecureTransport", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::my-bucket/*", "arn:aws:s3:::my-bucket" ], "Condition": { "Bool": { "aws:SecureTransport": "false" } } } ] }
现有IAM策略
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*" ] }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": [ "arn:aws:iam::*:role/*" ] } ] }
Terraform模块代码
resource "aws_s3_bucket_public_access_block" "bucket_public_access" { count = var.create ? 1 : 0 bucket = aws_s3_bucket.s3_bucket[0].bucket block_public_acls = true block_public_policy = true } resource "aws_s3_bucket_policy" "bucket_policy" { count = var.create ? 1 : 0 bucket = local.bucket_name policy = data.aws_iam_policy_document.s3_comb_policy[0].json } data "aws_iam_policy_document" "policy" { count = var.create ? 1 : 0 statement { sid = "denyInsecureTransport" effect = "Deny" actions = [ "s3:*", ] resources = [ "arn:aws:s3:::${local.bucket_name}", "arn:aws:s3:::${local.bucket_name}/*" ] principals { type = "*" identifiers = ["*"] } condition { test = "Bool" variable = "aws:SecureTransport" values = [ "false" ] } } depends_on = [ aws_s3_bucket.s3_bucket[0], ] } data "aws_iam_policy_document" "object_lock_policy" { count = var.create && var.object_lock ? 1 : 0 statement { sid = "ObjectLockConfiguration" effect = "Deny" actions = [ "s3:BypassGovernanceRetention", "s3:PutBucketObjectLockConfiguration", "s3:PutObjectLegalHold", "s3:PutObjectRetention" ] resources = [ "arn:aws:s3:::${local.bucket_name}", "arn:aws:s3:::${local.bucket_name}/*" ] principals { type = "*" identifiers = ["*"] } condition { test = "ArnNotEquals" variable = "aws:PrincipalArn" values = [ "arn:aws:iam::${var.account_number}:role/${var.department}-jenkins-assumed-role-${var.environment}" ] } } depends_on = [ aws_s3_bucket.s3_bucket[0], ] } data "aws_iam_policy_document" "s3_comb_policy" { count = var.create ? 1 : 0 source_policy_documents = compact([ data.aws_iam_policy_document.policy[0].json, var.object_lock ? data.aws_iam_policy_document.object_lock_policy[0].json : "", var.additional_policy != null ? var.additional_policy : "" ]) }
模块内创建的IAM角色代码
resource "aws_iam_role" "replication_role" { count = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0 name = "${local.bucket_name}-s3-replication-role" permissions_boundary = "arn:aws:iam::${var.account_number}:policy/AGT-IAM-BOUNDARY-BASE" assume_role_policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "s3.amazonaws.com" }, "Effect": "Allow", "Sid": "s3ReplicationAssume" } ] } POLICY } resource "aws_iam_policy" "replication_policy" { count = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0 name = "${local.bucket_name}-s3-replication-policy" policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:GetReplicationConfiguration", "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "${aws_s3_bucket.s3_bucket[0].arn}" ] }, { "Action": [ "s3:GetObjectVersionForReplication", "s3:GetObjectVersionAcl", "s3:GetObjectVersionTagging", "s3:GetObjectVersion" ], "Effect": "Allow", "Resource": [ "${aws_s3_bucket.s3_bucket[0].arn}/*" ] }, { "Action": [ "s3:ReplicateObject", "s3:ReplicateDelete", "s3:ReplicateTags" ], "Effect": "Allow", "Resource": "${var.replication_bucket_arn}/*" } ] } POLICY } resource "aws_iam_role_policy_attachment" "replication_policy_attachment" { count = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0 role = aws_iam_role.replication_role[0].name policy_arn = aws_iam_policy.replication_policy[0].arn }
解决方案
1. 确认请求使用HTTPS
桶策略明确拒绝所有非HTTPS请求,需确保所有访问S3的操作都通过HTTPS发起:
- AWS CLI需配置正确的HTTPS endpoint,避免使用HTTP
- 应用代码中调用S3 API时使用HTTPS协议
2. 收紧并修正IAM策略权限
当前IAM策略的iam:PassRole权限范围过广,且未限定使用场景,建议修改为:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:PutObject", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*" ] }, { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::123456789012:role/your-target-role-name", "Condition": { "StringEquals": { "iam:PassedToService": "s3.amazonaws.com" } } } ] }
- 缩小S3操作范围到实际需要的
ListBucket、PutObject、GetObject,遵循最小权限原则 - 将
iam:PassRole的资源限定为目标角色的ARN,并通过iam:PassedToService条件限制仅允许传递给S3服务
3. 检查复制角色的权限边界
如果是复制角色出现访问拒绝,需确认权限边界AGT-IAM-BOUNDARY-BASE允许角色执行所需的S3复制操作。权限边界会限制角色的最大权限,即使策略允许,边界拒绝的操作仍会失败。可通过IAM控制台查看权限边界的具体内容,或调整边界策略包含必要的S3权限。
4. 验证S3公共访问块配置
当前配置的block_public_policy = true不会影响现有桶策略(该策略并非开放公共访问),但需确认桶的**对象所有权(Object Ownership)**设置为Bucket owner enforced,避免因对象所有权冲突导致权限问题。
内容的提问来源于stack exchange,提问作者Sayon
相关产品推荐
相关产品推荐

