Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services 如何限制Cloudfront访问S3网站?_Amazon Web Services_Amazon S3_Amazon Cloudformation_Amazon Cloudfront - Fatal编程技术网

Amazon web services 如何限制Cloudfront访问S3网站?

Amazon web services 如何限制Cloudfront访问S3网站?,amazon-web-services,amazon-s3,amazon-cloudformation,amazon-cloudfront,Amazon Web Services,Amazon S3,Amazon Cloudformation,Amazon Cloudfront,我想在静态网站的前面放一个Cloudfront CDN,并限制Cloudfront发行版对bucket的读取访问。非常常见,还有其他来源。但由于某种原因,我不能让它工作 我不是第一个偶然发现这一点的人。(, ). 我已经尝试了那里发布的解决方案,但同样,没有运气 作为Cloudformation模板,我的设置如下所示: AWSTemplateFormatVersion: "2010-09-09" Parameters: s3BucketName: Type: S

我想在静态网站的前面放一个Cloudfront CDN,并限制Cloudfront发行版对bucket的读取访问。非常常见,还有其他来源。但由于某种原因,我不能让它工作

我不是第一个偶然发现这一点的人。(, ). 我已经尝试了那里发布的解决方案,但同样,没有运气

作为Cloudformation模板,我的设置如下所示:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  s3BucketName:
    Type: String
  domainName:
    Type: String
  certificateArn:
    Type: String
  bucketAuthHeader:
    Type: String

Resources:
  cloudfrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
         Enabled: true
         PriceClass: PriceClass_100
         Origins:
           - Id: !Sub "ID-${s3BucketName}"
             DomainName: !Sub "${s3BucketName}.s3-website.eu-central-1.amazonaws.com"
             CustomOriginConfig:
               OriginProtocolPolicy : http-only
             OriginCustomHeaders:
               - HeaderName: User-Agent
                 HeaderValue: !Ref bucketAuthHeader
         DefaultCacheBehavior:
           AllowedMethods:
             - GET
             - HEAD
             - OPTIONS
           CachedMethods:
             - GET
             - HEAD
             - OPTIONS
           DefaultTTL: 600
           ForwardedValues:
               QueryString: false
           TargetOriginId: !Sub "ID-${s3BucketName}"
           ViewerProtocolPolicy: redirect-to-https

  s3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref s3BucketName
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: _errors/404/index.html
    DeletionPolicy: Delete

  s3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref s3BucketName
      PolicyDocument:
        Version: 2012-10-17
        Id: "Cloudfront Bucket Access"
        Statement:
          - Sid: "Cloudfront Bucket Access via Referer"
            Effect: Allow
            Principal: "*"
            Action: "s3:GetObject"
            Resource:  !Sub "arn:aws:s3:::${s3BucketName}/*"
            Condition:
              StringEquals:
                aws:UserAgent:
                  - !Ref bucketAuthHeader
然而,当应用这个时,我无法通过Cloudfront访问文件,我总是得到403。我还尝试在
publiccessblockconfiguration
AccessControl
中调整值,并尝试使用
aws s3 sync…--grants read=uri上传bucket内容=http://acs.amazonaws.com/groups/global/AllUsers

但我总是以公共S3内容或通过Cloudfront无法获得的内容而告终


有人知道我还可以尝试什么吗?

我使用AWS云开发工具包(CDK)为这样一个SPA做了这件事:

