From f43115ad2a534076b1a7424b057dbb181b986f0d Mon Sep 17 00:00:00 2001 From: nlicitra Date: Fri, 9 Sep 2022 13:10:04 -0400 Subject: [PATCH 1/3] Updating Router to handle S3 origins by default and adding OAI to serverless config --- serverless.yml | 65 +++++++++++++++++++++++++++++++------------------- src/router.js | 38 +++++++++++++++-------------- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/serverless.yml b/serverless.yml index d7a8a76..5469daa 100644 --- a/serverless.yml +++ b/serverless.yml @@ -1,9 +1,9 @@ -service: 'sveltekit-app' +service: "sveltekit-app" frameworkVersion: "3" plugins: - - '@silvermine/serverless-plugin-cloudfront-lambda-edge' + - "@silvermine/serverless-plugin-cloudfront-lambda-edge" - serverless-s3-deploy provider: @@ -25,23 +25,22 @@ custom: assets: auto: true targets: - - bucket: + - bucket: Ref: StaticAssets files: - source: ./build/assets/ - globs: - - '**' + globs: + - "**" empty: true headers: CacheControl: max-age=31104000 - source: ./build/prerendered/ - globs: - - '**' + globs: + - "**" empty: true headers: CacheControl: max-age=60 - functions: #SSR Function svelte: @@ -56,7 +55,7 @@ functions: memorySize: 128 timeout: 1 lambdaAtEdge: - distribution: 'WebsiteDistribution' + distribution: "WebsiteDistribution" eventType: origin-request resources: @@ -64,7 +63,6 @@ resources: StaticAssets: Type: AWS::S3::Bucket Properties: - AccessControl: PublicRead BucketName: ${self:provider.stage}-${self:service}-static-assets StaticAssetsS3BucketPolicy: @@ -74,35 +72,54 @@ resources: Ref: StaticAssets PolicyDocument: Statement: - - Sid: PublicReadGetObject + - Sid: PolicyForCloudFrontPrivateContent Effect: Allow - Principal: "*" + Principal: + AWS: + Fn::Join: + [ + "", + ["arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ", { "Ref": "StaticAssetsOAI" }], + ] Action: - s3:GetObject Resource: Fn::Join: ["", ["arn:aws:s3:::", { "Ref": "StaticAssets" }, "/*"]] + StaticAssetsOAI: + Type: AWS::CloudFront::CloudFrontOriginAccessIdentity + Properties: + CloudFrontOriginAccessIdentityConfig: + Comment: "Access Identity for ${self:service} (${self:provider.stage})" + WebsiteDistribution: - Type: 'AWS::CloudFront::Distribution' + Type: "AWS::CloudFront::Distribution" Properties: DistributionConfig: Origins: - - - DomainName: !Select [2, !Split ["/", !GetAtt ["SvelteLambdaFunctionUrl", "FunctionUrl"]]] - Id: default - OriginCustomHeaders: + - DomainName: !Select [2, !Split ["/", !GetAtt ["SvelteLambdaFunctionUrl", "FunctionUrl"]]] + Id: svelte-server + OriginCustomHeaders: #Lambda@edge does not support ENV vars, so instead we have to pass in a customHeaders. - - - HeaderName: 's3-host' - HeaderValue: '${self:provider.stage}-${self:service}-static-assets.s3.amazonaws.com' + - HeaderName: "s3-host" + HeaderValue: "${self:provider.stage}-${self:service}-static-assets.s3.amazonaws.com" CustomOriginConfig: HTTPPort: 80 HTTPSPort: 443 - OriginProtocolPolicy: 'https-only' + OriginProtocolPolicy: "https-only" + - DomainName: !GetAtt ["StaticAssets", "DomainName"] + Id: static-assets + OriginCustomHeaders: + #Lambda@edge does not support ENV vars, so instead we have to pass in a customHeaders. + - HeaderName: "lambda-domain" + HeaderValue: !Select [2, !Split ["/", !GetAtt ["SvelteLambdaFunctionUrl", "FunctionUrl"]]] + S3OriginConfig: + OriginAccessIdentity: + Fn::Join: ["", ["origin-access-identity/cloudfront/", { "Ref": "StaticAssetsOAI" }]] Enabled: true - Comment: '${self:service}_${self:provider.stage}' + Comment: "${self:service}_${self:provider.stage}" DefaultCacheBehavior: - TargetOriginId: default + TargetOriginId: static-assets Compress: true AllowedMethods: - DELETE @@ -120,4 +137,4 @@ resources: Cookies: Forward: all QueryString: True - ViewerProtocolPolicy: 'redirect-to-https' + ViewerProtocolPolicy: "redirect-to-https" diff --git a/src/router.js b/src/router.js index 2e8a00e..b097438 100644 --- a/src/router.js +++ b/src/router.js @@ -1,17 +1,10 @@ -'use strict'; +"use strict"; -import staticFiles from './static.js' +import staticFiles from "./static.js"; exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; - //Only senf GET request to S3 - if (request.method !== 'GET') { - callback(null, request); - return; - } - - //For request without a file extention, we should look for index.html let uri = request.uri; if (!uri.includes(".") && uri.slice(-1) !== "/") { uri += "/"; @@ -19,15 +12,24 @@ exports.handler = (event, context, callback) => { if (uri.slice(-1) === "/") { uri += "index.html"; } - - //If our path matches a static file, perfrom an origin re-write to S3; - if (staticFiles.includes(uri)) { + if (static_default.includes(uri)) { request.uri = uri; - //Lambda@edge does not support ENV vars, so instead we have to pass in a customHeaders. - const domainName = request.origin.custom.customHeaders["s3-host"][0].value; - request.origin.custom.domainName = domainName; - request.origin.custom.path = ""; - request.headers["host"] = [{ key: "host", value: domainName }]; + } else { + const domainName = request.origin.s3.customHeaders["lambda-domain"][0].value; + request.headers["host"] = [{ key: "Host", value: domainName }]; + request.origin.custom = { + domainName: domainName, + keepaliveTimeout: 5, + path: "", + port: 443, + protocol: "https", + readTimeout: 30, + sslProtocols: ["TLSv1", "SSLv3"], + }; + + // Cleanup request origin to only have custom configuration + delete request.origin.s3; } + callback(null, request); -}; \ No newline at end of file +}; From 93e07b7b25bedbdbb8f18b391e27eb88b2155c5a Mon Sep 17 00:00:00 2001 From: nlicitra Date: Fri, 9 Sep 2022 14:07:10 -0400 Subject: [PATCH 2/3] Fixing bug with router file --- src/router.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router.js b/src/router.js index b097438..b6b1360 100644 --- a/src/router.js +++ b/src/router.js @@ -12,7 +12,7 @@ exports.handler = (event, context, callback) => { if (uri.slice(-1) === "/") { uri += "index.html"; } - if (static_default.includes(uri)) { + if (staticFiles.includes(uri)) { request.uri = uri; } else { const domainName = request.origin.s3.customHeaders["lambda-domain"][0].value; From 102a4c3b26102d44196b84f97ef7901860443a43 Mon Sep 17 00:00:00 2001 From: nlicitra Date: Fri, 9 Sep 2022 14:24:19 -0400 Subject: [PATCH 3/3] Block all public access for static asset bucket --- serverless.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/serverless.yml b/serverless.yml index 5469daa..be05082 100644 --- a/serverless.yml +++ b/serverless.yml @@ -64,6 +64,11 @@ resources: Type: AWS::S3::Bucket Properties: BucketName: ${self:provider.stage}-${self:service}-static-assets + PublicAccessBlockConfiguration: + BlockPublicAcls: true + BlockPublicPolicy: true + IgnorePublicAcls: true + RestrictPublicBuckets: true StaticAssetsS3BucketPolicy: Type: AWS::S3::BucketPolicy