带有 Cloudflare 的 S3 不允许直接访问

Posted

技术标签:

【中文标题】带有 Cloudflare 的 S3 不允许直接访问【英文标题】:S3 with Cloudflare disallow direct access 【发布时间】:2017-02-05 12:19:29 【问题描述】:

我试图让 Cloudflare 充当托管在 S3 上的文件的 CDN,以使任何人都无法直接访问这些文件。例如:

S3 存储桶:cdn.mydomain.com.s3.amazonaws.com

CDN (Cloudflare):cdn.mydomain.com

我想要的是能够访问cdn.mydomain.com/file.jpg (Cloudflare) 但不能访问cdn.mydomain.com.s3.amazonaws.com/file.jpg (S3)。

现在我在 Cloudflare 上配置了一个指向我的存储桶的 CNAME,以及以下 CORS:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

如果我尝试通过 S3 或 CDN 访问任何文件,我的权限会被拒绝。如果我公开了一个文件(也就是所有人),我就可以通过 S3 和 CDN 访问该文件。

我尝试将AllowedOrigin 更改为*.mydomain.com,但没有成功。

【问题讨论】:

希望这篇文章对你有帮助maxcdn.com/one/tutorial/s3-access 【参考方案1】:

我找到了解决方案。 article at CloudFlare's support center 没有提到这一点。

您必须编辑存储桶策略,而不是 CORS。而不是像那篇文章所说的那样允许您的域访问存储桶,您必须允许 CloudFlare IP。供参考,以下是 IP 列表:https://www.cloudflare.com/ips

这是与 CloudFlare 一起使用的存储桶策略示例:

    
        "Sid": "SOME_STRING_ID_HERE",
        "Effect": "Allow", // or deny
        "Principal": "AWS": "*", // or whatever principal you want
        "Action": "s3:GetObject", // or whatever action you want
        "Resource": "arn:aws:s3:::cdn.mydomain.com/*", // or whatever resource you want
        "Condition": 
            "IpAddress": 
                "aws:SourceIp": [
                    "103.21.244.0/22",
                    "103.22.200.0/22",
                    "103.31.4.0/22",
                    "104.16.0.0/12",
                    "108.162.192.0/18",
                    "131.0.72.0/22",
                    "141.101.64.0/18",
                    "162.158.0.0/15",
                    "172.64.0.0/13",
                    "173.245.48.0/20",
                    "188.114.96.0/20",
                    "190.93.240.0/20",
                    "197.234.240.0/22",
                    "198.41.128.0/17",
                    "199.27.128.0/21"
                ]
            
        
    

【讨论】:

你能编辑你的答案吗?我得到这不是一个有效的杰森,即使与第一个答案混在一起。我发现缺少一个零件,并且不允许使用 cmets。 好吧,cmets在这里只是解释一下。你可以删除它们。我仍然在存储桶策略中使用此代码,并且运行良好。请务必检查 Cloudflare 上的 IP 列表。他们在几个月前添加了 IPv6。 这对我有用。现在只有cloudflare可以读取,直接访问会返回access denied 嗨@NickChanAbdullah..您是否更改了您的存储桶公共访问权限已关闭或仅公开? @Sreejith 访问控制列表。在公共访问>所有人上,我撤销了所有权限。只需取消选中所有内容:列出对象、写入对象……这将阻止所有人访问存储桶,包括您。但是cdn方式还是可以的。【参考方案2】:

接受的解决方案并不完全有效。它只允许访问 CloudFlare。要使该解决方案起作用,您必须明确拒绝策略中其他地方的所有内容。此存储桶策略针对 Cloudflare 的最新 IP 地址(包括 IPv6)进行了更新,它还拒绝所有非 Cloudflare IP 地址的现成访问。


    "Id": "Policy1517260196123",
    "Version": "2012-10-17",
    "Statement": [
        
            "Sid": "A string ID here",
            "Action": "s3:*",
            "Effect": "Deny",
            "Resource": "arn:aws:s3:::yourbucket.example.com/*",
            "Condition": 
                "NotIpAddress": 
                    "aws:SourceIp": [
                        "103.21.244.0/22",
                        "103.22.200.0/22",
                        "103.31.4.0/22",
                        "104.16.0.0/12",
                        "108.162.192.0/18",
                        "131.0.72.0/22",
                        "141.101.64.0/18",
                        "162.158.0.0/15",
                        "172.64.0.0/13",
                        "173.245.48.0/20",
                        "188.114.96.0/20",
                        "190.93.240.0/20",
                        "197.234.240.0/22",
                        "198.41.128.0/17",
                        "2400:cb00::/32",
                        "2405:8100::/32",
                        "2405:b500::/32",
                        "2606:4700::/32",
                        "2803:f800::/32",
                        "2c0f:f248::/32",
                        "2a06:98c0::/29"
                    ]
                
            ,
            "Principal": 
                "AWS": "*"
            
        
    ]

【讨论】:

好吧,我忘了提桶不是公开的。所以无论如何都没有人可以访问它。你的方法也有效。它只是假设存储桶是公共的,然后如果NotIpAddress,您的策略会阻止对它的访问。同样的想法;) 嗨@rlcabral,我试图将我的存储桶设为私有,但这样做,我无法使用 cloudflare 访问 S3 存储桶中的对象。您能否让我知道如何将 S3 存储桶设为私有并通过 cloudflare 访问存储桶中的内容?我想保持存储桶私有并仅通过 cloudflare 提供访问权限【参考方案3】:

最好使用您的域名作为 s3 的入口保护,而不是 IP 列表。

转到您网站的 S3 控制台 选择属性面板许可下 选择添加 CORS 配置 为您的域名添加 CORSRules

更多CORS配置可以找到here


我的错误,这个答案只禁止其他网站通过合法的网络浏览器下载您的资产,不能阻止人们通过不同的用户代理下载它们。

【讨论】:

以上是关于带有 Cloudflare 的 S3 不允许直接访问的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 CloudFlare 从 S3 提供文件

如何降低数据传输成本? Amazon S3 --> Cloudflare --> 访客

Rails 直接上传到 Amazon S3

使用 cloudflare 将 CNAME 分配给我在亚马逊 S3 中的静态网站存储桶

带有 CloudFlare 的子域

htaccess 中的 cloudflare 用户代理