import*作为“路径”中的路径;
将*作为s3从“@aws cdk/aws-s3”导入;
从“@aws cdk/aws cloudfront”导入*作为cloudfront;
从“@aws cdk/aws cloudfront origins”导入*作为cloudfrontOrigins;
从“@aws cdk/aws lambda”导入*作为lambda
//私人网站bucket
const websiteBucket=new s3.Bucket(这个“websiteBucket”{
加密:s3.BucketEncryption.s3_管理,
blockPublicAccess:s3.blockPublicAccess.BLOCK_ALL,
publicReadAccess:错误,
});
//访问标识,我们可以将其附加到bucket以授予其访问权限
const websiteOriginAccessIdentity=新cloudfront.OriginAccessIdentity(
这
“OriginAccessIdentity”
);
//授予此存储桶的访问标识访问权限
Grantrade(websiteOriginAccessIdentity)
//使用此存储桶和源站访问标识访问Cloudfront
const websiteBucketOrigin=new cloudfrontOrigins.S3Origin(
props.websiteBucket,
{
原始路径:“/”,
originAccessIdentity:websiteOriginAccessIdentity,
}
);
//添加Lambda@Edge将所有非资产请求重定向到“/index.html”。
//就像用放大的重写规则一样。
const websiteRedirectFunction=新lambda.Function(
这
“重定向功能”,
{
代码:lambda.code.fromAsset(path.resolve(\uu dirname,“../redirect”){
捆绑:{
命令:[
“猛击”,
“-c”,
“npm安装和npm运行构建和cp-rT/asset input/dist//asset output/”,
],
图:lambda.Runtime.NODEJS_12_X.bundlingDockerImage,
用户:“根”,
},
}),
处理程序:“index.redirect”,
运行时:lambda.runtime.NODEJS_12_X,
}
);
//使用源文件创建Cloudfront分发
const websiteCdn=new cloudfront.Distribution(这是“websiteCdn”{
默认行为:{
来源:网站BuckeTorigin,
edgeLambdas:[
{
eventType:cloudfront.LambdaEdgeEventType.ORIGIN_请求,
functionVersion:websiteRedirectFunction.currentVersion,
},
],
},
});
/../redirect/src/index.ts
从“aws lambda”导入*作为lambdaTypes;
导出常量重定向=(
事件:lambdaTypes.CloudFrontRequestEvent,
_上下文:lambdaTypes.context,
回调:lambdaTypes.CloudFrontRequestCallback
):void=>{
const request=event.Records[0].cf.request;
console.info({request});
//将所有文件重定向到index.html,但资产的特定文件扩展名除外
const isPageRequest=/^[^.]+$\(?!(css ^ gif | ico | jpg | js | png | txt | svg | woff | ttf | map | json)$)([^.]+$)/;
log({isPageRequest});
if(isPageRequest){
request.uri=“/index.html”;
}
log({updateRequest:request});
回调(null,请求);
};
本例假设您正在将网站部署到我们在这里创建的
websiteBucket
bucket。由于有几种不同的方法可以将您的网站部署到S3,因此为了简洁起见,将其省略。例如

注意:本例使用TypeScript,并假设您已将其设置为内置到
/dist/
。以下面的简单TSConfig为例:

{
“编译器选项”:{
“目标”:“es5”,
“模块”:“commonjs”,
“outDir”:“dist”,
“rootDir”:“src”
},
“包括”:[“src/***”]
}
//package.json
“脚本”:{
“构建”:“tsc-b”
}

请尝试此方法作为测试:从AWS内部对S3存储桶进行基于角色的访问不是一种好做法。最好对静态站点本身有一些其他限制。您是否考虑过使用仅允许从CloudFront访问您的bucket?@Nikhil我们这里讨论的是S3网站bucket,因此该链接在这个screnario中是不相关的。AWS自己也明确推荐了基于角色的方法,请参见我问题中的链接。@Marcin OAIs不适用于S3网站bucket。非常感谢您的分享!看到您使用带有OAI的网站bucket,我有点惊讶,因为从官方来看,这不可能。但可能有一些隐藏的功能,只有SDK才支持。但是,你又在使用Lambda,这有点不着边际,因为我认为你实际上是在使用它来进行访问,而不是通过Cloudfront。在未来几天的某个时候,我将不得不分析你的设置,让你知道它是否解决了问题。它实际上不是一个网站bucket-这只是我提供给它作为参考的id/名称。抱歉搞混了!你可以看到我阻止公众访问,这不是一个网站桶会做的。