将CloudFront对S3源站的访问授权从原有的OAI切换为最新的OAC

一、背景

CloudFront对S3源站保护功能之前采用源访问身份Origin Access Identity(简称OAI)机制。由于OAI的权限管理颗粒度较粗,且不支持需要AWS Signature V4签名的POST方法,不支持SSE-KMS集成等。由于这一系列的局限,2022年起被新的源访问控制功能Origin Access Control (OAC)所取代。

本文讲述如何切换配置。需要注意的是,对生产环境修改配置可能导致访问失效,请务必提前做好技术储备和测试,生产环境谨慎调整。

更新了Signing behavior的参数说明。

二、查看现有CloudFront访问授权

在开始OAI从OAC的修改工作之前,先查看当前所有配置,并对配置做备份。

1、查看原有S3存储桶的OAI的Policy

进入S3控制台,点击要配置的存储桶,点击第三个标签页Permissions策略,然后将页面向下滚动,来到Bucket policy位置,可查看下方配置策略:

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E2NXXXXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::waf-referer-test/*"
        }
    ]
}

以上配置即是OAI对应的S3策略。请备份好,以防配置失败需要回滚。

2、查看新的Origin Access菜单

进入CloudFront控制台,查看左边的菜单Security,点击其中第一项Origin Access,点击右侧第二个标签页Identities (legacy)就是OAI的配置。如下截图。

以上截图列出了当前存在的OAI。如果有多个CloudFront发布点分别使用不同的OAI访问不同的存储桶,那么这里将分别列出。

3、查看原有授权OAI配置

进入CloudFront发布点,点击第二个标签页origins,查看当前源站,选中之,然后点击Edit按钮,即可编辑设置。如下截图。

Origin access位置,可以看到当前使用的是Legacy access identities的OAI配置,且使用的Identities就是上文列出的那一个。如下截图。

至此确认了当前OAI配置。稍后开始修改OAI配置为OAC。

三、切换为新的OAC访问授权

1、在CloudFront发布点的源管理中修改配置

在上一步的界面中,点击Origin access位置的第二个选项Origin access control settings (recommended),然后点击Create control setting按钮创建新的OAC。如下截图。

在弹出的新建OAC的对话框中,输入名称(可使用CloudFront发布点对本存储桶默认带出的名称),描述部分可任意输入。在Signing behavior签名规则位置,选择Sign requests (recommended),然后点击Create按钮创建。注意这里出现了签名,并不是CloudFront分发私有内容时候的Signed URL和Signed Cookie,这里的签名是CloudFront对S3源站的访问时候,源站S3的Endpoint需要的Signature V4签名。

选择推荐配置Sign requests。如下截图。

这里稍微展开讲解下这个选项的作用:

  • Sign requests (recommended):此选项意味着CloudFront发给S3源站的访问请求时候,CloudFront会生成一个符合S3要求的Signature V4签名请求。这个选项使用的场景最为广泛,客户端只需要发送要请求的URL给CloudFront即可,客户端自己无需处理S3的身份验证问题,都由CloudFront OAC代为验证。如果客户端发给CloudFront的请求已经带有客户端签署的签名了,选择这个选项后,CloudFront会覆盖掉客户端自己生成的签名,转而用CloudFront生成的签名去替代。因此不管客户端自己做的Signature V4签名是否正确有效,S3源站最后收到的访问请求都是以CloudFront OAC身份对应的Signature V4请求发起的。
  • Sign request – Do not override authentication header:这个选项意味着CloudFront发给S3源站的访问请求时候,CloudFront自己不负责生成签名,而是接受从客户端发来的Signature V4签名请求并转发给源站。在这种情况下意味着客户端的代码需要自行处理S3服务API访问所需要的Signature V4签名。Signature V4签名使用HMAC-SHA256算法,这对于应用的开发复杂度会稍高。本功能的使用场景是希望对去往源站的多种访问行为分别进行不同的授权,或者调用CloudFront Function边缘计算等场景。由于在通过网页发布图片的场景下客户端仅仅是请求图片的URL,并不包含签名,因此这个选项对于简单分发图片场景不适用。
  • Do not sign request:这个选项意味着CloudFront发给S3源站的访问请求不带有任何签名,这等同于不使用OAC。使用这个选项的场景是客户端完全处理所有签名,或者后端的S3源站设置为Public无需签名即可访问的场景。

根据以上选项的介绍,现在回到界面配置上。

返回到源配置界面,这里下拉框已经能看到带出了上一步创建时候的OAC了。OAC策略是需要手工修改的,这里提供了复制策略按钮,可以点击复制,也可以下一步修改完毕之后能再去复制。最后点击本页面最下方Save changes保存配置完成修改。如下截图。

修改完毕后,页面上方再次提示可复制策略。如下截图。

现在去修改S3策略。

2、修改S3存储桶策略

OAC与原有的OAI配置不一样,OAI可以自动追加策略到S3存储桶。新的OAC是需要手工配置。原因是新的OAI控制颗粒度更细更严格,是按照单个发布点授权。

这里看下上一步复制出来的策略是:

{
        "Version": "2008-10-17",
        "Id": "PolicyForCloudFrontPrivateContent",
        "Statement": [
            {
                "Sid": "AllowCloudFrontServicePrincipal",
                "Effect": "Allow",
                "Principal": {
                    "Service": "cloudfront.amazonaws.com"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::waf-referer-test/*",
                "Condition": {
                    "StringEquals": {
                      "AWS:SourceArn": "arn:aws:cloudfront::133129065110:distribution/ELOXXXXXXXXX"
                    }
                }
            }
        ]
      }

将以上策略粘贴到S3存储桶策略中。

配置到S3控制台后。如下截图。

点击保存策略后,配置完毕。

3、测试访问

使用客户端对CloudFront发起访问,可看到访问正常。

至此从OAI更换到OAC完成。

四、参考文档

Amazon CloudFront introduces Origin Access Control (OAC)

https://aws.amazon.com/blogs/networking-and-content-delivery/amazon-cloudfront-introduces-origin-access-control-oac/

限制对 Amazon S3 源的访问:

https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

全文完。