对象存储桶策略、JSON 配置和域名访问控制实战

预计阅读时间:11 分钟

这是「把自己部署到互联网上」系列的第 30 篇。

上一篇讲了为什么个人博客也需要对象存储。

图片、附件、项目截图和静态资源会随着文章不断增长,如果全部放在服务器本地,后面会遇到磁盘膨胀、迁移麻烦、备份边界不清晰和带宽压力等问题

但对象存储真正有坑的地方,是文件权限到底该怎么开?

  1. 图片既要能被文章访问,也要不能被别人随便访问
  2. 图片等相关资源能通过自己的域名访问,但又不希望任何地方都无限制引用
  3. 桶策略、JSON 配置、访问域名、防盗链、CORS 混在一起,很容易出错

我刚开始使用对象存储时,就把它当成云端文件夹:

创建桶,上传图片,复制链接,放进文章里,图片能打开,好像就结束了。

应该有不少这样操作的人,但经历过不少坑之后,就会继续往下一层考虑:

  • 这个文件为什么能打开?
  • 是整个桶公开了,还是单个对象公开了?
  • 文件会不会能被别的网站引用?
  • 文件会不会被人恶意盗刷?
  • 如果上传了不该公开的文件,会不会也被公开?
  • 绑定自定义域名后,访问路径会不会变化?

对象存储难的不是文件传不上去,而是如何能保证文件在安全范围内访问。

资源分类

公开资源

第一类是公开资源,比如文章图片、项目截图、封面图、头像、公开下载的 PDF、作品站预览图。这些本来就是给读者访问的,要允许公开读取。

私有资源

第二类是私有资源,比如数据库备份、配置备份、未发布材料、私密附件、带敏感信息的文件。这些不应该公开访问。

这个分类很重要。很多对象存储事故,就是把所有文件放进一个公开桶里。

一开始只是想公开几张文章图片,后来无意中把备份文件、配置文件、临时文件也传进去,结果这些文件也成了可访问资源,很容易造成 存储事故

Bucket 划分

我的建议是:公开资源和私有资源不要放在同一个桶里

对我的博客来说,最简单的方式是公开图片一个桶,私密备份另一个桶

边界越清楚,后面越不容易出错。

权限设置

对象存储里常见权限包括 私有读写、公共读私有写、公共读写

不同云厂商叫法略有差异,但含义大致相同。

对公开图片桶来说,常见选择是公共读私有写:

读者可以读取资源对象,不能上传、修改或删除对象。

上传和删除仍然需要账号权限。

不要为了省事开启公共读写。

公共读写意味着任何人都可能写入或修改资源,风险很高。私有资源桶则应保持私有,需要访问时通过签名 URL、后台授权或临时凭证处理。

桶策略

桶策略可以理解成对象存储的访问规则

它通常以 JSON 配置,谁可以对哪些资源执行哪些操作,在什么条件下允许或拒绝。

常见字段包括:

  • Effect 表示允许还是拒绝
  • Principal 表示访问主体
  • Action 表示操作
  • Resource 表示资源范围
  • Condition 表示条件

假设我有一个公开图片桶,只希望 public/ 前缀下的文件能被所有人读取,示意策略可以写成:

{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "GetObject"
      ],
      "Resource": [
        "bucket-name/public/*"
      ]
    }
  ]
}

这只是通用示意。不同云厂商的字段名、Action 名称和 Resource 格式可能不同,有的会写成 oss:GetObject,有的会写成 cos:GetObject。实际配置必须以对应平台文档为准。稳定的思路是:只允许读取,只作用于公开前缀,不给写入权限,不把整个桶随手开放。

前缀隔离也很重要。对象存储里的“目录”通常只是对象 Key 的前缀,例如:

public/blog/2026/xxx.png
private/backup/db.sql

公开图片放 public/,文章图片放 public/blog/,作品截图放 public/projects/,私有备份不放进公开桶,或者至少不放进公开前缀。路径规范是最低成本的权限辅助。

对象存储默认会提供访问域名,但我更倾向使用自己的资源域名,例如:

assets.example.com

文章里的图片地址可以写成:

https://assets.example.com/public/blog/2026/demo.png

自定义域名的好处是域名体系统一,后续迁移也更灵活。绑定自定义域名通常要在对象存储控制台绑定域名,在 DNS 里添加 CNAME,配置 HTTPS,等待解析生效,再验证资源能否访问。

绑定域名后,还要考虑访问控制。有些平台支持指定域名访问、防盗链 Referer 白名单、是否允许空 Referer、CORS 跨域规则和强制 HTTPS。

安全策略

防盗链可以减少普通盗链

例如只允许来自 blog.example.comwww.example.com 的 Referer 访问图片。

Referer 可能缺失,也可能被伪造,所以它不是强安全边界。

真正私密的文件不能靠防盗链保护,应该保持私有,通过签名 URL 或授权访问。

CORS 也要分清楚

它影响的是浏览器里的跨域请求,不等于对象访问权限控制。如果只是文章里引用图片,通常不需要复杂 CORS

只有前端页面通过 JavaScript 请求对象存储资源,或者浏览器直传文件到对象存储时,才需要配置 CORS。

CORS 配置要最小化。

如果只需要 GET,就不要开放 PUT、DELETE。

如果只允许自己的博客和官网访问,就把 Origin 限制在自己的域名。

不要为了省事写成所有来源、所有方法、所有 Header 都放开。

我是怎么设计的

结合我的场景,对象存储资源访问时这样设计的,感兴趣的可以参考下:

公开桶

公开图片桶用于文章图片、项目截图、公开附件。

允许公开读取,不允许公开写入,绑定 assets.example.com,按 public/blog/public/projects/ 等前缀组织,可按需配置防盗链,CORS 保持最小化。

私有桶

私有备份桶用于数据库备份、配置备份等敏感文件。

保持完全私有,不绑定公开访问域名,不公开读,访问需要账号权限或签名 URL

配置完对象存储后,一定要验证。上传一张测试图片到公开路径,例如:

public/blog/test.png

然后访问:

https://assets.example.com/public/blog/test.png

确认公开读取正常。再测试非公开路径是否不能访问,自定义域名和 HTTPS 是否正常,防盗链是否符合预期,CORS 是否按前端需求生效。

最重要的是确认没有开启公共写入,公开策略只包含读取动作,私有桶没有误公开

小结

  1. 对象存储真正要管好的,是公开资源和私有资源的边界
  2. 公开桶可以服务文章图片和项目截图,但只能公开读,不能公开写
  3. 私有桶保存备份和敏感文件,不对公网开放
  4. JSON 策略要看懂 ActionResourcePrincipalCondition,自定义域名要配合 DNS、HTTPS 和访问控制,防盗链和 CORS 都按需配置。

下一篇开始进入博客部署主流程:我是如何用 Docker 部署个人博客的。

前面铺了服务器、安全、Docker、Nginx、HTTPS 和对象存储,接下来终于要把博客真正跑起来。


本文由 楸木 原创,转载请注明出处。

相关推荐

发现更多