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

Lambda通过S3网关VPCEndpoint上传对象时策略验证失败排查

问题描述

我有一个部署在无NAT网关的公有子网中的Lambda函数,需要向S3存储桶执行PutObject操作。为此创建了网关类型的VPC端点,配置如下:

UploadsBucketS3GatewayEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Principal: "*"
          Action:
            - s3:PutObject
          Resource:
            - !Sub 'arn:aws:s3:::${UploadsBucket}'
            - !Sub 'arn:aws:s3:::${UploadsBucket}/*'
    RouteTableIds:
      - ${cf:vpc.PublicRouteTable}
    ServiceName: com.amazonaws.${self:provider.region}.s3
    VpcId: ${cf:vpc.VpcId}

部署时收到错误提示:

Please provide a valid VPC Endpoint policy (Service: Ec2, Status Code: 400, Request ID: xx)

请问我的VPC端点配置存在什么问题?


附加信息

以下是存储桶完整的CloudFormation配置(位于Serverless Framework的resources部分):

Resources:
  UploadsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: redacted-website-name-uploads-${opt:stage}
      AccessControl: Private

  UploadsBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref UploadsBucket
      PolicyDocument:
        Statement:
          - Sid: AllowGetFromCloudfront
            Effect: Allow
            Action: s3:GetObject
            Resource: !Sub 'arn:aws:s3:::${UploadsBucket}/*'
            Principal:
              AWS:
                - !Sub "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${UploadsDistributionOAI.Id}"
          - Sid: AllowAdministrationFromVpcEndpoint
            Effect: Allow
            Action: s3:*
            Resource: !Sub 'arn:aws:s3:::${UploadsBucket}/*'
            Principal: "*"
            Condition:
              StringEquals:
                aws:userid:
                  - !Ref UploadsBucketS3GatewayEndpoint

  UploadsDistributionOAI:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: 'OAI for CloudFront access to s3'

  UploadsDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Comment: PWB uploads
        Origins:
          - DomainName: !GetAtt UploadsBucket.RegionalDomainName
            Id: 's3-origin'
            S3OriginConfig:
              OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${UploadsDistributionOAI.Id}"
        PriceClass: PriceClass_100
        Enabled: true
        DefaultCacheBehavior:
          TargetOriginId: 's3-origin'
          ViewerProtocolPolicy: 'redirect-to-https'
          ForwardedValues:
            QueryString: 'false'
            Cookies:
              Forward: all

  # This enables lambda to talk to the uploads bucket without needing a NAT gateway
  UploadsBucketS3GatewayEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal: "*"
            Action:
              - s3:PutObject
            Resource:
              - !Sub 'arn:aws:s3:::${UploadsBucket}'
              - !Sub 'arn:aws:s3:::${UploadsBucket}/*'
      RouteTableIds:
        - ${cf:vpc.PublicRouteTable}
      ServiceName: com.amazonaws.${self:provider.region}.s3
      VpcId: ${cf:vpc.VpcId}

问题分析与解决方案

核心错误原因

  1. S3网关型VPC端点策略不允许通配符Principal:AWS对S3网关端点的策略有严格限制,Principal字段不能直接设为"*",必须指定具体IAM身份(如Lambda执行角色ARN),或通过条件限制访问来源。
  2. 资源声明冗余:s3:PutObject操作的目标是存储桶内的对象,而非存储桶本身,策略中包含arn:aws:s3:::${UploadsBucket}属于无效资源声明,会触发策略校验失败。

修正后的VPC端点策略

方案1:指定Lambda执行角色作为Principal

直接授权Lambda的执行角色通过端点访问S3:

PolicyDocument:
  Version: 2012-10-17
  Statement:
    - Effect: Allow
      Principal:
        AWS:
          - !GetAtt LambdaExecutionRole.Arn  # 替换为你的Lambda执行角色ARN
      Action:
        - s3:PutObject
      Resource:
        - !Sub 'arn:aws:s3:::${UploadsBucket}/*'

方案2:通过条件限制访问来源

如果需要开放端点给VPC内所有符合条件的身份,可通过VPC或端点ID限制:

PolicyDocument:
  Version: 2012-10-17
  Statement:
    - Effect: Allow
      Principal: "*"
      Action:
        - s3:PutObject
      Resource:
        - !Sub 'arn:aws:s3:::${UploadsBucket}/*'
      Condition:
        StringEquals:
          aws:SourceVpce: !Ref UploadsBucketS3GatewayEndpoint  # 限制仅通过当前端点访问

额外注意事项

  • Lambda执行角色本身必须拥有s3:PutObject权限,VPC端点策略是附加访问控制层,无法替代IAM角色权限。
  • 公有子网的路由表已关联VPC端点,这部分配置正确,能确保Lambda通过端点访问S3而非公网。
  • 存储桶策略中用aws:userid关联VPC端点ID的方式可行,注意VPC端点的userid格式为vpce-xxxxxx,引用需正确。

内容的提问来源于stack exchange,提问作者amacrobert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:32:45