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 |