You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建可访问带拒绝策略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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:30:21