Google Cloud CDN 和 Media CDN 现在支持 AWS Signature V4 认证回源请求。通过这个功能,Cloud CDN 和 Media CDN 可以将任何兼容 AWS S3 存储桶作为源站进行访问。本文将介绍如何部署这一功能。

URL改写

AWS S3 中模拟建立一个私有存储桶,名字为 bin.yinghli.cn,位置 us-east-1。并在其中部署一个 test.jpeg 的测试文件。因为桶名字中包含特殊字符”.”,所以我们无法使用传统 S3_BUCKET_NAME.s3.S3_REGION.amazonaws.com 对内容进行访问。特殊字符”.”会导致 TLS 证书的验证错误。

我们只能通过 URL 改写的方式,通过标准的 https://s3.amazonaws.com/bin.yinghli.cn/test.jpeg 方式来进行访问。我们为 CDN 设定一个新的 DNS 名称,例如 bin2.yinghli.cn,回源到 AWS 的 S3 的存储桶 bin.yinghli.cn。当用户访问 https://bin2.yinghli.cn/test.jpeg,CDN 需要将 Host 改为 s3.amazaonaws.com,URI 从 /test.jpeg 改为 /bin.yinghli.cn/test.jpeg

使用改写以后的信息,再进行 AWS Signature V4 进行认证,方可通过认证。

Cloud CDN 部署

Cloud CDN 通过将 AWS Signature V4 部署在 backend service 方式进行。构建 URL map 时需要根据需要对 URL 进行改写。例如在页面上对 Host 和 path 规则进行修改。

在本地编辑一个 aws-key.yaml 文件,按照以下格式将 AWS Key 文件中 acessKey ID 和 accessKey 分别放到文件中。keyVersion 没有实际意义,可以随意填写。 region 为 AWS S3 所在的区域信息,本例中为 us-east-1

securitySettings:

  awsV4Authentication:

    accessKeyId: $ACCESS_KEY_ID

    accessKey: $ACCESS_KEY

    accessKeyVersion: $ACCESS_KEY_VERSION

    originRegion: $REGION

文件编辑完成后,通过 gcloud 命令上传到对应的 backend-service 中,本例中为 bin6

gcloud beta compute backend-services import bin6 \\

   --source=aws-key.yaml \\

   --global

上传完成后,通过 gcloud beta compute backend-services describe bin6 --global 验证 backend service 中的 security setting 部分已经更新成功。注意 key 已经被隐匿。

name: bin6

port: 80

portName: http

protocol: HTTPS

securitySettings:

  awsV4Authentication:

    accessKeyId: AKIAVEG2Q5QVXFM37GMJ

    accessKeyVersion: v3

    originRegion: us-east-1

客户端上通过 curl -svo /dev/null https://bin.yinghli.cn/test.jpeg 进行验证

< HTTP/2 200

< x-amz-id-2: ph4dOwK08zPrv6mjbdsGcQ+F/Q5kv2EwhmxSjjVx5WbhFV5Gc9CSI1oPc6HbmmLye+aZ/uL0Q8o=

< x-amz-request-id: ZNJ1E50WQSQVAXT3

< date: Mon, 13 Mar 2023 02:47:39 GMT

< last-modified: Mon, 27 Feb 2023 08:05:10 GMT

< etag: "364c0cca9e8bd428975069ac489414a9"

< x-amz-server-side-encryption: AES256

< accept-ranges: bytes

< content-type: image/jpeg

< server: AmazonS3

< content-length: 32454

< via: 1.1 google

< cache-control: public,max-age=3600

< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000


Media CDN部署

与 Cloud CDN 不同,Media CDN 使用 Secure Manager 对 AWS 的 key 进行管理。我们需要创建 Secure manage key,将 access-key 放到 secret value 中。

创建完成后,在 secret detail 中,可以看到 version 1 的 key 已经创建。

通过 gcloud 命令,给 media cdn 账户授权访问 secret key。其中 SECRET_NAME 为 awskey,Project_number 为项目编号。

gcloud secrets add-iam-policy-binding \\

projects/PROJECT_NUMBER/secrets/SECRET_NAME \\

    --member="serviceAccount:service-PROJECT_NUMBER@gcp-sa-mediaedgefill.iam.gserviceaccount.com" \\

    --role="roles/secretmanager.secretAccessor"

更新 Media CDN 中 origin 的 yaml 文件。其中将 AWS Key 文件中 acessKey ID 填入文件, keyVersion 为上一步配置 secrets 名字和 version,本例中 secret 名字为 awskey,version 为 1。originRegion 为 AWS S3 所在的区域信息,本例中为 us-east-1

awsV4Authentication:

 accessKeyId: $ACCESS_KEY_ID

 secretAccessKeyVersion: projects/Project_Number/secrets/awskey/versions/1

 originRegion: $REGION

更新 Media CDN 中 service 的 yaml 文件,按照需求对 URL 进行改写,并更新 origin 配置。为区别于 Cloud CDN,我们使用 bin2.yinghli.cn 作为 Media CDN 测试域名。

routing:

 hostRules:

 - hosts:

   - bin2.yinghli.cn

   pathMatcher: path-matcher-0

 pathMatchers:

 - name: path-matcher-0

   routeRules:

   - priority: '10'

     matchRules:

     - prefixMatch: /

     origin: projects/Project_Number/locations/global/edgeCacheOrigins/bin2

     headerAction: {}

     routeAction:

       cdnPolicy:

         cacheMode: FORCE_CACHE_ALL

         defaultTtl: 3600s

         cacheKeyPolicy: {}

         signedRequestMode: DISABLED

       urlRewrite:

         pathPrefixRewrite: /bin.yinghli.cn/

         hostRewrite: s3.amazonaws.com

客户端上通过 curl -svo /dev/null https://bin2.yinghli.cn/test.jpeg 进行验证

* Connection state changed (MAX_CONCURRENT_STREAMS == 10)!

< HTTP/2 200

< last-modified: Mon, 27 Feb 2023 08:05:10 GMT

< x-amz-id-2: yCvIS5C+QacfXVohiHQVdui9QQdujuniseOcCWV1Q025VbB2YAmFLY5JxatdbD8b/6aYmjhKhfs=

< x-amz-request-id: Z8JXX89HPPBVMWZ1

< date: Mon, 13 Mar 2023 04:02:46 GMT

< x-amz-server-side-encryption: AES256

< accept-ranges: bytes

< content-type: image/jpeg

< server: Google-Edge-Cache

< x-request-id: b3a7bd6d-7f65-4e5f-9fb6-2b42fbe8cd28

< x-xss-protection: 0

< x-frame-options: SAMEORIGIN

< age: 0

< x-content-type-options: nosniff

< content-length: 32454

< etag: "364c0cca9e8bd428975069ac489414a9"

< cache-control: public,max-age=3600




相关推荐