OBS 桶公开读还是私有读?一次权限配置踩坑与防盗链实战
上个月,一个只放官网图片的 OBS 桶一夜流出流量翻了十几倍。排查发现:图片直链被采集站引用,而桶开着公开读,我们在替别人出流量费。这篇文章复盘这次踩坑,并讲清防盗链和私有访问的正确做法。
一、桶策略与 ACL 的区别
ACL 是挂在桶或对象上的访问控制列表,选项只有私有、公共读、公共读写几档,适合定桶的整体基调。桶策略是用 JSON 写的规则,可以精确到“谁、在什么条件下、能对哪个对象做什么操作”,比如只允许某个域名引用、只允许某个 IAM 用户下载。
我的做法是:ACL 只定基调,统一设私有;精细放行一律写桶策略,权限只有一个权威来源。两者并存时要注意:只要有一处放开公开读,对象就可能被匿名访问,不要以为“策略没写公开就安全”。
二、误开公开读的风险
公开读即任何人拿到对象 URL,不用登录、不用签名就能下载。风险有三:其一是盗链,图片、视频被别的站点引用,流量费全算在桶主头上;其二是数据泄露,测试截图、带客户信息的附件一旦进公开桶,就等于发到了公网;其三是被当成“免费图床”,爬虫收录后流量长期居高不下。因此,除非是明确要对外分发的静态资源且已做好防盗链,桶一律保持私有。
三、用桶策略限制 Referer 防盗链
OBS 支持在桶策略里用 Referer 条件做防盗链:只允许来自自己域名的页面引用桶内对象,其他来源直接拒绝。控制台步骤:
- 进入 OBS 控制台,选中目标桶,进入“权限管理 > 桶策略”,新建自定义策略;
- 动作选 GetObject,资源填本桶全部对象,如
obs-example/*,效果选“允许”; - 条件里添加 Referer 白名单,如
https://www.example.com/*,同时覆盖带 www 和不带 www 的写法; - 保存后用 curl 验证:带正确 Referer 返回 200,不带或带陌生域名返回 403。
策略骨架如下:
{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Principal": {"ID": ["*"]}, "Action": ["GetObject"], "Resource": ["obs-example/*"], "Condition": {"StringLike": {"aws:Referer": ["https://www.example.com/*"]}}} ]}
注意:Referer 是浏览器发出的请求头,可以伪造,它防的是“顺手盗链”和普通采集站,不是高强度攻击;小程序、App 内嵌页面可能不带 Referer,重要直链场景不要只依赖它。
四、私有桶对外分享:签名 URL 临时授权
桶保持私有,不代表没法分享。正确做法是生成带签名的临时 URL:用有权限的 AK/SK 对“对象 + 有效期”签名,得到有时效的链接,过期自动失效。控制台可在对象详情页直接生成,程序里调用 OBS SDK 的同名接口也一样。我的经验:给外部客户发资料,有效期设 1 天;内部调试设 1 小时;长期要公开的静态资源,单独放到已做防盗链的公开桶,不要把私有桶临时改公开。签名 URL 不要写进公开网页或公开代码仓库。
五、踩坑复盘
事故根源在项目初期:为让前端直接加载图片,创建桶时顺手选了“公共读”,图片地址直接写进页面;上线正常后,没人再想起权限的事。几周后图片被资源聚合站抓走,流量暴涨,告警才让我们发现。
处理分三步:先止血,把桶改回私有;再把图片迁移到专门的公开资源桶,配好 Referer 白名单,只允许官网域名引用;最后把私有桶的内部资料全部改走签名 URL,并把桶策略和 ACL 检查加进上线清单。
结尾检查清单
- 新桶默认私有,ACL 不做公开读;公开静态资源单独建桶,并配 Referer 防盗链;
- 私有内容对外分享一律用签名 URL,设好有效期;
- 定期检查桶策略,重点看有没有“*”放行了 GetObject;流量告警阈值设低一点。
OBS 的权限并不复杂,复杂的是“图省事”的那一刻。把默认收紧、把例外写清楚,防盗链和私有访问才能真正落地。
- 点赞
- 收藏
- 关注作者
评论(0)